1717import org .apache .lucene .search .Weight ;
1818import org .apache .lucene .util .BytesRef ;
1919import org .apache .lucene .util .PriorityQueue ;
20+ import org .elasticsearch .TransportVersion ;
21+ import org .elasticsearch .TransportVersions ;
22+ import org .elasticsearch .common .io .stream .NamedWriteableRegistry ;
23+ import org .elasticsearch .common .io .stream .StreamInput ;
24+ import org .elasticsearch .common .io .stream .StreamOutput ;
2025import org .elasticsearch .compute .data .Block ;
2126import org .elasticsearch .compute .data .BlockFactory ;
2227import org .elasticsearch .compute .data .BytesRefVector ;
2530import org .elasticsearch .compute .data .LongVector ;
2631import org .elasticsearch .compute .data .OrdinalBytesRefVector ;
2732import org .elasticsearch .compute .data .Page ;
28- import org .elasticsearch .compute .operator .SourceOperator ;
33+ import org .elasticsearch .compute .operator .Operator ;
2934import org .elasticsearch .core .Releasable ;
3035import org .elasticsearch .core .Releasables ;
3136import org .elasticsearch .index .fieldvisitor .StoredFieldLoader ;
3237import org .elasticsearch .index .mapper .BlockLoader ;
3338import org .elasticsearch .index .mapper .BlockLoaderStoredFieldsFromLeafLoader ;
3439import org .elasticsearch .index .mapper .SourceLoader ;
3540import org .elasticsearch .search .fetch .StoredFieldsSpec ;
41+ import org .elasticsearch .xcontent .XContentBuilder ;
3642
3743import java .io .IOException ;
3844import java .io .UncheckedIOException ;
3945import java .util .Arrays ;
4046import java .util .List ;
47+ import java .util .Objects ;
4148
42- public final class TimeSeriesSourceOperator extends SourceOperator {
49+ public final class TimeSeriesSourceOperator extends LuceneOperator {
4350
4451 private final boolean emitDocIds ;
4552 private final int maxPageSize ;
@@ -55,6 +62,7 @@ public final class TimeSeriesSourceOperator extends SourceOperator {
5562 private final List <ValuesSourceReaderOperator .FieldInfo > fieldsToExtracts ;
5663 private ShardLevelFieldsReader fieldsReader ;
5764 private DocIdCollector docCollector ;
65+ private long tsidsLoaded ;
5866
5967 TimeSeriesSourceOperator (
6068 BlockFactory blockFactory ,
@@ -64,6 +72,7 @@ public final class TimeSeriesSourceOperator extends SourceOperator {
6472 int maxPageSize ,
6573 int limit
6674 ) {
75+ super (blockFactory , maxPageSize , sliceQueue );
6776 this .maxPageSize = maxPageSize ;
6877 this .blockFactory = blockFactory ;
6978 this .fieldsToExtracts = fieldsToExtract ;
@@ -85,7 +94,7 @@ public boolean isFinished() {
8594 }
8695
8796 @ Override
88- public Page getOutput () {
97+ public Page getCheckedOutput () throws IOException {
8998 if (isFinished ()) {
9099 return null ;
91100 }
@@ -97,6 +106,7 @@ public Page getOutput() {
97106
98107 Page page = null ;
99108 Block [] blocks = new Block [(emitDocIds ? 3 : 2 ) + fieldsToExtracts .size ()];
109+ long startInNanos = System .nanoTime ();
100110 try {
101111 if (iterator == null ) {
102112 var slice = sliceQueue .nextSlice ();
@@ -130,6 +140,8 @@ public Page getOutput() {
130140 currentPagePos = 0 ;
131141 }
132142 if (iterator .completed ()) {
143+ processedShards .add (iterator .luceneSlice .shardContext ().shardIdentifier ());
144+ processedSlices ++;
133145 Releasables .close (docCollector , fieldsReader );
134146 iterator = null ;
135147 }
@@ -139,6 +151,7 @@ public Page getOutput() {
139151 if (page == null ) {
140152 Releasables .closeExpectNoException (blocks );
141153 }
154+ processingNanos += System .nanoTime () - startInNanos ;
142155 }
143156 return page ;
144157 }
@@ -162,6 +175,7 @@ protected boolean lessThan(LeafIterator a, LeafIterator b) {
162175 }
163176 };
164177 Weight weight = luceneSlice .weight ();
178+ processedQueries .add (weight .getQuery ());
165179 int maxSegmentOrd = 0 ;
166180 for (var leafReaderContext : luceneSlice .leaves ()) {
167181 LeafIterator leafIterator = new LeafIterator (weight , leafReaderContext .leafReaderContext ());
@@ -237,6 +251,9 @@ private PriorityQueue<LeafIterator> subQueueForNextTsid() {
237251 break ;
238252 }
239253 }
254+ if (oneTsidQueue .size () > 0 ) {
255+ ++tsidsLoaded ;
256+ }
240257 }
241258 return oneTsidQueue ;
242259 }
@@ -306,11 +323,6 @@ void reinitializeIfNeeded(Thread executingThread) throws IOException {
306323 }
307324 }
308325
309- @ Override
310- public String toString () {
311- return this .getClass ().getSimpleName () + "[" + "maxPageSize=" + maxPageSize + ", remainingDocs=" + remainingDocs + "]" ;
312- }
313-
314326 static class BlockLoaderFactory extends ValuesSourceReaderOperator .DelegatingBlockLoaderFactory {
315327 BlockLoaderFactory (BlockFactory factory ) {
316328 super (factory );
@@ -571,4 +583,84 @@ public void close() {
571583 Releasables .close (docsBuilder , segmentsBuilder );
572584 }
573585 }
586+
587+ @ Override
588+ protected void describe (StringBuilder sb ) {
589+ sb .append ("[" + "maxPageSize=" ).append (maxPageSize ).append (", remainingDocs=" ).append (remainingDocs ).append ("]" );
590+ }
591+
592+ @ Override
593+ public Operator .Status status () {
594+ final long valuesLoaded = rowsEmitted * (1 + fieldsToExtracts .size ()); // @timestamp and other fields
595+ return new Status (this , tsidsLoaded , valuesLoaded );
596+ }
597+
598+ public static class Status extends LuceneOperator .Status {
599+ public static final NamedWriteableRegistry .Entry ENTRY = new NamedWriteableRegistry .Entry (
600+ Operator .Status .class ,
601+ "time_series_source" ,
602+ Status ::new
603+ );
604+
605+ private final long tsidLoaded ;
606+ private final long valuesLoaded ;
607+
608+ Status (TimeSeriesSourceOperator operator , long tsidLoaded , long valuesLoaded ) {
609+ super (operator );
610+ this .tsidLoaded = tsidLoaded ;
611+ this .valuesLoaded = valuesLoaded ;
612+ }
613+
614+ Status (StreamInput in ) throws IOException {
615+ super (in );
616+ this .tsidLoaded = in .readVLong ();
617+ this .valuesLoaded = in .readVLong ();
618+ }
619+
620+ @ Override
621+ public void writeTo (StreamOutput out ) throws IOException {
622+ super .writeTo (out );
623+ out .writeVLong (tsidLoaded );
624+ out .writeVLong (valuesLoaded );
625+ }
626+
627+ @ Override
628+ protected void toXContentFields (XContentBuilder builder , Params params ) throws IOException {
629+ super .toXContentFields (builder , params );
630+ builder .field ("tsid_loaded" , tsidLoaded );
631+ builder .field ("values_loaded" , valuesLoaded );
632+ }
633+
634+ public long tsidLoaded () {
635+ return tsidLoaded ;
636+ }
637+
638+ @ Override
639+ public String getWriteableName () {
640+ return ENTRY .name ;
641+ }
642+
643+ @ Override
644+ public boolean supportsVersion (TransportVersion version ) {
645+ return version .onOrAfter (TransportVersions .ESQL_TIME_SERIES_SOURCE_STATUS );
646+ }
647+
648+ @ Override
649+ public long valuesLoaded () {
650+ return valuesLoaded ;
651+ }
652+
653+ @ Override
654+ public boolean equals (Object o ) {
655+ if (o == null || getClass () != o .getClass ()) return false ;
656+ if (super .equals (o ) == false ) return false ;
657+ Status status = (Status ) o ;
658+ return tsidLoaded == status .tsidLoaded && valuesLoaded == status .valuesLoaded ;
659+ }
660+
661+ @ Override
662+ public int hashCode () {
663+ return Objects .hash (super .hashCode (), tsidLoaded , valuesLoaded );
664+ }
665+ }
574666}
0 commit comments