Skip to content

Instantly share code, notes, and snippets.

@Fuud
Created September 8, 2016 13:32
Show Gist options
  • Save Fuud/6f09eb7d59d3b5013abe6e27692ebe33 to your computer and use it in GitHub Desktop.
Save Fuud/6f09eb7d59d3b5013abe6e27692ebe33 to your computer and use it in GitHub Desktop.
package com.github.metricscore.hdr.histogram;
import com.codahale.metrics.Clock;
import com.codahale.metrics.Reservoir;
import com.codahale.metrics.Snapshot;
import com.codahale.metrics.WeightedSnapshot;
import com.github.metricscore.hdr.counter.SimpleWindowCounter;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class SimpleWindowHistogramReservoir implements Reservoir {
private final long[] bucketOffsets;
private final SimpleWindowCounter[] buckets;
public SimpleWindowHistogramReservoir(Duration windowSize, int chunkCount, boolean smoothly, int numBuckets, Clock clock) {
bucketOffsets = newOffsets(numBuckets);
buckets = new SimpleWindowCounter[numBuckets];
for (int i = 0; i < numBuckets; i++) {
buckets[i] = new SimpleWindowCounter(windowSize, chunkCount, smoothly, clock);
}
}
@Override
public int size() {
return buckets.length;
}
@Override
public void update(long value) {
//todo: check value range
int index = Arrays.binarySearch(bucketOffsets, value);
if (index < 0) {
// inexact match, take the first bucket higher than n
index = -index - 1;
}
// else exact match; we're good
buckets[index].add(1);
}
@Override
public Snapshot getSnapshot() {
List<WeightedSnapshot.WeightedSample> weightedValues = new ArrayList<>(buckets.length);
for (int i = 0; i < buckets.length; i++) {
SimpleWindowCounter bucket = buckets[i];
final long value = bucketOffsets[i];
final long count = bucket.getSum();
if (count>0){
final WeightedSnapshot.WeightedSample weightedSample = new WeightedSnapshot.WeightedSample(value, count);
weightedValues.add(weightedSample);
}
}
return new WeightedSnapshot(weightedValues);
}
private static long[] newOffsets(int size) {
long[] result = new long[size];
result[0] = 0;
result[1] = 1;
for (int i = 1; i < result.length; i++) {
long next = Math.round(result[i - 1] * 1.2);
if (next == result[i - 1]) {
next++;
}
result[i] = next;
}
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment