Skip to content

Commit 9cff744

Browse files
committed
Added LonghHash for early detection of existing values
1 parent c27faa0 commit 9cff744

File tree

1 file changed

+23
-3
lines changed

1 file changed

+23
-3
lines changed

x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/sort/LongTopNUniqueSort.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.elasticsearch.common.util.BigArrays;
1111
import org.elasticsearch.common.util.BinarySearcher;
1212
import org.elasticsearch.common.util.LongArray;
13+
import org.elasticsearch.common.util.LongHash;
1314
import org.elasticsearch.core.Releasable;
1415
import org.elasticsearch.core.Releasables;
1516
import org.elasticsearch.search.sort.BucketedSort;
@@ -27,15 +28,30 @@ public class LongTopNUniqueSort implements Releasable {
2728

2829
private final LongArray values;
2930
private final LongBinarySearcher searcher;
31+
/**
32+
* Hash holding the unique seen values.
33+
* Adding is an O(1) operation to check if the new value is already in the top, and avoid trying to add it again, which is O(log(n)).
34+
*/
35+
private final LongHash seenUniqueValues;
3036

3137
private int count;
3238

3339
public LongTopNUniqueSort(BigArrays bigArrays, SortOrder order, int limit) {
3440
this.order = order;
3541
this.limit = limit;
3642
this.count = 0;
37-
this.values = bigArrays.newLongArray(limit, false);
38-
this.searcher = new LongBinarySearcher(values, order);
43+
44+
boolean success = false;
45+
try {
46+
this.values = bigArrays.newLongArray(limit, false);
47+
this.seenUniqueValues = new LongHash(1, bigArrays);
48+
this.searcher = new LongBinarySearcher(values, order);
49+
success = true;
50+
} finally {
51+
if (success == false) {
52+
close();
53+
}
54+
}
3955
}
4056

4157
public boolean collect(long value) {
@@ -49,6 +65,10 @@ public boolean collect(long value) {
4965
return false;
5066
}
5167

68+
if (seenUniqueValues.add(value) < 0) {
69+
return true;
70+
}
71+
5272
if (count == 0) {
5373
values.set(0, value);
5474
count++;
@@ -159,6 +179,6 @@ private boolean betterThan(long lhs, long rhs) {
159179

160180
@Override
161181
public final void close() {
162-
Releasables.close(values);
182+
Releasables.close(values, seenUniqueValues);
163183
}
164184
}

0 commit comments

Comments
 (0)