All Downloads are FREE. Search and download functionalities are using the official Maven repository.

se.l4.vibe.percentile.BucketPercentileCounter Maven / Gradle / Ivy

There is a newer version: 0.4.0
Show newest version
package se.l4.vibe.percentile;

import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicLongArray;

import se.l4.vibe.VibeException;

/**
 * A {@link PercentileCounter} that uses a fixed set of buckets that values are
 * sorted into.
 * 
 * 

* Each bucket represent a range, the first value given in this array is the start * of the first bucket and the last one is the upper bound for the next to last * bucket. * *

* Example: *

 * [0, 100, 400, 500]
 * 
* * Buckets created: *
    *
  1. 0-100
  2. *
  3. 101-400
  4. *
  5. 401-500
  6. *
  7. 501-*
  8. *
* * @author Andreas Holstenson * */ public class BucketPercentileCounter implements PercentileCounter { private final int[] limits; private volatile AtomicLongArray buckets; private final AtomicLong total; public BucketPercentileCounter(int... limits) { for(int i=1, n=limits.length; i= limits[i]) { throw new VibeException("Limits must be in ascending order"); } } this.limits = limits; buckets = new AtomicLongArray(limits.length); total = new AtomicLong(); } @Override public void add(long value) { int i = getBucket((int) value); if(i == -1) return; while(true) { long current = total.get(); if(total.compareAndSet(current, current+value)) { buckets.incrementAndGet(i); break; } } } @Override public void reset() { AtomicLongArray buckets = new AtomicLongArray(limits.length); while(true) { long current = total.get(); if(total.compareAndSet(current, 0)) { this.buckets = buckets; break; } } } @Override public PercentileSnapshot get() { long[] values = new long[limits.length]; int samples = 0; for(int i=0, n=limits.length; i 0) { high = i - 1; } else { return i; } } if(limits[i] >= time) { return i - 1; } else { return i; } } private static class BucketSnapshot implements PercentileSnapshot { private long samples; private long total; private long[] buckets; private int[] limits; public BucketSnapshot(long samples, long total, long[] buckets, int[] limits) { this.samples = samples; this.total = total; this.buckets = buckets; this.limits = limits; } @Override public long getTotal() { return total; } @Override public long getSamples() { return samples; } @Override public long estimatePercentile(int percentile) { long sum = 0; long cutoff = (long) Math.ceil((percentile / 100.0) * samples) - 1; for(int i=0, n=buckets.length-1; i= cutoff) { return limits[i+1]; } } return -1; } @Override public PercentileSnapshot add(PercentileSnapshot other) { BucketSnapshot s = (BucketSnapshot) other; long[] newBuckets = new long[buckets.length]; for(int i=0, n=newBuckets.length; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy