package com.intrbiz.bergamot.agent.util; import java.util.concurrent.TimeUnit; public class SampleRingBuffer { private final int capacity; private final double interval; private final long[] samples; private int size = 0; private int position = 0; public SampleRingBuffer(int capacity, long interval, TimeUnit intervalUnit) { this.capacity = capacity; this.interval = intervalUnit.toMillis(interval); this.samples = new long[capacity]; } public void addSample(long sample) { if (this.size < this.capacity) this.size++; this.samples[this.position] = sample; this.position = (this.position + 1) % this.capacity; } private int translate(int index) { return (this.size < this.capacity) ? (index % this.capacity) : (this.position + index) % this.capacity; } public long getSample(int index) { return this.samples[this.translate(index)]; } public long interval() { return (long) this.interval; } public int size() { return this.size; } public int capacity() { return this.capacity; } public double peakRate() { double peakRate = 0; if (this.size > 1) { long previous = this.samples[translate(0)]; for (int i = 1; i < this.size; i++) { long current = this.samples[translate(i)]; long delta = current - previous; if (delta > 0) peakRate = Math.max(peakRate, ((double) delta) / this.interval); previous = current; } } return peakRate; } public double peakRateSeconds() { return this.peakRate() * 1000D; } public double instantRate() { if (this.size > 1) { int latest = this.size - 1; long delta = this.samples[translate(latest)] - this.samples[translate(latest -1)]; if (delta > 0) return ((double) delta) / this.interval; } return 0; } public double instantRateSeconds() { return this.instantRate() * 1000D; } public double averageRate() { if (this.size > 1) { long delta = this.samples[translate(this.size - 1)] - this.samples[translate(0)]; if (delta > 0) return ((double) delta) / (this.interval * ((double) (this.size - 1))); } return 0; } public double averageRateSeconds() { return this.averageRate() * 1000D; } }