Skip to content

Commit e4b85ca

Browse files
authored
Implement IntersectVisitor#visit(IntsRef) whenever it makes sense (#14138)
Implement IntersectVisitor#visit(IntsRef) in many of the current implementations and add BulkAdder#add(IntsRef) method. They should provide better performance due to less virtual method calls and more efficient bulk processing.
1 parent 16cd779 commit e4b85ca

File tree

11 files changed

+154
-31
lines changed

11 files changed

+154
-31
lines changed

lucene/CHANGES.txt

+4
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ Improvements
6161

6262
* GITHUB#14113: Remove unnecessary ByteArrayDataInput allocations from `Lucene90DocValuesProducer$TermsDict.decompressBlock`. (Ankit Jain)
6363

64+
* GITHUB#14138: Implement IntersectVisitor#visit(IntsRef) in many of the current implementations and add
65+
BulkAdder#add(IntsRef) method. They should provide better performance due to less virtual method calls and
66+
more efficient bulk processing. (Ignacio Vera)
67+
6468
Optimizations
6569
---------------------
6670

lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java

+14
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import org.apache.lucene.util.BitSetIterator;
4545
import org.apache.lucene.util.DocIdSetBuilder;
4646
import org.apache.lucene.util.FixedBitSet;
47+
import org.apache.lucene.util.IntsRef;
4748
import org.apache.lucene.util.NumericUtils;
4849

4950
/** Distance query for {@link LatLonPoint}. */
@@ -233,6 +234,11 @@ public void visit(int docID) {
233234
adder.add(docID);
234235
}
235236

