/* * Licensed to Crate under one or more contributor license agreements. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. Crate licenses this file * to you under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may * obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * * However, if you have executed another commercial license agreement * with Crate these terms will supersede the license and you may use the * software solely pursuant to the terms of the relevant commercial * agreement. */ package io.crate.data; import java.util.concurrent.CompletionStage; /** * An iterator used to navigate over data organized in batches. Though not required most * implementations already hold an initial batch of data ready for use and further data can be loaded asynchronously * via the {@link #loadNextBatch()} method. * * The loaded data can be accessed by moving the iterator via the movement methods {@link #moveNext()} and * {@link #moveToStart()} and then using the {@link Columns} object returned by {@link #rowData()} to access the data * at the current position. * * Once all loaded data has been consumed more data can be loaded with {@link #loadNextBatch()} unless {@link * #allLoaded()} is true in which case the iterator is exhausted. * * A BatchIterator starts either *before* the first row or in an unloaded state. * This means a consumer can consume a BatchIterator like this: * * <pre> * while (it.moveNext()) { * // do something with the row * } * if (it.allLoaded()) { * // iterator is exhausted * } else { * it.loadNextBatch().whenComplete((r, t) -> { * // continue consumption * } * } * </pre> * * * Thread-safety notes: * * Concurrent usage of a BatchIterator is not supported. */ public interface BatchIterator extends Killable { /** * This method returns a columns object which can be used to access the underlying data of the current iterator * position. * * Note that it is only valid to call {@link Input#value()} on any of the returned columns if the iterator is * positioned on a valid row, which is only the case if the last call to {@link #moveNext()} returned true. * * This method is valid to be called over the whole lifetime of the iterator, regardless of the state of the * iterator or its position. However it is good practice for consumers of this iterator to gather the columns * before iterating. This method is required to always return the same object on every call. * * @return a columns object */ Columns rowData(); /** * Moves the Iterator back to the starting position. * * A consumer can then iterate over the rows again by calling into * {@link #moveNext()} and {@link #loadNextBatch()} as appropriate. * * @throws IllegalStateException if the cursor is closed */ void moveToStart(); /** * Advances the iterator. * * @return true if the iterator moved to the next valid row. * false if the iterator is no longer on a valid row. * If {@link #allLoaded()} returns true the iterator is out of data. Otherwise {@link #loadNextBatch()} * can be used to load the next batch - after which {@code moveNext()} can be used again. * * @throws IllegalStateException if the cursor is closed */ boolean moveNext(); /** * Closes the iterator and frees all resources. * After this method has been called all methods on the iterator will result in an error. * * There are two exceptions to that: * - close: Close itself can be called multiple times, but only the first call has an effect. * - loadNextBatch: This method never raises, but instead returns a failed CompletionStage. */ void close(); /** * Loads the next batch if there is still data available for loading. * This may only be called if {@link #allLoaded()} returns false. * If {@link #allLoaded()} returns true, calling this method will return a failed CompletionStage. * * <p> * NOTE: while loading takes place the iterator must not be moved. * The iterator behaviour in this case is undetermined. * * @return a future which will be completed once the loading is done. * Once the future completes the iterator is still in an "off-row" state, but {@link #moveNext()} * can be called again if the next batch contains more data. */ CompletionStage<?> loadNextBatch(); /** * @return true if no more batches can be loaded * @throws IllegalStateException if the cursor is closed */ boolean allLoaded(); }