1010import org .elasticsearch .common .util .BigArrays ;
1111import org .elasticsearch .common .util .BinarySearcher ;
1212import org .elasticsearch .common .util .LongArray ;
13+ import org .elasticsearch .common .util .LongHash ;
1314import org .elasticsearch .core .Releasable ;
1415import org .elasticsearch .core .Releasables ;
1516import org .elasticsearch .search .sort .SortOrder ;
@@ -27,15 +28,25 @@ public class LongTopNSet implements Releasable {
2728
2829 private final LongArray values ;
2930 private final LongBinarySearcher searcher ;
31+ private final LongHash seenValues ;
3032
3133 private int count ;
3234
3335 public LongTopNSet (BigArrays bigArrays , SortOrder order , int limit ) {
3436 this .order = order ;
3537 this .limit = limit ;
3638 this .count = 0 ;
37- this .values = bigArrays .newLongArray (limit , false );
38- this .searcher = new LongBinarySearcher (values , order );
39+ boolean success = false ;
40+ try {
41+ this .values = bigArrays .newLongArray (limit , false );
42+ this .searcher = new LongBinarySearcher (values , order );
43+ this .seenValues = new LongHash (limit , 0.05f , bigArrays );
44+ success = true ;
45+ } finally {
46+ if (success == false ) {
47+ close ();
48+ }
49+ }
3950 }
4051
4152 /**
@@ -58,6 +69,11 @@ public boolean collect(long value) {
5869 return true ;
5970 }
6071
72+ if (seenValues .add (value ) < 0 ) {
73+ // The value was already added
74+ return true ;
75+ }
76+
6177 int insertionIndex = this .searcher .search (0 , count - 1 , value );
6278
6379 if (insertionIndex == count - 1 ) {
@@ -168,6 +184,6 @@ private boolean betterThan(long lhs, long rhs) {
168184
169185 @ Override
170186 public final void close () {
171- Releasables .close (values );
187+ Releasables .close (values , seenValues );
172188 }
173189}
0 commit comments