com.aliyun.openservices.shade.io.prometheus.client.TimeWindowQuantiles Maven / Gradle / Ivy
package com.aliyun.openservices.shade.io.prometheus.client;
import com.aliyun.openservices.shade.io.prometheus.client.CKMSQuantiles.Quantile;
import java.util.concurrent.TimeUnit;
/**
* Wrapper around CKMSQuantiles.
*
* Maintains a ring buffer of CKMSQuantiles to provide quantiles over a sliding windows of time.
*/
class TimeWindowQuantiles {
private final Quantile[] quantiles;
private final CKMSQuantiles[] ringBuffer;
private int currentBucket;
private long lastRotateTimestampMillis;
private final long durationBetweenRotatesMillis;
public TimeWindowQuantiles(Quantile[] quantiles, long maxAgeSeconds, int ageBuckets) {
this.quantiles = quantiles;
this.ringBuffer = new CKMSQuantiles[ageBuckets];
for (int i = 0; i < ageBuckets; i++) {
this.ringBuffer[i] = new CKMSQuantiles(quantiles);
}
this.currentBucket = 0;
this.lastRotateTimestampMillis = System.currentTimeMillis();
this.durationBetweenRotatesMillis = TimeUnit.SECONDS.toMillis(maxAgeSeconds) / ageBuckets;
}
public synchronized double get(double q) {
CKMSQuantiles currentBucket = rotate();
return currentBucket.get(q);
}
public synchronized void insert(double value) {
rotate();
for (CKMSQuantiles ckmsQuantiles : ringBuffer) {
ckmsQuantiles.insert(value);
}
}
private CKMSQuantiles rotate() {
long timeSinceLastRotateMillis = System.currentTimeMillis() - lastRotateTimestampMillis;
while (timeSinceLastRotateMillis > durationBetweenRotatesMillis) {
ringBuffer[currentBucket] = new CKMSQuantiles(quantiles);
if (++currentBucket >= ringBuffer.length) {
currentBucket = 0;
}
timeSinceLastRotateMillis -= durationBetweenRotatesMillis;
lastRotateTimestampMillis += durationBetweenRotatesMillis;
}
return ringBuffer[currentBucket];
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy