package org.terracotta.statistics.derived.latency;
import org.terracotta.statistics.observer.ChainedEventObserver;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.concurrent.atomic.LongAdder;
public class LatencyAccumulator implements LatencyStatistic, ChainedEventObserver {
private static final long DEFAULT_MIN = Long.MAX_VALUE;
private static final long DEFAULT_MAX = Long.MIN_VALUE;
private final LongAdder count = new LongAdder();
private final LongAdder total = new LongAdder();
private final LongAccumulator minimum = new LongAccumulator(Math::min, DEFAULT_MIN);
private final LongAccumulator maximum = new LongAccumulator(Math::max, DEFAULT_MAX);
private LatencyAccumulator(long... latencies) {
for (long latency : latencies) {
accumulate(latency);
}
}
public void accumulate(long latency) {
count.increment();
total.add(latency);
minimum.accumulate(latency);
maximum.accumulate(latency);
}
public void accumulate(LatencyAccumulator accumulator) {
count.add(accumulator.count());
total.add(accumulator.total());
minimum.accumulate(accumulator.minimum());
maximum.accumulate(accumulator.maximum());
}
public long count() {
return count.sum();
}
public long total() {
return total.sum();
}
public boolean isEmpty() {
return count.sum() == 0;
}
@Override
public void event(long time, long latency) {
accumulate(latency);
}
@Override
public Long maximum() {
return isEmpty() ? null : maximum.get();
}
@Override
public Long minimum() {
return isEmpty() ? null : minimum.get();
}
@Override
public double average() {
return ((double) total.sum()) / count.sum();
}
@Override
public String toString() {
return "LatencyAccumulator{" +
"count=" + count() +
", total=" + total() +
", minimum=" + minimum() +
", maximum=" + maximum() +
", average=" + average() +
'}';
}
public static LatencyAccumulator accumulator(long... latencies) {
return new LatencyAccumulator(latencies);
}
public static LatencyAccumulator empty() {
return new LatencyAccumulator();
}
}