All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.infinispan.extendedstats.percentiles.ReservoirSampler Maven / Gradle / Ivy

There is a newer version: 14.0.31.Final
Show newest version
package org.infinispan.extendedstats.percentiles;

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Keeps the sample for percentile calculations.
 * 

* Please check this for more details * * @author Roberto Palmieri * @author Diego Didona * @author Pedro Ruivo * @since 6.0 */ public class ReservoirSampler { private static final int DEFAULT_NUM_SPOTS = 100; private final AtomicInteger index; private final Random random; private double[] reservoir; public ReservoirSampler() { this(DEFAULT_NUM_SPOTS); } public ReservoirSampler(int numSpots) { this.reservoir = createArray(numSpots); this.index = new AtomicInteger(0); random = new Random(System.nanoTime()); } public synchronized final void insertSample(double sample) { int i = index.getAndIncrement(); if (i < reservoir.length) reservoir[i] = sample; else { int randGenerated = random.nextInt(i + 2);//should be nextInt(index+1) but nextInt is exclusive if (randGenerated < reservoir.length) { reservoir[randGenerated] = sample; } } } /** * @param k the percentage of observations. Should be a value between 0 and 100 exclusively. * @return the percentile value for the k% observations. * @throws IllegalArgumentException if k is not between 0 and 100 exclusively. */ public synchronized final double getKPercentile(int k) throws IllegalArgumentException { if (k < 0 || k > 100) { throw new IllegalArgumentException(k + " should be between 0 and 100 exclusive"); } double[] copy = createArray(reservoir.length); System.arraycopy(this.reservoir, 0, copy, 0, reservoir.length); Arrays.sort(copy); return copy[this.getIndex(k)]; } public synchronized final void reset() { this.index.set(0); this.reservoir = createArray(reservoir.length); } private int getIndex(int k) { //I solve the proportion k:100=x:NUM_SAMPLE //Every percentage is covered by NUM_SAMPLE / 100 buckets; I consider here only the first as representative //of a percentage return reservoir.length * (k - 1) / 100; } private double[] createArray(int size) { return new double[size]; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy