1
1
package org .elasticsearch .search .aggregations .metrics .percentile .frugal ;
2
2
3
+ import com .carrotsearch .hppc .DoubleArrayList ;
3
4
import jsr166y .ThreadLocalRandom ;
4
5
import org .apache .lucene .util .OpenBitSet ;
5
6
import org .apache .lucene .util .RamUsageEstimator ;
6
7
import org .elasticsearch .common .io .stream .StreamInput ;
7
8
import org .elasticsearch .common .io .stream .StreamOutput ;
9
+ import org .elasticsearch .common .util .CollectionUtils ;
8
10
import org .elasticsearch .search .aggregations .metrics .percentile .InternalPercentiles ;
9
11
10
12
import java .io .IOException ;
@@ -211,8 +213,7 @@ public long ramBytesUsed() {
211
213
private class Merger implements InternalPercentiles .Estimator .Merger <Frugal > {
212
214
213
215
private final int expectedMerges ;
214
- private double [] merging ;
215
- private int currentMerge ;
216
+ private DoubleArrayList merging ;
216
217
217
218
private Merger (int expectedMerges ) {
218
219
this .expectedMerges = expectedMerges ;
@@ -226,23 +227,35 @@ public void add(Frugal frugal) {
226
227
}
227
228
228
229
if (merging == null ) {
229
- merging = new double [ expectedMerges * percents .length ] ;
230
+ merging = new DoubleArrayList ( expectedMerges * percents .length ) ;
230
231
}
231
232
232
233
for (int i = 0 ; i < percents .length ; ++i ) {
233
- merging [(expectedMerges * i ) + currentMerge ] = frugal .estimate (i );
234
+ merging .add (frugal .estimate (i ));
235
+ }
236
+ }
237
+
238
+ private double weightedValue (DoubleArrayList list , double index ) {
239
+ assert index <= list .size () - 1 ;
240
+ final int intIndex = (int ) index ;
241
+ final double d = index - intIndex ;
242
+ if (d == 0 ) {
243
+ return list .get (intIndex );
244
+ } else {
245
+ return (1 - d ) * list .get (intIndex ) + d * list .get (intIndex + 1 );
234
246
}
235
- currentMerge ++;
236
247
}
237
248
238
249
@ Override
239
250
public Frugal merge () {
240
- if (currentMerge > 0 ) {
251
+ if (merging != null ) {
241
252
if (estimates == null ) {
242
253
estimates = new double [percents .length ];
243
254
}
255
+ CollectionUtils .sort (merging );
256
+ final int numMerges = merging .size () / percents .length ;
244
257
for (int i = 0 ; i < percents .length ; ++i ) {
245
- estimates [i ] = QuickSelect . quickSelect (merging , i * expectedMerges , ( i * expectedMerges ) + currentMerge - 1 , currentMerge / 2 );
258
+ estimates [i ] = weightedValue (merging , numMerges * i + ( percents [ i ] / 100 * ( numMerges - 1 )) );
246
259
}
247
260
}
248
261
return Frugal .this ;
0 commit comments