Skip to content

Commit d2cf578

Browse files
committed
iter
1 parent 5f83743 commit d2cf578

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

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

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@
1717

1818
/**
1919
* Based on {@link org.apache.lucene.search.DocValuesRangeIterator} but modified for time series and logsdb use cases.
20+
* <p>
21+
* The @timestamp field always has exactly one value and all documents always have a @timestamp value.
22+
* Additionally, the @timestamp field is always the secondary index sort field and sort order is always descending.
23+
* <p>
24+
* This makes the doc value skipper on @timestamp field less effective, and so the doc value skipper for the first index sort field is
25+
* also used to skip to the next primary sort value if for the current skipper represents one value (min and max value are the same) and
26+
* the current value is lower than minTimestamp.
2027
*/
2128
final class TimestampIterator extends TwoPhaseIterator {
2229

@@ -110,7 +117,7 @@ public int advance(int target) throws IOException {
110117
return doc = target;
111118
}
112119
break;
113-
case NO:
120+
case NO_AND_SKIP:
114121
if (target > primaryFieldUpTo) {
115122
primaryFieldSkipper.advance(target);
116123
for (int level = 0; level < primaryFieldSkipper.numLevels(); level++) {
@@ -124,7 +131,12 @@ public int advance(int target) throws IOException {
124131
upTo = primaryFieldUpTo;
125132
}
126133
}
127-
134+
if (upTo == DocIdSetIterator.NO_MORE_DOCS) {
135+
return doc = NO_MORE_DOCS;
136+
}
137+
target = upTo + 1;
138+
break;
139+
case NO:
128140
if (upTo == DocIdSetIterator.NO_MORE_DOCS) {
129141
return doc = NO_MORE_DOCS;
130142
}
@@ -144,8 +156,10 @@ public long cost() {
144156
Match match(int level) {
145157
long minValue = timestampSkipper.minValue(level);
146158
long maxValue = timestampSkipper.maxValue(level);
147-
if (minValue > maxTimestamp || maxValue < minTimestamp) {
159+
if (minValue > maxTimestamp) {
148160
return Match.NO;
161+
} else if (maxValue < minTimestamp) {
162+
return Match.NO_AND_SKIP;
149163
} else if (minValue >= minTimestamp && maxValue <= maxTimestamp) {
150164
return Match.YES;
151165
} else {
@@ -163,7 +177,7 @@ public boolean matches() throws IOException {
163177
final long value = timestamps.longValue();
164178
yield value >= minTimestamp && value <= maxTimestamp;
165179
}
166-
case NO -> throw new IllegalStateException("Unpositioned approximation");
180+
case NO_AND_SKIP, NO -> throw new IllegalStateException("Unpositioned approximation");
167181
};
168182
}
169183

@@ -183,6 +197,8 @@ public float matchCost() {
183197
enum Match {
184198
/** None of the documents in the range match */
185199
NO,
200+
/** Same as NO, but can maybe also skip to next primary sort value */
201+
NO_AND_SKIP,
186202
/** Document values need to be checked to verify matches */
187203
MAYBE,
188204
/** All docs in the range match */

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import org.apache.lucene.search.ScoreMode;
2525
import org.apache.lucene.search.ScorerSupplier;
2626
import org.apache.lucene.search.Sort;
27-
import org.apache.lucene.search.TwoPhaseIterator;
2827
import org.apache.lucene.search.Weight;
2928
import org.elasticsearch.cluster.metadata.DataStream;
3029

@@ -92,10 +91,11 @@ public ScorerSupplier scorerSupplier(LeafReaderContext context) throws IOExcepti
9291
return ConstantScoreScorerSupplier.fromIterator(iterator, score(), scoreMode, maxDoc);
9392
}
9493
var primaryFieldSkipper = reader.getDocValuesSkipper(primarySortField);
95-
var iterator = new TimestampIterator(timestamps, timestampSkipper, primaryFieldSkipper, minTimestamp, maxTimestamp);
96-
return ConstantScoreScorerSupplier.fromIterator(TwoPhaseIterator.asDocIdSetIterator(iterator), score(), scoreMode, maxDoc);
97-
// var iterator = new TimestampIterator2(timestamps, timestampSkipper, primaryFieldSkipper, minTimestamp, maxTimestamp);
98-
// return ConstantScoreScorerSupplier.fromIterator(iterator, score(), scoreMode, maxDoc);
94+
// var iterator = new TimestampIterator(timestamps, timestampSkipper, primaryFieldSkipper, minTimestamp, maxTimestamp);
95+
// return ConstantScoreScorerSupplier.fromIterator(TwoPhaseIterator.asDocIdSetIterator(iterator), score(), scoreMode,
96+
// maxDoc);
97+
var iterator = new TimestampIterator2(timestamps, timestampSkipper, primaryFieldSkipper, minTimestamp, maxTimestamp);
98+
return ConstantScoreScorerSupplier.fromIterator(iterator, score(), scoreMode, maxDoc);
9999
}
100100

101101
@Override

0 commit comments

Comments
 (0)