237+
@Override
238+
public void visit(IntsRef ref) {
239+
adder.add(ref);
240+
}
241+
236242
@Override
237243
public void visit(DocIdSetIterator iterator) throws IOException {
238244
adder.add(iterator);
@@ -269,6 +275,14 @@ public void visit(int docID) {
269275
cost[0]--;
270276
}
271277

278+
@Override
279+
public void visit(IntsRef ref) {
280+
for (int i = 0; i < ref.length; i++) {
281+
result.clear(ref.ints[ref.offset + i]);
282+
}
283+
cost[0] = -ref.length;
284+
}
285+
272286
@Override
273287
public void visit(DocIdSetIterator iterator) throws IOException {
274288
result.andNot(iterator);

lucene/core/src/java/org/apache/lucene/document/LongDistanceFeatureQuery.java

+16
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.apache.lucene.search.ScorerSupplier;
3636
import org.apache.lucene.search.Weight;
3737
import org.apache.lucene.util.DocIdSetBuilder;
38+
import org.apache.lucene.util.IntsRef;
3839
import org.apache.lucene.util.NumericUtils;
3940

4041
final class LongDistanceFeatureQuery extends Query {
@@ -405,6 +406,21 @@ public void visit(int docID, byte[] packedValue) {
405406
adder.add(docID);
406407
}
407408

409+
@Override
410+
public void visit(DocIdSetIterator iterator) throws IOException {
411+
int docID;
412+
while ((docID = iterator.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
413+
visit(docID);
414+
}
415+
}
416+
417+
@Override
418+
public void visit(IntsRef ref) {
419+
for (int i = 0; i < ref.length; ++i) {
420+
visit(ref.ints[ref.offset + i]);
421+
}
422+
}
423+
408424
@Override
409425
public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
410426
long minDocValue = NumericUtils.sortableBytesToLong(minPackedValue, 0);

lucene/core/src/java/org/apache/lucene/document/RangeFieldQuery.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.apache.lucene.util.ArrayUtil;
3939
import org.apache.lucene.util.ArrayUtil.ByteArrayComparator;
4040
import org.apache.lucene.util.DocIdSetBuilder;
41+
import org.apache.lucene.util.IntsRef;
4142

4243
/**
4344
* Query class for searching {@code RangeField} types by a defined {@link Relation}.
@@ -401,7 +402,12 @@ public void grow(int count) {
401402
}
402403

403404
@Override
404-
public void visit(int docID) throws IOException {
405+
public void visit(IntsRef ref) {
406+
adder.add(ref);
407+
}
408+
409+
@Override
410+
public void visit(int docID) {
405411
adder.add(docID);
406412
}
407413

@@ -411,7 +417,7 @@ public void visit(DocIdSetIterator iterator) throws IOException {
411417
}
412418

413419
@Override
414-
public void visit(int docID, byte[] leaf) throws IOException {
420+
public void visit(int docID, byte[] leaf) {
415421
if (queryType.matches(ranges, leaf, numDims, bytesPerDim, comparator)) {
416422
visit(docID);
417423
}

lucene/core/src/java/org/apache/lucene/document/SpatialQuery.java

+44
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import org.apache.lucene.util.BitSetIterator;
5050
import org.apache.lucene.util.DocIdSetBuilder;
5151
import org.apache.lucene.util.FixedBitSet;
52+
import org.apache.lucene.util.IntsRef;
5253

5354
/**
5455
* Base query class for all spatial geometries: {@link LatLonShape}, {@link LatLonPoint} and {@link
@@ -445,6 +446,11 @@ public void visit(DocIdSetIterator iterator) throws IOException {
445446
adder.add(iterator);
446447
}
447448

449+
@Override
450+
public void visit(IntsRef ref) {
451+
adder.add(ref);
452+
}
453+
448454
@Override
449455
public void visit(int docID, byte[] t) {
450456
if (leafPredicate.test(t)) {
@@ -489,6 +495,14 @@ public void visit(DocIdSetIterator iterator) throws IOException {
489495
cost[0] += iterator.cost();
490496
}
491497

498+
@Override
499+
public void visit(IntsRef ref) {
500+
for (int i = 0; i < ref.length; i++) {
501+
result.set(ref.ints[ref.offset + i]);
502+
}
503+
cost[0] += ref.length;
504+
}
505+
492506
@Override
493507
public void visit(int docID, byte[] t) {
494508
if (result.get(docID) == false) {
@@ -532,6 +546,14 @@ public void visit(int docID) {
532546
cost[0]++;
533547
}
534548

549+
@Override
550+
public void visit(IntsRef ref) {
551+
for (int i = 0; i < ref.length; i++) {
552+
result.set(ref.ints[ref.offset + i]);
553+
}
554+
cost[0] += ref.length;
555+
}
556+
535557
@Override
536558
public void visit(DocIdSetIterator iterator) throws IOException {
537559
result.or(iterator);
@@ -589,6 +611,13 @@ public void visit(DocIdSetIterator iterator) throws IOException {
589611
excluded.or(iterator);
590612
}
591613

614+
@Override
615+
public void visit(IntsRef ref) {
616+
for (int i = 0; i < ref.length; i++) {
617+
visit(ref.ints[ref.offset + i]);
618+
}
619+
}
620+
592621
@Override
593622
public void visit(int docID, byte[] t) {
594623
if (excluded.get(docID) == false) {
@@ -643,6 +672,14 @@ public void visit(int docID) {
643672
cost[0]--;
644673
}
645674

675+
@Override
676+
public void visit(IntsRef ref) {
677+
for (int i = 0; i < ref.length; i++) {
678+
result.clear(ref.ints[ref.offset + i]);
679+
}
680+
cost[0] -= ref.length;
681+
}
682+
646683
@Override
647684
public void visit(DocIdSetIterator iterator) throws IOException {
648685
result.andNot(iterator);
@@ -693,6 +730,13 @@ public void visit(DocIdSetIterator iterator) throws IOException {
693730
result.andNot(iterator);
694731
}
695732

733+
@Override
734+
public void visit(IntsRef ref) {
735+
for (int i = 0; i < ref.length; i++) {
736+
visit(ref.ints[ref.offset + i]);
737+
}
738+
}
739+
696740
@Override
697741
public void visit(int docID, byte[] packedTriangle) {
698742
// NO-OP

lucene/core/src/java/org/apache/lucene/document/XYPointInGeometryQuery.java

+6
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.apache.lucene.search.ScorerSupplier;
3939
import org.apache.lucene.search.Weight;
4040
import org.apache.lucene.util.DocIdSetBuilder;
41+
import org.apache.lucene.util.IntsRef;
4142

4243
/**
4344
* Finds all previously indexed points that fall within the specified XY geometries.
@@ -90,6 +91,11 @@ public void visit(DocIdSetIterator iterator) throws IOException {
9091
adder.add(iterator);
9192
}
9293

94+
@Override
95+
public void visit(IntsRef ref) {
96+
adder.add(ref);
97+
}
98+
9399
@Override
94100
public void visit(int docID, byte[] packedValue) {
95101
double x = XYEncodingUtils.decode(packedValue, 0);

lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,7 @@ public void visit(DocIdSetIterator iterator) throws IOException {
188188

189189
@Override
190190
public void visit(IntsRef ref) {
191-
for (int i = ref.offset; i < ref.offset + ref.length; i++) {
192-
adder.add(ref.ints[i]);
193-
}
191+
adder.add(ref);
194192
}
195193

196194
@Override

lucene/core/src/java/org/apache/lucene/util/DocIdSetBuilder.java

+28-20
Original file line numberDiff line numberDiff line change
@@ -41,29 +41,28 @@ public final class DocIdSetBuilder {
4141
*
4242
* @see DocIdSetBuilder#grow
4343
*/
44-
public abstract static class BulkAdder {
45-
public abstract void add(int doc);
44+
public sealed interface BulkAdder permits FixedBitSetAdder, BufferAdder {
45+
void add(int doc);
4646

47-
public void add(DocIdSetIterator iterator) throws IOException {
48-
int docID;
49-
while ((docID = iterator.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
50-
add(docID);
51-
}
52-
}
53-
}
47+
void add(IntsRef docs);
5448

55-
private static class FixedBitSetAdder extends BulkAdder {
56-
final FixedBitSet bitSet;
49+
void add(DocIdSetIterator iterator) throws IOException;
50+
}
5751

58-
FixedBitSetAdder(FixedBitSet bitSet) {
59-
this.bitSet = bitSet;
60-
}
52+
private record FixedBitSetAdder(FixedBitSet bitSet) implements BulkAdder {
6153

6254
@Override
6355
public void add(int doc) {
6456
bitSet.set(doc);
6557
}
6658

59+
@Override
60+
public void add(IntsRef docs) {
61+
for (int i = 0; i < docs.length; i++) {
62+
bitSet.set(docs.ints[docs.offset + i]);
63+
}
64+
}
65+
6766
@Override
6867
public void add(DocIdSetIterator iterator) throws IOException {
6968
bitSet.or(iterator);
@@ -85,17 +84,26 @@ private static class Buffer {
8584
}
8685
}
8786

88-
private static class BufferAdder extends BulkAdder {
89-
final Buffer buffer;
90-
91-
BufferAdder(Buffer buffer) {
92-
this.buffer = buffer;
93-
}
87+
private record BufferAdder(Buffer buffer) implements BulkAdder {
9488

9589
@Override
9690
public void add(int doc) {
9791
buffer.array[buffer.length++] = doc;
9892
}
93+
94+
@Override
95+
public void add(IntsRef docs) {
96+
System.arraycopy(docs.ints, docs.offset, buffer.array, buffer.length, docs.length);
97+
buffer.length += docs.length;
98+
}
99+
100+
@Override
101+
public void add(DocIdSetIterator iterator) throws IOException {
102+
int docID;
103+
while ((docID = iterator.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
104+
add(docID);
105+
}
106+
}
99107
}
100108

101109
private final int maxDoc;

lucene/core/src/java/org/apache/lucene/util/bkd/BKDReader.java

+14
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.lucene.store.IndexInput;
2525
import org.apache.lucene.util.ArrayUtil;
2626
import org.apache.lucene.util.BytesRef;
27+
import org.apache.lucene.util.IntsRef;
2728
import org.apache.lucene.util.MathUtil;
2829

2930
/**
@@ -146,6 +147,19 @@ public void visit(int docID) {
146147
count[0]++;
147148
}
148149

150+
@Override
151+
public void visit(DocIdSetIterator iterator) throws IOException {
152+
int docID;
153+
while ((docID = iterator.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
154+
visit(docID);
155+
}
156+
}
157+
158+
@Override
159+
public void visit(IntsRef ref) {
160+
count[0] += ref.length;
161+
}
162+
149163
@Override
150164
public void visit(int docID, byte[] packedValue) {
151165
throw new AssertionError();

lucene/core/src/test/org/apache/lucene/util/TestDocIdSetBuilder.java

+13-6
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,20 @@ public void testRandom() throws IOException {
130130
for (j = 0; j < array.length; ) {
131131
final int l = TestUtil.nextInt(random(), 1, array.length - j);
132132
DocIdSetBuilder.BulkAdder adder = null;
133-
for (int k = 0, budget = 0; k < l; ++k) {
134-
if (budget == 0 || rarely()) {
135-
budget = TestUtil.nextInt(random(), 1, l - k + 5);
136-
adder = builder.grow(budget);
133+
if (usually()) {
134+
for (int k = 0, budget = 0; k < l; ++k) {
135+
if (budget == 0 || rarely()) {
136+
budget = TestUtil.nextInt(random(), 1, l - k + 5);
137+
adder = builder.grow(budget);
138+
}
139+
adder.add(array[j++]);
140+
budget--;
137141
}
138-
adder.add(array[j++]);
139-
budget--;
142+
} else {
143+
IntsRef intsRef = new IntsRef(array, j, l);
144+
adder = builder.grow(l);
145+
adder.add(intsRef);
146+
j += l;
140147
}
141148
}
142149

lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInShapeIntersectVisitor.java

+6
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.apache.lucene.spatial3d.geom.PlanetModel.DocValueEncoder;
2828
import org.apache.lucene.spatial3d.geom.XYZBounds;
2929
import org.apache.lucene.util.DocIdSetBuilder;
30+
import org.apache.lucene.util.IntsRef;
3031
import org.apache.lucene.util.NumericUtils;
3132

3233
class PointInShapeIntersectVisitor implements IntersectVisitor {
@@ -67,6 +68,11 @@ public void visit(DocIdSetIterator iterator) throws IOException {
6768
adder.add(iterator);
6869
}
6970

71+
@Override
72+
public void visit(IntsRef ref) throws IOException {
73+
adder.add(ref);
74+
}
75+
7076
@Override
7177
public void visit(int docID, byte[] packedValue) {
7278
assert packedValue.length == 12;

0 commit comments

Comments
 (0)