@@ -373,6 +373,25 @@ private int findFirstDocWithTsIdOrdinalEqualTo(int tsIdOrd) throws IOException {
373373 return DocIdSetIterator .NO_MORE_DOCS ;
374374 }
375375
376+ /**
377+ * Skip as many documents as possible after a given document ID to find the first document ID matching the timestamp.
378+ *
379+ * @param timestamp the timestamp to match
380+ * @param minDocID the min. document ID
381+ * @return a docID to start scanning documents from in order to find the first document ID matching the provided timestamp
382+ * @throws IOException if any I/O exception occurs
383+ */
384+ private int skipDocIDForTimestamp (long timestamp , int minDocID ) throws IOException {
385+ var skipper = docValuesProducer .getSkipper (timestampFieldInfo );
386+ assert skipper != null ;
387+ if (skipper .minValue () > timestamp || timestamp > skipper .maxValue ()) {
388+ return DocIdSetIterator .NO_MORE_DOCS ;
389+ }
390+ skipper .advance (minDocID );
391+ skipper .advance (timestamp , Long .MAX_VALUE );
392+ return Math .max (minDocID , skipper .minDocID (0 ));
393+ }
394+
376395 private int getTsIdValueCount () throws IOException {
377396 if (tsIdDocValues == null ) {
378397 tsIdDocValues = docValuesProducer .getSorted (tsIdFieldInfo );
@@ -483,32 +502,37 @@ public SeekStatus seekCeil(BytesRef id) throws IOException {
483502 return SeekStatus .END ;
484503 }
485504
486- // _tsid found, extract the timestamp
487- final long timestamp = TsidExtractingIdFieldMapper .extractTimestampFromSyntheticId (id );
488-
489- // Find the first document matching the _tsid
490- final int startDocID = docValues .findFirstDocWithTsIdOrdinalEqualTo (tsIdOrd );
505+ // Find the first document ID matching the _tsid
506+ int startDocID = docValues .findFirstDocWithTsIdOrdinalEqualTo (tsIdOrd );
491507 assert startDocID >= 0 : startDocID ;
492508
493- int docID = startDocID ;
494- int docTsIdOrd = tsIdOrd ;
495- long docTimestamp ;
496-
497- // Iterate over documents to find the first one matching the timestamp
498- for (; docID < maxDocs ; docID ++) {
499- docTimestamp = docValues .docTimestamp (docID );
500- if (startDocID < docID ) {
501- // After the first doc, we need to check again if _tsid matches
502- docTsIdOrd = docValues .docTsIdOrdinal (docID );
503- }
504- if (docTsIdOrd == tsIdOrd && docTimestamp == timestamp ) {
505- // It's a match!
506- current = new SyntheticTerm (docID , tsIdOrd , tsId , docTimestamp , docValues .docRoutingHash (docID ));
507- return SeekStatus .FOUND ;
508- }
509- // Remaining docs don't match, stop here
510- if (tsIdOrd < docTsIdOrd || docTimestamp < timestamp ) {
511- break ;
509+ if (startDocID != DocIdSetIterator .NO_MORE_DOCS ) {
510+ // _tsid found, extract the timestamp
511+ final long timestamp = TsidExtractingIdFieldMapper .extractTimestampFromSyntheticId (id );
512+
513+ startDocID = docValues .skipDocIDForTimestamp (timestamp , startDocID );
514+ if (startDocID != DocIdSetIterator .NO_MORE_DOCS ) {
515+ int docID = startDocID ;
516+ int docTsIdOrd = tsIdOrd ;
517+ long docTimestamp ;
518+
519+ // Iterate over documents to find the first one matching the timestamp
520+ for (; docID < maxDocs ; docID ++) {
521+ docTimestamp = docValues .docTimestamp (docID );
522+ if (startDocID < docID ) {
523+ // After the first doc, we need to check again if _tsid matches
524+ docTsIdOrd = docValues .docTsIdOrdinal (docID );
525+ }
526+ if (docTsIdOrd == tsIdOrd && docTimestamp == timestamp ) {
527+ // It's a match!
528+ current = new SyntheticTerm (docID , tsIdOrd , tsId , docTimestamp , docValues .docRoutingHash (docID ));
529+ return SeekStatus .FOUND ;
530+ }
531+ // Remaining docs don't match, stop here
532+ if (tsIdOrd < docTsIdOrd || docTimestamp < timestamp ) {
533+ break ;
534+ }
535+ }
512536 }
513537 }
514538 current = NO_MORE_DOCS ;
0 commit comments