/**
*
*/
package com.trendrr.oss.counters;
import java.util.Date;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.trendrr.oss.TimeAmount;
import com.trendrr.oss.Timeframe;
/**
*
* Threadsafe counter that keeps counts of the past and current minute, second, ect.
*
*
* @author Dustin Norlander
* @created Jan 31, 2013
*
*/
public class TimeAmountCounter {
protected static Log log = LogFactory.getLog(TimeAmountCounter.class);
protected AtomicLong current = new AtomicLong(0);
protected AtomicLong previous = new AtomicLong(0l);
protected AtomicLong previousEpoch = new AtomicLong(0l);
protected TimeAmount timeframe = TimeAmount.instance(Timeframe.MINUTES);
protected AtomicLong epoch = new AtomicLong(0);
protected TimeAmountCounterCallback callback = null;
public TimeAmountCounter(TimeAmount timeamount, TimeAmountCounterCallback callback) {
this.timeframe = timeamount;
this.callback = callback;
}
public long inc() {
return this.inc(1);
}
public long inc(long val) {
long curepoch = timeframe.toTrendrrEpoch(new Date()).longValue();
long oldepoch = this.epoch.getAndSet(curepoch);
if (oldepoch != curepoch) {
previous.set(current.getAndSet(0));
previousEpoch.set(oldepoch);
//rolled over
if (callback != null) {
callback.onRollover(this, this.timeframe.fromTrendrrEpoch(oldepoch), previous.get());
}
}
return current.addAndGet(val);
}
/**
* triggers a rollover if necessary.
* this is just a pointer to inc(0l);
*/
public void rolloverIfNeeded() {
this.inc(0);
}
/**
* Gets the current value for this timeframe
* @return
*/
public long getCurrent() {
if (timeframe.toTrendrrEpoch(new Date()).longValue() != this.epoch.get()) {
return 0l;
}
return this.current.get();
}
/**
* gets the most recently completed from one timeframe ago (ie. yesterday, an hour ago, ect).
* @return
*/
public long getPrevious() {
if ((timeframe.toTrendrrEpoch(new Date()).longValue()-1) != this.previousEpoch.get()) {
return 0l;
}
return this.previous.get();
}
public TimeAmount getTimeAmount() {
return this.timeframe;
}
}