Class StatsCapturingIterator

java.lang.Object
org.elasticsearch.xpack.esql.datasources.cache.StatsCapturingIterator
All Implemented Interfaces:
Closeable, AutoCloseable, Iterator<Page>, CloseableIterator<Page>, ColumnExtractorProducer

public final class StatsCapturingIterator extends Object implements CloseableIterator<Page>, ColumnExtractorProducer
Wraps a CloseableIterator so the iterator's close() runs with an ExternalStatsCapture sink bound on the current thread. The text-format iterators' close hooks call ExternalStatsCapture.record(...) on the bound sink; whichever operator drove the iteration owns the sink and reads its contents back via AsyncExternalSourceBuffer#capturedSourceMetadataSnapshot() or equivalent.

The wrapper is a thin pass-through for hasNext / next; the only behavior change is at close time. Multiple iterators wrapped against the same sink accumulate contributions in the sink — natural fit for multi-file and multi-split paths.

ColumnExtractorProducer forwarding

The wrapper unconditionally declares the ColumnExtractorProducer capability and forwards createColumnExtractor() / setExtractorId(int) to its delegate, mirroring SchemaAdaptingIterator. A non-producer delegate makes the consumer's instanceof ColumnExtractorProducer check a necessary-but-not-sufficient guard — the dispatch into the delegate fails loud (see innerProducer()). Without this forwarding the stats wrapper would hide a producer-capable reader from the deferred-extraction wiring in AsyncExternalSourceOperatorFactory#wrapWithEncoderIfNeeded, breaking _rowPosition encoding whenever stats capture and deferred extraction are both active on the same read.