package ddth.dasp.framework.stats;
import java.util.Timer;
import java.util.TimerTask;
/**
* Single-slot rate (number of things/amount of time) counter.
*
* @author NBThanh <btnguyen2k@gmail.com>
*/
public class SingleRateCounter {
private Timer timer;
private TimerTask task;
/*
* Resolution is best to be power of 2 (e.g. 2, 4, 8, 16, etc)
*/
private int slotResolution;
private long slotResolutionNanoseconds;
private int resolutionShift;
private String name;
private volatile long lastAccessTimestamp = System.nanoTime();
private volatile long counter = 0;
/**
* Constructs a new {@link SingleRateCounter} instance.
*/
public SingleRateCounter() {
}
/**
* Constructs a new {@link SingleRateCounter} instance.
*/
public SingleRateCounter(Timer timer) {
setTimer(timer);
}
/**
* Setter for {@link #timer}.
*
* @param timer
* Timer
*/
public void setTimer(Timer timer) {
this.timer = timer;
}
/**
* Getter for {@link #timer}.
*
* @return Timer
*/
protected Timer getTimer() {
return timer;
}
public void destroy() {
if (task != null) {
task.cancel();
task = null;
}
}
/**
* Initialzing method.
*/
public void init() {
if (this.slotResolution < 1) {
this.slotResolution = 1;
}
this.resolutionShift = 20;
this.slotResolutionNanoseconds = 1 << this.resolutionShift;
long temp = this.slotResolution * 1000000L;
while (this.slotResolutionNanoseconds < temp) {
this.resolutionShift++;
this.slotResolutionNanoseconds <<= 1;
}
if (timer != null) {
long delay = slotResolution;
task = new ResetCounterTask(this);
timer.scheduleAtFixedRate(task, delay, delay);
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* Gets slot's resolution in nanoseconds.
*
* @return long the resolution in nanoseconds
*/
public long getSlotResolutionNano() {
return this.slotResolutionNanoseconds;
}
/**
* Gets slot's resolution.
*
* @return long the resolution in milliseconds
*/
public int getSlotResolution() {
return this.slotResolution;
}
/**
* Sets slot's resolution.
*
* @param resolution
* int slot's resolution in milliseconds
*/
public void setSlotResolution(int resolution) {
this.slotResolution = resolution;
}
/**
* Gets the counter's last access timestamp.
*
* @return long last access timestamp in nanoseconds
*/
public long getLastAccessTimestamp() {
return this.lastAccessTimestamp;
}
/**
* Gets the counter value.
*
* @return long
*/
public long getCounter() {
return counter;
}
/**
* Increases counter by 1 and returns the post-inc value.
*
* @return
*/
public long incCounter() {
return incCounter(1);
}
/**
* Increases counter by a specific value and returns the post-inc value.
*
* @param value
* long
* @return
*/
public long incCounter(long value) {
long oldValue = counter;
counter += value;
return oldValue;
}
static class ResetCounterTask extends TimerTask {
private SingleRateCounter rateCounter;
public ResetCounterTask(SingleRateCounter rateCounter) {
this.rateCounter = rateCounter;
}
/**
* {@inheritDoc}
*/
@Override
public void run() {
rateCounter.counter = 0;
}
}
}