in spectator-api/src/main/java/com/netflix/spectator/api/histogram/PercentileBuckets.java [181:228]
public static void percentiles(double[] counts, double[] pcts, double[] results) {
Preconditions.checkArg(counts.length == BUCKET_VALUES.length,
"counts is not the same size as buckets array");
Preconditions.checkArg(pcts.length > 0, "pct array cannot be empty");
Preconditions.checkArg(pcts.length == results.length,
"pcts is not the same size as results array");
int lastNonZeroIdx = 0;
double total = 0.0;
for (int i = 0; i < counts.length; ++i) {
double c = counts[i];
if (c > 0.0 && Double.isFinite(c)) {
total += c;
lastNonZeroIdx = i;
}
}
int pctIdx = 0;
double prev = 0.0;
double prevP = 0.0;
long prevB = 0;
for (int i = 0; i <= lastNonZeroIdx; ++i) {
double next = prev + counts[i];
double nextP = 100.0 * next / total;
long nextB = BUCKET_VALUES[i];
while (pctIdx < pcts.length && nextP >= pcts[pctIdx]) {
double f = (pcts[pctIdx] - prevP) / (nextP - prevP);
if (Double.isNaN(f))
results[pctIdx] = 0.0;
else
results[pctIdx] = f * (nextB - prevB) + prevB;
++pctIdx;
}
if (pctIdx >= pcts.length) break;
prev = next;
prevP = nextP;
prevB = nextB;
}
double nextP = 100.0;
long nextB = BUCKET_VALUES[lastNonZeroIdx];
while (pctIdx < pcts.length) {
double f = (pcts[pctIdx] - prevP) / (nextP - prevP);
results[pctIdx] = f * (nextB - prevB) + prevB;
++pctIdx;
}
}