1
1
package org .elasticsearch .search .aggregations .metrics .percentile .qdigest ;
2
2
3
- import it . unimi . dsi . fastutil . Hash ;
4
- import it . unimi . dsi . fastutil . longs . Long2LongOpenHashMap ;
5
- import it . unimi . dsi . fastutil . longs . LongArrayFIFOQueue ;
3
+ import com . carrotsearch . hppc . LongArrayDeque ;
4
+ import com . carrotsearch . hppc . LongLongOpenHashMap ;
5
+ import com . carrotsearch . hppc . cursors . LongLongCursor ;
6
6
import org .apache .lucene .util .CollectionUtil ;
7
7
import org .apache .lucene .util .RamUsageEstimator ;
8
8
import org .elasticsearch .common .io .stream .StreamInput ;
@@ -74,13 +74,13 @@ public int compare(long[] ra, long[] rb) {
74
74
}
75
75
};
76
76
77
- private static final int MAP_INITIAL_SIZE = Hash . DEFAULT_INITIAL_SIZE ;
78
- private static final float MAP_LOAD_FACTOR = Hash . VERY_FAST_LOAD_FACTOR ;
77
+ private static final int MAP_INITIAL_SIZE = 16 ;
78
+ private static final float MAP_LOAD_FACTOR = 0.5f ;
79
79
80
80
private long size ;
81
81
private long capacity = 1 ;
82
82
private double compressionFactor ;
83
- private Long2LongOpenHashMap node2count = new Long2LongOpenHashMap (MAP_INITIAL_SIZE , MAP_LOAD_FACTOR );
83
+ private LongLongOpenHashMap node2count = new LongLongOpenHashMap (MAP_INITIAL_SIZE , MAP_LOAD_FACTOR );
84
84
85
85
public QDigestState (double compressionFactor ) {
86
86
this .compressionFactor = compressionFactor ;
@@ -168,15 +168,17 @@ public static QDigestState unionOf(QDigestState a, QDigestState b) {
168
168
QDigestState res = new QDigestState (a .compressionFactor );
169
169
res .capacity = a .capacity ;
170
170
res .size = a .size + b .size ;
171
- for (long k : a .node2count .keySet ()) {
171
+ for (LongLongCursor cursor : a .node2count ) {
172
+ final long k = cursor .key ;
172
173
res .node2count .put (k , a .node2count .get (k ));
173
174
}
174
175
175
176
if (b .capacity > res .capacity ) {
176
177
res .rebuildToCapacity (b .capacity );
177
178
}
178
179
179
- for (long k : b .node2count .keySet ()) {
180
+ for (LongLongCursor cursor : b .node2count ) {
181
+ final long k = cursor .key ;
180
182
res .node2count .put (k , b .get (k ) + res .get (k ));
181
183
}
182
184
@@ -186,7 +188,7 @@ public static QDigestState unionOf(QDigestState a, QDigestState b) {
186
188
}
187
189
188
190
private void rebuildToCapacity (long newCapacity ) {
189
- Long2LongOpenHashMap newNode2count = new Long2LongOpenHashMap (MAP_INITIAL_SIZE , MAP_LOAD_FACTOR );
191
+ LongLongOpenHashMap newNode2count = new LongLongOpenHashMap (MAP_INITIAL_SIZE , MAP_LOAD_FACTOR );
190
192
// rebuild to newLogCapacity.
191
193
// This means that our current tree becomes a leftmost subtree
192
194
// of the new tree.
@@ -198,7 +200,12 @@ private void rebuildToCapacity(long newCapacity) {
198
200
// This is easy to see if you draw it on paper.
199
201
// Process the keys by "layers" in the original tree.
200
202
long scaleR = newCapacity / capacity - 1 ;
201
- Long [] keys = node2count .keySet ().toArray (new Long [node2count .size ()]);
203
+ final long [] keys = new long [node2count .size ()];
204
+ int i = 0 ;
205
+ for (LongLongCursor cursor : node2count ) {
206
+ final long k = cursor .key ;
207
+ keys [i ++] = k ;
208
+ }
202
209
Arrays .sort (keys );
203
210
long scaleL = 1 ;
204
211
for (long k : keys ) {
@@ -214,8 +221,8 @@ private void rebuildToCapacity(long newCapacity) {
214
221
215
222
private void compressFully () {
216
223
// Restore property 2 at each node.
217
- Long [] allNodes = node2count . keySet (). toArray ( new Long [ node2count . size ()]);
218
- for ( long node : allNodes ) {
224
+ for ( LongLongCursor cursor : node2count ) {
225
+ final long node = cursor . key ;
219
226
compressDownward (node );
220
227
}
221
228
}
@@ -257,10 +264,10 @@ private void compressUpward(long node) {
257
264
private void compressDownward (long seedNode ) {
258
265
double threshold = Math .floor (size / compressionFactor );
259
266
// P2 check same as above but shorter and slower (and invoked rarely)
260
- LongArrayFIFOQueue q = new LongArrayFIFOQueue ();
261
- q .enqueue (seedNode );
267
+ LongArrayDeque q = new LongArrayDeque ();
268
+ q .addLast (seedNode );
262
269
while (!q .isEmpty ()) {
263
- long node = q .dequeueLong ();
270
+ long node = q .removeFirst ();
264
271
long atNode = get (node );
265
272
long atSibling = get (sibling (node ));
266
273
if (atNode == 0 && atSibling == 0 ) {
@@ -275,8 +282,8 @@ private void compressDownward(long seedNode) {
275
282
node2count .remove (sibling (node ));
276
283
// Now P2 could have vanished at the node's and sibling's subtrees since they decreased.
277
284
if (!isLeaf (node )) {
278
- q .enqueue (leftChild (node ));
279
- q .enqueue (leftChild (sibling (node )));
285
+ q .addLast (leftChild (node ));
286
+ q .addLast (leftChild (sibling (node )));
280
287
}
281
288
}
282
289
}
@@ -303,7 +310,8 @@ public boolean isEmpty() {
303
310
304
311
public List <long []> toAscRanges () {
305
312
List <long []> ranges = new ArrayList <long []>();
306
- for (long key : node2count .keySet ()) {
313
+ for (LongLongCursor cursor : node2count ) {
314
+ final long key = cursor .key ;
307
315
ranges .add (new long []{rangeLeft (key ), rangeRight (key ), node2count .get (key )});
308
316
}
309
317
@@ -323,7 +331,8 @@ public static void write(QDigestState state, StreamOutput out) throws IOExceptio
323
331
out .writeLong (state .size );
324
332
out .writeLong (state .capacity );
325
333
out .writeInt (state .node2count .size ());
326
- for (long k : state .node2count .keySet ()) {
334
+ for (LongLongCursor cursor : state .node2count ) {
335
+ final long k = cursor .key ;
327
336
out .writeVLong (k );
328
337
out .writeVLong (state .node2count .get (k ));
329
338
}
@@ -334,7 +343,7 @@ public static QDigestState read(StreamInput in) throws IOException {
334
343
state .size = in .readLong ();
335
344
state .capacity = in .readLong ();
336
345
int count = in .readInt ();
337
- state .node2count = new Long2LongOpenHashMap (count , MAP_LOAD_FACTOR );
346
+ state .node2count = new LongLongOpenHashMap (count , MAP_LOAD_FACTOR );
338
347
for (int i = 0 ; i < count ; ++i ) {
339
348
long k = in .readVLong ();
340
349
long n = in .readVLong ();
0 commit comments