Skip to content

Commit 541e953

Browse files
committed
improve iterator
1 parent d22ae66 commit 541e953

File tree

2 files changed

+27
-30
lines changed

2 files changed

+27
-30
lines changed

server/src/main/java/org/elasticsearch/lucene/queries/TimestampIterator.java

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
package org.elasticsearch.lucene.queries;
1010

1111
import org.apache.lucene.index.DocValuesSkipper;
12+
import org.apache.lucene.index.NumericDocValues;
1213
import org.apache.lucene.search.DocIdSetIterator;
1314
import org.apache.lucene.search.TwoPhaseIterator;
1415

@@ -20,18 +21,23 @@
2021
final class TimestampIterator extends TwoPhaseIterator {
2122

2223
private final RangeNoGapsApproximation approximation;
23-
private final TwoPhaseIterator innerTwoPhase;
24+
private final NumericDocValues timestamps;
25+
26+
private final long minTimestamp;
27+
private final long maxTimestamp;
2428

2529
TimestampIterator(
26-
TwoPhaseIterator twoPhase,
30+
NumericDocValues timestamps,
2731
DocValuesSkipper timestampSkipper,
2832
DocValuesSkipper primaryFieldSkipper,
2933
long minTimestamp,
3034
long maxTimestamp
3135
) {
32-
super(new RangeNoGapsApproximation(twoPhase.approximation(), timestampSkipper, primaryFieldSkipper, minTimestamp, maxTimestamp));
36+
super(new RangeNoGapsApproximation(timestamps, timestampSkipper, primaryFieldSkipper, minTimestamp, maxTimestamp));
3337
this.approximation = (RangeNoGapsApproximation) approximation();
34-
this.innerTwoPhase = twoPhase;
38+
this.timestamps = timestamps;
39+
this.minTimestamp = minTimestamp;
40+
this.maxTimestamp = maxTimestamp;
3541
}
3642

3743
static final class RangeNoGapsApproximation extends DocIdSetIterator {
@@ -48,6 +54,7 @@ static final class RangeNoGapsApproximation extends DocIdSetIterator {
4854
// Track a decision for all doc IDs between the current doc ID and upTo inclusive.
4955
Match match = Match.MAYBE;
5056
int upTo = -1;
57+
int primaryFieldUpTo = -1;
5158

5259
RangeNoGapsApproximation(
5360
DocIdSetIterator innerApproximation,
@@ -78,13 +85,10 @@ public int advance(int target) throws IOException {
7885
while (true) {
7986
if (target > upTo) {
8087
timestampSkipper.advance(target);
81-
// If target doesn't have a value and is between two blocks, it is possible that advance()
82-
// moved to a block that doesn't contain `target`.
83-
target = Math.max(target, timestampSkipper.minDocID(0));
84-
if (target == NO_MORE_DOCS) {
85-
return doc = NO_MORE_DOCS;
86-
}
8788
upTo = timestampSkipper.maxDocID(0);
89+
if (upTo == DocIdSetIterator.NO_MORE_DOCS) {
90+
return doc = DocIdSetIterator.NO_MORE_DOCS;
91+
}
8892
match = match(0);
8993

9094
// If we have a YES or NO decision, see if we still have the same decision on a higher
@@ -107,18 +111,17 @@ public int advance(int target) throws IOException {
107111
}
108112
break;
109113
case NO:
110-
if (match == Match.NO) {
114+
if (target > primaryFieldUpTo) {
111115
primaryFieldSkipper.advance(target);
112-
int betterUptTo = -1;
113116
for (int level = 0; level < primaryFieldSkipper.numLevels(); level++) {
114117
if (primaryFieldSkipper.minValue(level) == primaryFieldSkipper.maxValue(level)) {
115-
betterUptTo = primaryFieldSkipper.maxDocID(level);
118+
primaryFieldUpTo = primaryFieldSkipper.maxDocID(level);
116119
} else {
117120
break;
118121
}
119122
}
120-
if (betterUptTo > upTo) {
121-
upTo = betterUptTo;
123+
if (primaryFieldUpTo > upTo) {
124+
upTo = primaryFieldUpTo;
122125
}
123126
}
124127

@@ -156,7 +159,10 @@ Match match(int level) {
156159
public boolean matches() throws IOException {
157160
return switch (approximation.match) {
158161
case YES -> true;
159-
case MAYBE -> innerTwoPhase.matches();
162+
case MAYBE -> {
163+
final long value = timestamps.longValue();
164+
yield value >= minTimestamp && value <= maxTimestamp;
165+
}
160166
case NO -> throw new IllegalStateException("Unpositioned approximation");
161167
};
162168
}
@@ -171,7 +177,7 @@ public int docIDRunEnd() throws IOException {
171177

172178
@Override
173179
public float matchCost() {
174-
return innerTwoPhase.matchCost();
180+
return 2; // 2 comparisons
175181
}
176182

177183
enum Match {

server/src/main/java/org/elasticsearch/lucene/queries/TimestampQuery.java

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -91,21 +91,12 @@ public ScorerSupplier scorerSupplier(LeafReaderContext context) throws IOExcepti
9191
var iterator = getIteratorIfTimestampIfPrimarySort(maxDoc, timestamps, timestampSkipper, minTimestamp, maxTimestamp);
9292
return ConstantScoreScorerSupplier.fromIterator(iterator, score(), scoreMode, maxDoc);
9393
}
94-
TwoPhaseIterator iterator = new TwoPhaseIterator(timestamps) {
95-
@Override
96-
public boolean matches() throws IOException {
97-
final long value = timestamps.longValue();
98-
return value >= minTimestamp && value <= maxTimestamp;
99-
}
100-
101-
@Override
102-
public float matchCost() {
103-
return 2; // 2 comparisons
104-
}
105-
};
10694
var primaryFieldSkipper = reader.getDocValuesSkipper(primarySortField);
107-
iterator = new TimestampIterator(iterator, timestampSkipper, primaryFieldSkipper, minTimestamp, maxTimestamp);
95+
var iterator = new TimestampIterator(timestamps, timestampSkipper, primaryFieldSkipper, minTimestamp, maxTimestamp);
10896
return ConstantScoreScorerSupplier.fromIterator(TwoPhaseIterator.asDocIdSetIterator(iterator), score(), scoreMode, maxDoc);
97+
// var primaryFieldSkipper = reader.getDocValuesSkipper(primarySortField);
98+
// var iterator = new TimestampIterator2(timestamps, timestampSkipper, primaryFieldSkipper, minTimestamp, maxTimestamp);
99+
// return ConstantScoreScorerSupplier.fromIterator(iterator, score(), scoreMode, maxDoc);
109100
}
110101

111102
@Override

0 commit comments

Comments
 (0)