currentPercentileSnapshot = new PercentileSnapshot(allBuckets);
PercentileSnapshot ps = new PercentileSnapshot(1000, 1000, 1000, 2000, 1000, 500, 200, 200, 1600, 200, 1600, 1600); assertEquals(ps.getPercentile(0.15), p.getPercentile(0.15)); assertEquals(ps.getPercentile(0.50), p.getPercentile(0.50)); assertEquals(ps.getPercentile(0.90), p.getPercentile(0.90)); assertEquals(ps.getPercentile(0.995), p.getPercentile(0.995)); System.out.println("100th: " + ps.getPercentile(100) + " " + p.getPercentile(100)); System.out.println("99.5th: " + ps.getPercentile(99.5) + " " + p.getPercentile(99.5)); System.out.println("99th: " + ps.getPercentile(99) + " " + p.getPercentile(99)); System.out.println("90th: " + ps.getPercentile(90) + " " + p.getPercentile(90)); System.out.println("50th: " + ps.getPercentile(50) + " " + p.getPercentile(50)); System.out.println("10th: " + ps.getPercentile(10) + " " + p.getPercentile(10)); assertEquals(991, ps.getMean());
currentPercentileSnapshot = new PercentileSnapshot(allBuckets);
/** * Compute a percentile from the underlying rolling buckets of values. * <p> * For performance reasons it maintains a single snapshot of the sorted values from all buckets that is re-generated each time the bucket rotates. * <p> * This means that if a bucket is 5000ms, then this method will re-compute a percentile at most once every 5000ms. * * @param percentile * value such as 99 (99th percentile), 99.5 (99.5th percentile), 50 (median, 50th percentile) to compute and retrieve percentile from rolling buckets. * @return int percentile value */ public int getPercentile(double percentile) { /* no-op if disabled */ if (!enabled.get()) return -1; // force logic to move buckets forward in case other requests aren't making it happen getCurrentBucket(); // fetch the current snapshot return getCurrentPercentileSnapshot().getPercentile(percentile); }
/** * This returns the mean (average) of all values in the current snapshot. This is not a percentile but often desired so captured and exposed here. * * @return mean of all values */ public int getMean() { /* no-op if disabled */ if (!enabled.get()) return -1; // force logic to move buckets forward in case other requests aren't making it happen getCurrentBucket(); // fetch the current snapshot return getCurrentPercentileSnapshot().getMean(); }
/** * Force a reset so that percentiles start being gathered from scratch. */ public void reset() { /* no-op if disabled */ if (!enabled.get()) return; // clear buckets so we start over again buckets.clear(); // and also make sure the percentile snapshot gets reset currentPercentileSnapshot = new PercentileSnapshot(buckets.getArray()); }
/** * Provides percentile computation. */ public int getPercentile(double percentile) { if (length == 0) { return 0; } return computePercentile(percentile); }
@Test public void testPercentileAlgorithm_Extremes() { PercentileSnapshot p = new PercentileSnapshot(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 800, 768, 657, 700, 867); System.out.println("0.01: " + p.getPercentile(0.01)); System.out.println("10th: " + p.getPercentile(10)); System.out.println("Median: " + p.getPercentile(50)); System.out.println("75th: " + p.getPercentile(75)); System.out.println("90th: " + p.getPercentile(90)); System.out.println("99th: " + p.getPercentile(99)); System.out.println("99.5th: " + p.getPercentile(99.5)); System.out.println("99.99: " + p.getPercentile(99.99)); Assert.assertEquals(2, p.getPercentile(50)); Assert.assertEquals(2, p.getPercentile(10)); Assert.assertEquals(2, p.getPercentile(75)); if (p.getPercentile(95) < 600) { fail("We expect the 90th to be over 600 to show the extremes but got: " + p.getPercentile(90)); } if (p.getPercentile(99) < 600) { fail("We expect the 99th to be over 600 to show the extremes but got: " + p.getPercentile(99)); } }
/** * Compute a percentile from the underlying rolling buckets of values. * <p> * For performance reasons it maintains a single snapshot of the sorted values from all buckets that is re-generated each time the bucket rotates. * <p> * This means that if a bucket is 5000ms, then this method will re-compute a percentile at most once every 5000ms. * * @param percentile * value such as 99 (99th percentile), 99.5 (99.5th percentile), 50 (median, 50th percentile) to compute and retrieve percentile from rolling buckets. * @return int percentile value */ public int getPercentile(double percentile) { /* no-op if disabled */ if (!enabled.get()) return -1; // force logic to move buckets forward in case other requests aren't making it happen getCurrentBucket(); // fetch the current snapshot return getCurrentPercentileSnapshot().getPercentile(percentile); }
@Test public void testPercentileAlgorithm_Median4() { PercentileSnapshot list = new PercentileSnapshot(300, 75, 125, 500, 100, 160, 180, 200, 210, 50, 170); // unsorted so it is expected to sort it for us // list.addValue(300); // 10 // list.addValue(75); // 2 // list.addValue(125); // 4 // list.addValue(500); // 11 // list.addValue(100); // 3 // list.addValue(160); // 5 // list.addValue(180); // 7 // list.addValue(200); // 8 // list.addValue(210); // 9 // list.addValue(50); // 1 // list.addValue(170); // 6 Assert.assertEquals(175, list.getPercentile(50)); }
@Test public void testPercentileAlgorithm_Median3() { PercentileSnapshot list = new PercentileSnapshot(50, 75, 100, 125, 160, 170, 180, 200, 210, 300, 500); // list.addValue(50); // 1 // list.addValue(75); // 2 // list.addValue(100); // 3 // list.addValue(125); // 4 // list.addValue(160); // 5 // list.addValue(170); // 6 // list.addValue(180); // 7 // list.addValue(200); // 8 // list.addValue(210); // 9 // list.addValue(300); // 10 // list.addValue(500); // 11 Assert.assertEquals(175, list.getPercentile(50)); }
public PercentileSnapshot getPercentileForValues(int... values) { return new PercentileSnapshot(values); }
/** * This returns the mean (average) of all values in the current snapshot. This is not a percentile but often desired so captured and exposed here. * * @return mean of all values */ public int getMean() { /* no-op if disabled */ if (!enabled.get()) return -1; // force logic to move buckets forward in case other requests aren't making it happen getCurrentBucket(); // fetch the current snapshot return getCurrentPercentileSnapshot().getMean(); }
/** * Force a reset so that percentiles start being gathered from scratch. */ public void reset() { /* no-op if disabled */ if (!enabled.get()) return; // clear buckets so we start over again buckets.clear(); // and also make sure the percentile snapshot gets reset currentPercentileSnapshot = new PercentileSnapshot(buckets.getArray()); }
@Test public void testPercentileAlgorithm_Percentiles() { PercentileSnapshot p = getPercentileForValues(10, 30, 20, 40); Assert.assertEquals(22, p.getPercentile(30), 1.0e-5); Assert.assertEquals(20, p.getPercentile(25), 1.0e-5); Assert.assertEquals(40, p.getPercentile(75), 1.0e-5); Assert.assertEquals(30, p.getPercentile(50), 1.0e-5); // invalid percentiles Assert.assertEquals(10, p.getPercentile(-1)); Assert.assertEquals(40, p.getPercentile(101)); }
@Test public void testPercentileAlgorithm_LowPercentile() { PercentileSnapshot p = getPercentileForValues(1, 2); Assert.assertEquals(1, p.getPercentile(25)); Assert.assertEquals(2, p.getPercentile(75)); }
@Test public void testPercentileAlgorithm_HighPercentile() { PercentileSnapshot p = getPercentileForValues(1, 2, 3); Assert.assertEquals(2, p.getPercentile(50)); Assert.assertEquals(3, p.getPercentile(75)); }
/** * Provides percentile computation. */ public int getPercentile(double percentile) { if (length == 0) { return 0; } return computePercentile(percentile); }
@Test public void testPercentileAlgorithm_NISTExample() { PercentileSnapshot p = getPercentileForValues(951772, 951567, 951937, 951959, 951442, 950610, 951591, 951195, 951772, 950925, 951990, 951682); Assert.assertEquals(951983, p.getPercentile(90)); Assert.assertEquals(951990, p.getPercentile(100)); }
@Test public void testPercentileAlgorithm_Median2() { PercentileSnapshot list = new PercentileSnapshot(100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 500); Assert.assertEquals(100, list.getPercentile(50)); }