Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lucene/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,8 @@ Optimizations
* GITHUB#16370: Sort two-phase iterators by matchCost in DenseConjunctionBulkScorer.
(Alan Woodward)

* GITHUB#16180: Add bulk intoBitSet for SortedDocValues ordinal ranges. (Prithvi S)

Bug Fixes
---------------------
* GITHUB#16350: Disable bulk-scoring in monitor queries. (Alan Woodward)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1478,6 +1478,15 @@ public void intoBitSet(int upTo, FixedBitSet bitSet, int offset) throws IOExcept
advance(upTo);
}
}

@Override
public void ordinalRangeIntoBitSet(
int fromDoc, int toDoc, long minOrd, long maxOrd, FixedBitSet bitSet, int offset)
throws IOException {
// Dense packed ordinals: bulk evaluate via the same SIMD path as NumericDocValues
Lucene90DocValuesProducer.rangeIntoBitSet(
values, fromDoc, toDoc, minOrd, maxOrd, bitSet, offset);
}
};
} else if (ordsEntry.docsWithFieldOffset >= 0) { // sparse but non-empty
final IndexedDISI disi =
Expand Down Expand Up @@ -1576,6 +1585,15 @@ public int docIDRunEnd() throws IOException {
public void intoBitSet(int upTo, FixedBitSet bitSet, int offset) throws IOException {
ords.intoBitSet(upTo, bitSet, offset);
}

@Override
public void ordinalRangeIntoBitSet(
int fromDoc, int toDoc, long minOrd, long maxOrd, FixedBitSet bitSet, int offset)
throws IOException {
// Delegate to the underlying NumericDocValues which already has a (possibly SIMD)
// rangeIntoBitSet override.
ords.rangeIntoBitSet(fromDoc, toDoc, minOrd, maxOrd, bitSet, offset);
}
};
}

Expand Down
29 changes: 29 additions & 0 deletions lucene/core/src/java/org/apache/lucene/index/SortedDocValues.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.io.IOException;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.FixedBitSet;
import org.apache.lucene.util.automaton.CompiledAutomaton;

/**
Expand Down Expand Up @@ -95,6 +96,34 @@ public TermsEnum termsEnum() throws IOException {
return new SortedDocValuesTermsEnum(this);
}

/**
* Fills {@code bitSet} with the doc IDs in {@code [fromDoc, toDoc)} whose ordinals are in {@code
* [minOrd, maxOrd]}. This is a bulk operation that avoids per-doc virtual dispatch overhead.
*
* <p>The default implementation falls back to per-doc evaluation via {@link #advanceExact} and
* {@link #ordValue}. Subclasses with random-access storage (e.g., dense fixed-bitsPerValue
* fields) can override this for significantly better performance.
*
* @param fromDoc first doc ID to evaluate (inclusive)
* @param toDoc last doc ID to evaluate (exclusive)
* @param minOrd lower bound of the ordinal range (inclusive)
* @param maxOrd upper bound of the ordinal range (inclusive)
* @param bitSet the bitset to fill
* @param offset subtracted from each doc ID before setting the bit
*/
public void ordinalRangeIntoBitSet(
int fromDoc, int toDoc, long minOrd, long maxOrd, FixedBitSet bitSet, int offset)
throws IOException {
for (int d = fromDoc; d < toDoc; d++) {
if (advanceExact(d)) {
int ord = ordValue();
if (ord >= minOrd && ord <= maxOrd) {
bitSet.set(d - offset);
}
}
}
}

/**
* Returns a {@link TermsEnum} over the values, filtered by a {@link CompiledAutomaton} The enum
* supports {@link TermsEnum#ord()}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ public static DocValuesRangeIterator forOrdinalRange(
};
return skipper == null
? new DocValuesValueRangeIterator(values, check, 2)
: new BulkOrdinalRangeIterator(
values, new SkipBlockRangeIterator(skipper, min, max), check, 2);
: new BulkSortedRangeIterator(
values, new SkipBlockRangeIterator(skipper, min, max), check, 2, min, max);
}

/**
Expand Down Expand Up @@ -474,9 +474,43 @@ void intoMaybeBlock(int blockStart, int blockEnd, FixedBitSet bitSet, int offset
}

/**
* Bulk range iterator over ordinal (sorted / sorted-set) doc values. There is no columnar
* range-decode like the numeric path, so MAYBE blocks confirm the ordinal predicate one doc at a
* time, visiting only docs that have a value.
* Bulk range iterator over single-valued sorted (ordinal) doc values. Delegates MAYBE blocks to
* {@link SortedDocValues#ordinalRangeIntoBitSet} so that dense packed implementations can use
* direct (SIMD) range evaluation over the ordinal array.
*/
private static final class BulkSortedRangeIterator extends BulkBlockRangeIterator {

private final SortedDocValues sortedValues;
private final long minOrd;
private final long maxOrd;

private BulkSortedRangeIterator(
SortedDocValues values,
SkipBlockRangeIterator blockIterator,
IOBooleanSupplier predicate,
float matchCost,
long minOrd,
long maxOrd) {
super(values, blockIterator, predicate, matchCost);
this.sortedValues = values;
this.minOrd = minOrd;
this.maxOrd = maxOrd;
}

@Override
void intoMaybeBlock(int blockStart, int blockEnd, FixedBitSet bitSet, int offset)
throws IOException {
// sortedValues is the same instance as disi, so a preceding matches() call may have
// moved it beyond blockStart. Adjust the starting point.
int from = Math.max(blockStart, sortedValues.docID());
sortedValues.ordinalRangeIntoBitSet(from, blockEnd, minOrd, maxOrd, bitSet, offset);
}
}

/**
* Bulk range iterator over ordinal (sorted-set) doc values. There is no columnar range-decode
* like the numeric path, and for multi-valued we must check the predicate (which walks the
* per-doc ords), so MAYBE blocks confirm by visiting only docs that have a value.
*/
private static final class BulkOrdinalRangeIterator extends BulkBlockRangeIterator {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,12 @@ public int getValueCount() {

@Override
public boolean advanceExact(int target) {
throw new UnsupportedOperationException();
if (docHasValue(target)) {
doc = target;
return true;
}
doc = target;
return false;
}

@Override
Expand Down Expand Up @@ -349,7 +354,12 @@ public long getValueCount() {

@Override
public boolean advanceExact(int target) {
throw new UnsupportedOperationException();
if (docHasValue(target)) {
doc = target;
return true;
}
doc = target;
return false;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,12 @@ public int getValueCount() {

@Override
public boolean advanceExact(int target) {
throw new UnsupportedOperationException();
if (docHasValue(target)) {
doc = target;
return true;
}
doc = target;
return false;
}

@Override
Expand Down Expand Up @@ -500,7 +505,12 @@ public long getValueCount() {

@Override
public boolean advanceExact(int target) {
throw new UnsupportedOperationException();
if (docHasValue(target)) {
doc = target;
return true;
}
doc = target;
return false;
}

@Override
Expand Down
Loading
Loading