Skip to content

Commit 4b73745

Browse files
committed
Overload getPercentile to allow re-use of a snapshot
1 parent 31f2083 commit 4b73745

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

server/src/main/java/org/elasticsearch/common/metrics/ExponentialBucketHistogram.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,26 @@ public long[] getSnapshot() {
7676
*
7777
* @param percentile The percentile as a fraction (in [0, 1.0])
7878
* @return A value greater than the specified fraction of values in the histogram
79+
* @throws IllegalArgumentException if the requested percentile is invalid
7980
*/
8081
public long getPercentile(float percentile) {
81-
assert percentile >= 0 && percentile <= 1;
82-
final long[] snapshot = getSnapshot();
82+
return getPercentile(percentile, getSnapshot(), getBucketUpperBounds());
83+
}
84+
85+
/**
86+
* Calculate the Nth percentile value
87+
*
88+
* @param percentile The percentile as a fraction (in [0, 1.0])
89+
* @param snapshot An array of frequencies of handling times in buckets with upper bounds as returned by {@link #getBucketUpperBounds()}
90+
* @param bucketUpperBounds The upper bounds of the buckets in the histogram, as returned by {@link #getBucketUpperBounds()}
91+
* @return A value greater than the specified fraction of values in the histogram
92+
* @throws IllegalArgumentException if the requested percentile is invalid
93+
*/
94+
public long getPercentile(float percentile, long[] snapshot, int[] bucketUpperBounds) {
95+
assert snapshot.length == BUCKET_COUNT && bucketUpperBounds.length == BUCKET_COUNT - 1;
96+
if (percentile < 0 || percentile > 1) {
97+
throw new IllegalArgumentException("Requested percentile must be in [0, 1.0], percentile=" + percentile);
98+
}
8399
final long totalCount = Arrays.stream(snapshot).sum();
84100
long percentileIndex = (long) Math.ceil(totalCount * percentile);
85101
// Find which bucket has the Nth percentile value and return the upper bound value.
@@ -89,7 +105,7 @@ public long getPercentile(float percentile) {
89105
if (i == snapshot.length - 1) {
90106
return Long.MAX_VALUE;
91107
} else {
92-
return getBucketUpperBounds()[i];
108+
return bucketUpperBounds[i];
93109
}
94110
}
95111
}

server/src/test/java/org/elasticsearch/common/metrics/ExponentialBucketHistogramTests.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,12 @@ public void testPercentile() {
9090
for (int i = 0; i < valueCount; i++) {
9191
histogram.addObservation(i);
9292
}
93+
final long[] snapshot = histogram.getSnapshot();
94+
final int[] bucketUpperBounds = ExponentialBucketHistogram.getBucketUpperBounds();
9395
for (int i = 0; i <= 100; i++) {
9496
final float percentile = i / 100.0f;
9597
final long actualPercentile = (long) Math.ceil(valueCount * percentile);
96-
final long histogramPercentile = histogram.getPercentile(percentile);
98+
final long histogramPercentile = histogram.getPercentile(percentile, snapshot, bucketUpperBounds);
9799
final String message = Strings.format("%d percentile is %d (actual=%d)", i, histogramPercentile, actualPercentile);
98100
assertThat(message, histogramPercentile, greaterThanOrEqualTo(actualPercentile));
99101
}

0 commit comments

Comments
 (0)