Skip to content

Commit 38c1036

Browse files
authored
Delegate rangeIntoBitSet in SingletonSortedNumericDocValues (#16295)
SingletonSortedNumericDocValues did not override rangeIntoBitSet, causing single-valued sorted numeric fields queried via SortedNumericDocValuesField.newSlowRangeQuery to fall back to per-doc scalar evaluation even when the underlying NumericDocValues has an optimized override.
1 parent ffb86f9 commit 38c1036

3 files changed

Lines changed: 70 additions & 1 deletion

File tree

lucene/CHANGES.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,10 @@ Optimizations
325325

326326
Bug Fixes
327327
---------------------
328-
(No changes)
328+
329+
* GITHUB#16295: SingletonSortedNumericDocValues now delegates rangeIntoBitSet
330+
to the wrapped NumericDocValues, enabling optimized range evaluation for
331+
single-valued sorted numeric fields. (Costin Leau)
329332

330333
Other
331334
---------------------

lucene/core/src/java/org/apache/lucene/index/SingletonSortedNumericDocValues.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ public int docIDRunEnd() throws IOException {
7373
return in.docIDRunEnd();
7474
}
7575

76+
@Override
77+
public void rangeIntoBitSet(
78+
int fromDoc, int toDoc, long minValue, long maxValue, FixedBitSet bitSet, int offset)
79+
throws IOException {
80+
in.rangeIntoBitSet(fromDoc, toDoc, minValue, maxValue, bitSet, offset);
81+
}
82+
7683
@Override
7784
public long cost() {
7885
return in.cost();

lucene/core/src/test/org/apache/lucene/search/TestSkipBlockRangeIteratorIntoBitSet.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717
package org.apache.lucene.search;
1818

19+
import java.io.IOException;
1920
import java.util.ArrayList;
2021
import java.util.List;
2122
import java.util.Random;
@@ -25,11 +26,13 @@
2526
import org.apache.lucene.document.NumericDocValuesField;
2627
import org.apache.lucene.document.SortedNumericDocValuesField;
2728
import org.apache.lucene.index.DirectoryReader;
29+
import org.apache.lucene.index.DocValues;
2830
import org.apache.lucene.index.DocValuesSkipper;
2931
import org.apache.lucene.index.IndexWriter;
3032
import org.apache.lucene.index.IndexWriterConfig;
3133
import org.apache.lucene.index.LeafReaderContext;
3234
import org.apache.lucene.index.NumericDocValues;
35+
import org.apache.lucene.index.SortedNumericDocValues;
3336
import org.apache.lucene.search.BooleanClause.Occur;
3437
import org.apache.lucene.store.Directory;
3538
import org.apache.lucene.util.FixedBitSet;
@@ -818,6 +821,62 @@ private void doTestSortedNumericRangeIntoBitSet(
818821
}
819822
}
820823

824+
public void testSingletonDelegatesRangeIntoBitSet() throws Exception {
825+
int maxDoc = 100;
826+
boolean[] delegated = {false};
827+
NumericDocValues spy =
828+
new NumericDocValues() {
829+
private int doc = -1;
830+
831+
@Override
832+
public long longValue() {
833+
return doc;
834+
}
835+
836+
@Override
837+
public boolean advanceExact(int target) {
838+
doc = target;
839+
return true;
840+
}
841+
842+
@Override
843+
public int docID() {
844+
return doc;
845+
}
846+
847+
@Override
848+
public int nextDoc() {
849+
return ++doc < maxDoc ? doc : NO_MORE_DOCS;
850+
}
851+
852+
@Override
853+
public int advance(int target) {
854+
doc = target;
855+
return doc < maxDoc ? doc : NO_MORE_DOCS;
856+
}
857+
858+
@Override
859+
public long cost() {
860+
return maxDoc;
861+
}
862+
863+
@Override
864+
public void rangeIntoBitSet(
865+
int fromDoc, int toDoc, long minValue, long maxValue, FixedBitSet bitSet, int offset)
866+
throws IOException {
867+
delegated[0] = true;
868+
super.rangeIntoBitSet(fromDoc, toDoc, minValue, maxValue, bitSet, offset);
869+
}
870+
};
871+
872+
SortedNumericDocValues singleton = DocValues.singleton(spy);
873+
FixedBitSet bitSet = new FixedBitSet(maxDoc);
874+
singleton.rangeIntoBitSet(0, maxDoc, 20, 40, bitSet, 0);
875+
876+
assertTrue("Expected delegation to NumericDocValues.rangeIntoBitSet", delegated[0]);
877+
assertTrue("Expected some bits set", bitSet.cardinality() > 0);
878+
}
879+
821880
private static long[] rangeValues(int numDocs, LongUnaryOperator valueFunction) {
822881
long[] values = new long[numDocs];
823882
for (int i = 0; i < numDocs; i++) {

0 commit comments

Comments
 (0)