@@ -162,10 +162,6 @@ public void grow(int count) {
162
162
@ Override
163
163
public void visit (int docID ) {
164
164
// it is possible that size < 1024 and docCount < size but we will continue to count through all the 1024 docs
165
- // and collect less, but it won't hurt performance
166
- if (docCount [0 ] >= size ) {
167
- return ;
168
- }
169
165
adder .add (docID );
170
166
docCount [0 ]++;
171
167
}
@@ -177,9 +173,8 @@ public void visit(DocIdSetIterator iterator) throws IOException {
177
173
178
174
@ Override
179
175
public void visit (IntsRef ref ) {
180
- for (int i = 0 ; i < ref .length ; i ++) {
181
- adder .add (ref .ints [ref .offset + i ]);
182
- }
176
+ adder .add (ref );
177
+ docCount [0 ] += ref .length ;
183
178
}
184
179
185
180
@ Override
@@ -248,10 +243,10 @@ private void intersectRight(PointValues.PointTree pointTree, PointValues.Interse
248
243
// custom intersect visitor to walk the left of the tree
249
244
public void intersectLeft (PointValues .IntersectVisitor visitor , PointValues .PointTree pointTree , long [] docCount )
250
245
throws IOException {
251
- PointValues .Relation r = visitor .compare (pointTree .getMinPackedValue (), pointTree .getMaxPackedValue ());
252
246
if (docCount [0 ] >= size ) {
253
247
return ;
254
248
}
249
+ PointValues .Relation r = visitor .compare (pointTree .getMinPackedValue (), pointTree .getMaxPackedValue ());
255
250
switch (r ) {
256
251
case CELL_OUTSIDE_QUERY :
257
252
// This cell is fully outside the query shape: stop recursing
@@ -293,65 +288,49 @@ public void intersectLeft(PointValues.IntersectVisitor visitor, PointValues.Poin
293
288
}
294
289
}
295
290
296
- // custom intersect visitor to walk the right of tree
291
+ // custom intersect visitor to walk the right of tree (from rightmost leaf going left)
297
292
public void intersectRight (PointValues .IntersectVisitor visitor , PointValues .PointTree pointTree , long [] docCount )
298
293
throws IOException {
299
- PointValues .Relation r = visitor .compare (pointTree .getMinPackedValue (), pointTree .getMaxPackedValue ());
300
294
if (docCount [0 ] >= size ) {
301
295
return ;
302
296
}
297
+ PointValues .Relation r = visitor .compare (pointTree .getMinPackedValue (), pointTree .getMaxPackedValue ());
303
298
switch (r ) {
304
- case CELL_OUTSIDE_QUERY :
305
- // This cell is fully outside the query shape: stop recursing
306
- break ;
307
-
308
299
case CELL_INSIDE_QUERY :
309
- // If the cell is fully inside, we keep moving right as long as the point tree size is over our size requirement
310
- if (pointTree .size () > size && docCount [0 ] < size && moveRight (pointTree )) {
311
- intersectRight (visitor , pointTree , docCount );
312
- pointTree .moveToParent ();
313
- }
314
- // if point tree size is no longer over, we have to go back one level where it still was over and the intersect left
315
- else if (pointTree .size () <= size && docCount [0 ] < size ) {
316
- pointTree .moveToParent ();
317
- intersectLeft (visitor , pointTree , docCount );
318
- }
319
- // if we've reached leaf, it means out size is under the size of the leaf, we can just collect all docIDs
320
- else {
321
- // Leaf node; scan and filter all points in this block:
322
- if (docCount [0 ] < size ) {
323
- pointTree .visitDocIDs (visitor );
324
- }
325
- }
326
- break ;
327
300
case CELL_CROSSES_QUERY :
328
- // If the cell is fully inside, we keep moving right as long as the point tree size is over our size requirement
329
- if (pointTree .size () > size && docCount [0 ] < size && moveRight (pointTree )) {
330
- intersectRight (visitor , pointTree , docCount );
331
- pointTree .moveToParent ();
332
- }
333
- // if point tree size is no longer over, we have to go back one level where it still was over and the intersect left
334
- else if (pointTree .size () <= size && docCount [0 ] < size ) {
301
+ if (pointTree .moveToChild () && docCount [0 ] < size ) {
302
+ PointValues .PointTree leftChild = pointTree .clone ();
303
+ // BKD is binary today, so one moveToSibling() is enough to land on the right child.
304
+ // If PointTree ever becomes n-ary, update the traversal below to visit all siblings or re-enable a full loop.
305
+ if (pointTree .moveToSibling ()) {
306
+ // We have two children - visit right first
307
+ intersectRight (visitor , pointTree , docCount );
308
+ // Then visit left if we still need more docs
309
+ if (docCount [0 ] < size ) {
310
+ intersectRight (visitor , leftChild , docCount );
311
+ }
312
+ } else {
313
+ // Only one child - visit it
314
+ intersectRight (visitor , leftChild , docCount );
315
+ }
335
316
pointTree .moveToParent ();
336
- intersectLeft (visitor , pointTree , docCount );
337
- }
338
- // if we've reached leaf, it means out size is under the size of the leaf, we can just collect all doc values
339
- else {
340
- // Leaf node; scan and filter all points in this block:
317
+ } else {
341
318
if (docCount [0 ] < size ) {
342
- pointTree .visitDocValues (visitor );
319
+ if (r == PointValues .Relation .CELL_INSIDE_QUERY ) {
320
+ pointTree .visitDocIDs (visitor );
321
+ } else {
322
+ pointTree .visitDocValues (visitor );
323
+ }
343
324
}
344
325
}
345
326
break ;
327
+ case CELL_OUTSIDE_QUERY :
328
+ break ;
346
329
default :
347
330
throw new IllegalArgumentException ("Unreachable code" );
348
331
}
349
332
}
350
333
351
- public boolean moveRight (PointValues .PointTree pointTree ) throws IOException {
352
- return pointTree .moveToChild () && pointTree .moveToSibling ();
353
- }
354
-
355
334
@ Override
356
335
public ScorerSupplier scorerSupplier (LeafReaderContext context ) throws IOException {
357
336
LeafReader reader = context .reader ();
0 commit comments