netflix.ocelli.util.RpsEstimator Maven / Gradle / Ivy
package netflix.ocelli.util;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
public class RpsEstimator {
private static final double MICROS_PER_SECOND = TimeUnit.MICROSECONDS.convert(1, TimeUnit.SECONDS);
private AtomicLong sampleCounter = new AtomicLong();
private AtomicLong lastCheckpoint = new AtomicLong();
private volatile long estimatedRps;
private volatile long nextCheckpoint;
private volatile long lastFlushTime = System.nanoTime();
public static class State {
long count;
long rps;
}
public RpsEstimator(long initialRps) {
this.estimatedRps = 0;
this.nextCheckpoint = 1000;
}
public State addSample() {
long counter = sampleCounter.incrementAndGet();
if (counter - lastCheckpoint.get() == nextCheckpoint) {
long count = counter - lastCheckpoint.get();
synchronized (this) {
lastCheckpoint.set(counter);
long now = System.nanoTime();
estimatedRps = (long) (count * MICROS_PER_SECOND / (lastFlushTime - now));
lastFlushTime = now;
nextCheckpoint = estimatedRps;
State state = new State();
state.count = count;
state.rps = estimatedRps;
return state;
}
}
else if (counter - lastCheckpoint.get() > 2 * estimatedRps) {
nextCheckpoint = (counter - lastCheckpoint.get()) * 2;
}
return null;
}
long getSampleCount() {
return sampleCounter.get();
}
long getRps() {
return estimatedRps;
}
}