/*
* Copyright (C) 2012, 2016 higherfrequencytrading.com
* Copyright (C) 2016 Roman Leventov
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.openhft.chronicle.map;
/**
* Created by peter.lawrey on 28/02/14.
*/
public class Histogram {
static final String[] FRACTION_STR = "worst,99.99,99.9,99,90,50".split(",");
static final int[] FRACTIONS = {Integer.MAX_VALUE, 10000, 1000, 100, 10, 2};
static final int BITS_OF_ACCURACY = 5;
final int[] counters = new int[40 << BITS_OF_ACCURACY];
static final int MANTISSA = 52;
static final int BITS_TO_TRUNCATE = MANTISSA - BITS_OF_ACCURACY;
long count = 0;
public void sample(long value) {
long rawValue = Double.doubleToRawLongBits(value) >> BITS_TO_TRUNCATE;
int bucket = (int) rawValue - (1023 << BITS_OF_ACCURACY);
counters[bucket]++;
count++;
}
public void printResults() {
for (int i = 0; i < counters.length; i++) {
if (counters[i] == 0) continue;
double d = indexToDouble(i);
if (d < 10000 && d * counters[i] < 20000) continue;
System.out.println((long) d + ":" + counters[i]);
}
}
private double indexToDouble(int i) {
return Double.longBitsToDouble((i + (1023L << BITS_OF_ACCURACY)) << BITS_TO_TRUNCATE);
}
public void printPercentiles() {
printPercentiles("");
}
public void printPercentiles(String tail) {
long[] times = new long[FRACTIONS.length];
int f = 0;
long total = 0;
for (int pos = counters.length - 1; pos >= 0 && f < FRACTIONS.length; pos--) {
total += counters[pos];
if (total > count / FRACTIONS[f]) {
times[f++] = (long) indexToDouble(pos);
}
}
// print in reverse order.
StringBuilder sb = new StringBuilder();
for (int i = FRACTIONS.length - 1; i >= 0; i--) {
sb.append(FRACTION_STR[i]).append("/");
}
sb.setLength(sb.length() - 1);
sb.append(" : ");
for (int i = FRACTIONS.length - 1; i >= 0; i--) {
long time = times[i];
if (time < 10000)
sb.append(time / 100 / 10.0);
else
sb.append(time / 1000);
sb.append(" / ");
}
sb.setLength(sb.length() - 3);
sb.append(tail);
System.out.println(sb);
}
}