MergeableExponentiallyDecayingReservoir { public double[] getUnsortedValues() { lockForRegularUsage(); try { Collection<Double> dataValues = _values.values(); double[] result = new double[dataValues.size()]; int j = 0; for (Double dataValue : dataValues) { result[j++] = dataValue.doubleValue(); } return result; } finally { unlockForRegularUsage(); } } MergeableExponentiallyDecayingReservoir();  MergeableExponentiallyDecayingReservoir(int size, double alpha);  MergeableExponentiallyDecayingReservoir(int size, double alpha, Clock clock); int size(); void update(double value); void update(double value, long timestamp); void merge(MergeableExponentiallyDecayingReservoir other); long getLandmark(); ConcurrentNavigableMap<Double, Double> getDescendingMap(); double[] getUnsortedValues(); ConcurrentNavigableMap<Double, Double> rescale(long now, long next, long startTime); static final int DEFAULT_SIZE; static final double DEFAULT_ALPHA; }
@Test public void testEmptyReservoir() { MergeableExponentiallyDecayingReservoir res = new MergeableExponentiallyDecayingReservoir(10, 0.015); double[] dataValues = res.getUnsortedValues(); assertEquals("expected empty dataValues array", 0, dataValues.length); double result = StatUtils.percentile(dataValues, 50.0); assertEquals("expected NaN for 50th percentile of empty array", Double.NaN, result); result = StatUtils.max(dataValues); assertEquals("expected NaN for max of empty array", Double.NaN, result); }