Skip to content

Commit 80e1a6e

Browse files
committed
Improve Frugal merging.
1 parent 4400685 commit 80e1a6e

File tree

4 files changed

+23
-117
lines changed

4 files changed

+23
-117
lines changed

src/main/java/org/elasticsearch/search/aggregations/metrics/percentile/PercentileParser.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.elasticsearch.search.internal.SearchContext;
3333

3434
import java.io.IOException;
35+
import java.util.Arrays;
3536
import java.util.HashMap;
3637
import java.util.Map;
3738

@@ -101,7 +102,8 @@ public AggregatorFactory parse(String aggregationName, XContentParser parser, Se
101102
values.add(percent);
102103
}
103104
percents = values.toArray();
104-
105+
// Some impls rely on the fact that percents are sorted
106+
Arrays.sort(percents);
105107
}
106108
} else if (token == XContentParser.Token.START_OBJECT) {
107109
if ("params".equals(currentFieldName)) {

src/main/java/org/elasticsearch/search/aggregations/metrics/percentile/frugal/Frugal.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package org.elasticsearch.search.aggregations.metrics.percentile.frugal;
22

3+
import com.carrotsearch.hppc.DoubleArrayList;
34
import jsr166y.ThreadLocalRandom;
45
import org.apache.lucene.util.OpenBitSet;
56
import org.apache.lucene.util.RamUsageEstimator;
67
import org.elasticsearch.common.io.stream.StreamInput;
78
import org.elasticsearch.common.io.stream.StreamOutput;
9+
import org.elasticsearch.common.util.CollectionUtils;
810
import org.elasticsearch.search.aggregations.metrics.percentile.InternalPercentiles;
911

1012
import java.io.IOException;
@@ -211,8 +213,7 @@ public long ramBytesUsed() {
211213
private class Merger implements InternalPercentiles.Estimator.Merger<Frugal> {
212214

213215
private final int expectedMerges;
214-
private double[] merging;
215-
private int currentMerge;
216+
private DoubleArrayList merging;
216217

217218
private Merger(int expectedMerges) {
218219
this.expectedMerges = expectedMerges;
@@ -226,23 +227,35 @@ public void add(Frugal frugal) {
226227
}
227228

228229
if (merging == null) {
229-
merging = new double[expectedMerges * percents.length];
230+
merging = new DoubleArrayList(expectedMerges * percents.length);
230231
}
231232

232233
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);
234246
}
235-
currentMerge++;
236247
}
237248

238249
@Override
239250
public Frugal merge() {
240-
if (currentMerge > 0) {
251+
if (merging != null) {
241252
if (estimates == null) {
242253
estimates = new double[percents.length];
243254
}
255+
CollectionUtils.sort(merging);
256+
final int numMerges = merging.size() / percents.length;
244257
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)));
246259
}
247260
}
248261
return Frugal.this;

src/main/java/org/elasticsearch/search/aggregations/metrics/percentile/frugal/QuickSelect.java

Lines changed: 0 additions & 59 deletions
This file was deleted.

src/test/java/org/elasticsearch/search/aggregations/metrics/percentile/QuickSelectTests.java

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)