Class BufferingPageIterator

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

public abstract class BufferingPageIterator extends Object implements CloseableIterator<Page>
Base class for the external-format page iterators (NDJSON, CSV, parquet-rs) that buffer a single look-ahead Page in nextPage — materialized by the subclass's hasNext() and handed out (and nulled) by its next().

It centralizes the one thing every such iterator must do and each previously forgot: release that buffered page on close(). When a consumer closes early — a pushed-down LIMIT, a query cancellation, or a downstream operator error — hasNext() may have already materialized a page that next() never consumed; without this release its Blocks leak against the circuit breaker. Subclasses keep their own produce/consume logic and put their teardown in closeInternal().

Threading contract: iteration (hasNext()/next()) is single-threaded — one consumer drives the iterator and is the only writer of nextPage. close() is idempotent and thread-safe (first caller wins) so it may run on a different thread than iteration: a consumer hands the iterator off to a cancel/abort path, and some backends (e.g. the native parquet-rs reader) must not be torn down twice. The buffered page is published to the closing thread by the same handoff that transfers ownership. Subclasses must preserve the single-threaded-iteration precondition; nextPage is not safe to publish across concurrent iterators.

  • Field Details

    • nextPage

      protected volatile Page nextPage
      The single look-ahead page: set by the subclass's hasNext(), handed out (and nulled) by next(). Volatile so close() — which may run on a different thread than iteration — reads the iterating thread's last write rather than a stale value, closing the publish gap for the off-thread close the class contract permits.
  • Constructor Details

    • BufferingPageIterator

      public BufferingPageIterator()
  • Method Details

    • close

      public final void close() throws IOException
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Throws:
      IOException
    • isClosed

      protected final boolean isClosed()
      Whether close() has been entered. Lets a subclass's hasNext() short-circuit to false after close instead of touching an already-torn-down decoder / native handle.
    • closeInternal

      protected abstract void closeInternal() throws IOException
      Subclass teardown: close streams / decoders / native handles and publish any end-of-read stats. Invoked exactly once, after the buffered page (if any) has been released, even if that release throws.
      Throws:
      IOException