/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.kafka.common.metrics.stats;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Random;
import org.apache.kafka.common.metrics.stats.Histogram.BinScheme;
import org.apache.kafka.common.metrics.stats.Histogram.ConstantBinScheme;
import org.apache.kafka.common.metrics.stats.Histogram.LinearBinScheme;
import org.junit.Test;
public class HistogramTest {
private static final double EPS = 0.0000001d;
@Test
public void testHistogram() {
BinScheme scheme = new ConstantBinScheme(12, -5, 5);
Histogram hist = new Histogram(scheme);
for (int i = -5; i < 5; i++)
hist.record(i);
for (int i = 0; i < 10; i++)
assertEquals(scheme.fromBin(i + 1), hist.value(i / 10.0 + EPS), EPS);
}
@Test
public void testConstantBinScheme() {
ConstantBinScheme scheme = new ConstantBinScheme(5, -5, 5);
assertEquals("A value below the lower bound should map to the first bin", 0, scheme.toBin(-5.01));
assertEquals("A value above the upper bound should map to the last bin", 4, scheme.toBin(5.01));
assertEquals("Check boundary of bucket 1", 1, scheme.toBin(-5));
assertEquals("Check boundary of bucket 4", 4, scheme.toBin(5));
assertEquals("Check boundary of bucket 3", 3, scheme.toBin(4.9999));
checkBinningConsistency(new ConstantBinScheme(4, 0, 5));
checkBinningConsistency(scheme);
}
@Test
public void testLinearBinScheme() {
LinearBinScheme scheme = new LinearBinScheme(10, 10);
checkBinningConsistency(scheme);
}
private void checkBinningConsistency(BinScheme scheme) {
for (int bin = 0; bin < scheme.bins(); bin++) {
double fromBin = scheme.fromBin(bin);
int binAgain = scheme.toBin(fromBin + EPS);
assertEquals("unbinning and rebinning the bin " + bin
+ " gave a different result ("
+ fromBin
+ " was placed in bin "
+ binAgain
+ " )", bin, binAgain);
}
}
public static void main(String[] args) {
Random random = new Random();
System.out.println("[-100, 100]:");
for (BinScheme scheme : Arrays.asList(new ConstantBinScheme(1000, -100, 100),
new ConstantBinScheme(100, -100, 100),
new ConstantBinScheme(10, -100, 100))) {
Histogram h = new Histogram(scheme);
for (int i = 0; i < 10000; i++)
h.record(200.0 * random.nextDouble() - 100.0);
for (double quantile = 0.0; quantile < 1.0; quantile += 0.05)
System.out.printf("%5.2f: %.1f, ", quantile, h.value(quantile));
System.out.println();
}
System.out.println("[0, 1000]");
for (BinScheme scheme : Arrays.asList(new LinearBinScheme(1000, 1000),
new LinearBinScheme(100, 1000),
new LinearBinScheme(10, 1000))) {
Histogram h = new Histogram(scheme);
for (int i = 0; i < 10000; i++)
h.record(1000.0 * random.nextDouble());
for (double quantile = 0.0; quantile < 1.0; quantile += 0.05)
System.out.printf("%5.2f: %.1f, ", quantile, h.value(quantile));
System.out.println();
}
}
}