Interface RecordCursor<T>

    • Method Detail

      • hasNext

        @API(DEPRECATED)
        @Deprecated
        default boolean hasNext()
        Deprecated.
        in favor of the onNext() method or advancing the cursor asIterator()
        Synchronously check whether there are more records available from the cursor.
        Specified by:
        hasNext in interface Iterator<T>
        Returns:
        true if next() would return a record and false otherwise
      • getContinuation

        @API(DEPRECATED)
        @Deprecated
        @Nullable
        byte[] getContinuation()
        Deprecated.
        in favor of the onNext() method or advancing the cursor asIterator()
        Get a byte string that can be used to continue a query after the last record returned.
        Returns:
        opaque byte array denoting where the cursor should pick up. This can be passed back into a new cursor of the same type, with all other parameters remaining the same. Returns null if the underlying source is completely exhausted, independent of any limit passed to the cursor creator. Since such creators generally accept null to mean no continuation, that is, start from the beginning, one must check for null from getContinuation to keep from starting over. Result is not always defined if called before onHasNext or before next after onHasNext has returned true. That is, a continuation is only guaranteed when called "between" records from a while (hasNext) next loop or after its end.
      • onNext

        @Nonnull
        CompletableFuture<RecordCursorResult<T>> onNext()
        Asynchronously return the next result from this cursor. When complete, the future will contain a RecordCursorResult, which represents exactly one of the following:
        1. The next object of type T produced by the cursor. In addition to the next record, this result includes a RecordCursorContinuation that can be used to continue the cursor after the last record returned. The returned continuation is guaranteed not to be an "end continuation" representing the end of the cursor: specifically, RecordCursorContinuation.isEnd() is always false on the returned continuation.
        2. The fact that the cursor is stopped and cannot produce another record and a RecordCursor.NoNextReason that explains why no record could be produced. The result include a continuation that can be used to continue the cursor after the last record returned. If the result's NoNextReason is anything other than RecordCursor.NoNextReason.SOURCE_EXHAUSTED, the returned continuation must not be an end continuation. Conversely, if the result's NoNextReason is SOURCE_EXHAUSTED, then the returned continuation must be an an "end continuation".
        In either case, the returned RecordCursorContinuation can be serialized to an opaque byte array using RecordCursorContinuation.toBytes(). This can be passed back into a new cursor of the same type, with all other parameters remaining the same.
        Returns:
        a future for the next result from this cursor representing either the next record or an indication of why the cursor stopped
        See Also:
        RecordCursorResult, RecordCursorContinuation
      • getNext

        @Nonnull
        default RecordCursorResult<T> getNext()
        Get the next result from this cursor. In many cases, this is a blocking operation and should not be called within asynchronous contexts. The non-blocking version of this function, onNext(), should be preferred in such circumstances.
        Returns:
        the next result from this cursor representing either the next record or an indication of why the cursor stopped
        See Also:
        onNext(), RecordCursorResult, RecordCursorContinuation
      • accept

        boolean accept​(@Nonnull
                       RecordCursorVisitor visitor)
        Accept a visit from hierarchical visitor, which implements RecordCursorVisitor. By contract, implementations of this method must return the value of visitor.visitLeave(this), which determines whether or not subsequent siblings of this cursor should be visited.
        Parameters:
        visitor - a hierarchical visitor
        Returns:
        true if the subsequent siblings of the cursor should be visited, and false otherwise
      • asList

        @Nonnull
        default CompletableFuture<List<T>> asList()
        Return the entire stream of records as an asynchronous list.
        Returns:
        a future that when complete has a list with all remaining records.
      • getCount

        @Nonnull
        default CompletableFuture<Integer> getCount()
        Count the number of records remaining.
        Returns:
        a future that completes to the number of records in the cursor
      • first

        @Nonnull
        default CompletableFuture<Optional<T>> first()
        Fetches the first item returned by the cursor.
        Returns:
        Optional.empty() if the cursor had no results or if the first record was null, otherwise returns an Optional of the first item returned by the cursor.
      • map

        @Nonnull
        default <V> RecordCursor<V> map​(@Nonnull
                                        Function<T,​V> func)
        Get a new cursor by applying the given function to the records in this cursor.
        Type Parameters:
        V - the type of the record elements
        Parameters:
        func - the function to apply
        Returns:
        a new cursor that applies the given function
      • mapEffect

        @Nonnull
        default RecordCursor<T> mapEffect​(@Nonnull
                                          Consumer<T> consumer)
        Get a new cursor that applies the given consumer to the records in this cursor, without modifying the cursor records.
        Parameters:
        consumer - the consumer to apply
        Returns:
        a new cursor that applies the given consumer
      • mapEffect

        @Nonnull
        default RecordCursor<T> mapEffect​(@Nonnull
                                          Runnable runnable)
        Get a new cursor that runs the given runnable every time a record arrives, without modifying the cursor records.
        Parameters:
        runnable - the runnable to call
        Returns:
        a new cursor that runs the given runnable as record pass through
      • filter

        @Nonnull
        default RecordCursor<T> filter​(@Nonnull
                                       Function<T,​Boolean> pred)
        Get a new cursor that skips records that do not satisfy the given predicate.
        Parameters:
        pred - the predicate to apply
        Returns:
        a new cursor that filters out records for which pred returns false
      • filterInstrumented

        @Nonnull
        default RecordCursor<T> filterInstrumented​(@Nonnull
                                                   Function<T,​Boolean> pred,
                                                   @Nullable
                                                   StoreTimer timer,
                                                   @Nonnull
                                                   Set<StoreTimer.Count> inSet,
                                                   @Nonnull
                                                   Set<StoreTimer.Event> duringSet,
                                                   @Nonnull
                                                   Set<StoreTimer.Count> successSet,
                                                   @Nonnull
                                                   Set<StoreTimer.Count> failureSet)
        Get a new cursor that skips records that do not satisfy the given predicate, while instrumenting the number of records that the filter sees, the number that it passes, the number that it fails, and the amount of time that it spends computing the predicate.
        Parameters:
        pred - a boolean predicate to filter on
        timer - a StoreTimer to log the counts and events
        inSet - a set StoreTimer.Count that will be incremented for each record the filter sees
        duringSet - a set of StoreTimer.Event that will log the time spent computing the predicate
        successSet - a set of StoreTimer.Count that will be increment for each record on which the predicate evaluates true
        failureSet - a set of StoreTimer.Count that will be increment for each record on which the predicate evaluates false
        Returns:
        a new cursor that skips records for which pred returns false
      • skip

        default RecordCursor<T> skip​(int skip)
        Get a new cursor that skips the given number of records.
        Parameters:
        skip - number of records to skip
        Returns:
        a new cursor that starts after skip records
      • limitTo

        @Deprecated
        default RecordCursor<T> limitTo​(int limit)
        Deprecated.
        Use limitRowsTo(int) instead.
        Parameters:
        limit - the maximum number of records to return
        Returns:
        a new cursor that will return at most limit records
      • limitRowsTo

        @Nonnull
        default RecordCursor<T> limitRowsTo​(int limit)
        Get a new cursor that will only return records up to the given limit.
        Parameters:
        limit - the maximum number of records to return
        Returns:
        a new cursor that will return at most limit records
      • mapPipelined

        @Nonnull
        default <V> RecordCursor<V> mapPipelined​(@Nonnull
                                                 Function<T,​CompletableFuture<V>> func,
                                                 int pipelineSize)
        Get a new cursor by applying the given asynchronous function to the records in this cursor.
        Type Parameters:
        V - the result type of the mapping function
        Parameters:
        func - the function to apply to each record
        pipelineSize - the number of futures from applications of the mapping function to start ahead of time
        Returns:
        a new cursor that applies the given function to each record
      • flatMapPipelined

        @Deprecated
        @API(DEPRECATED)
        @Nonnull
        default <V> RecordCursor<V> flatMapPipelined​(@Nonnull
                                                     Function<T,​? extends RecordCursor<V>> func,
                                                     int pipelineSize)
        Deprecated.
        because it does not support continuations and is easy to misuse. Use flatMapPipelined(Function, BiFunction, byte[], int) instead.
        Get a new cursor by applying the given cursor generating function to the records in this cursor.
        Type Parameters:
        V - the result type of the mapping function
        Parameters:
        func - the function to apply to each record
        pipelineSize - the number of cursors from applications of the mapping function to open ahead of time
        Returns:
        a new cursor that applies the given function to produce a cursor of records that gets flattened
      • flatMapPipelined

        @Nonnull
        static <T,​V> RecordCursor<V> flatMapPipelined​(@Nonnull
                                                            Function<byte[],​? extends RecordCursor<T>> outerFunc,
                                                            @Nonnull
                                                            BiFunction<T,​byte[],​? extends RecordCursor<V>> innerFunc,
                                                            @Nullable
                                                            Function<T,​byte[]> checker,
                                                            @Nullable
                                                            byte[] continuation,
                                                            int pipelineSize)
        Resume a nested cursor with the given continuation or start if null.
        Type Parameters:
        T - the result type of the outer cursor
        V - the result type of the inner cursor produced by the mapping function
        Parameters:
        outerFunc - a function that takes the outer continuation and returns the outer cursor.
        innerFunc - a function that takes an outer record and an inner continuation and returns the inner cursor.
        checker - a function that takes an outer record and returns a way of recognizing it again or null. When computing the continuation, this is called on the current outer record and the result, if not null, becomes part of the continuation. When this continuation is used, the function (presumably the same one) is called on the outer record again. If the results match, the inner cursor picks up where it left off. If not, the entire inner cursor is run. This handles common cases of the data changing between transactions, such as the outer record being deleted (skip rest of inner record) or a new record being inserted right before it (do full inner cursor, not partial based on previous).
        continuation - the continuation returned from a previous instance of this pipeline or null at start.
        pipelineSize - the number of outer items to work ahead; inner cursors for these will be started in parallel.
        Returns:
        a FlatMapPipelinedCursor that maps the inner function across the results of the outer function
      • filterAsync

        @Nonnull
        default RecordCursor<T> filterAsync​(@Nonnull
                                            Function<T,​CompletableFuture<Boolean>> pred,
                                            int pipelineSize)
        Get a new cursor that skips records that do not satisfy the given asynchronous predicate.
        Parameters:
        pred - a predicate to apply
        pipelineSize - the number of futures from applications of the predicate to start ahead of time
        Returns:
        a new cursor that filters out records for which pred returned a future that completed to false
      • filterAsyncInstrumented

        @Nonnull
        default RecordCursor<T> filterAsyncInstrumented​(@Nonnull
                                                        Function<T,​CompletableFuture<Boolean>> pred,
                                                        int pipelineSize,
                                                        @Nullable
                                                        StoreTimer timer,
                                                        @Nonnull
                                                        Set<StoreTimer.Count> inSet,
                                                        @Nonnull
                                                        Set<StoreTimer.Event> duringSet,
                                                        @Nonnull
                                                        Set<StoreTimer.Count> successSet,
                                                        @Nonnull
                                                        Set<StoreTimer.Count> failureSet)
        Get a new cursor that skips records that do not satisfy the given asynchronous predicate, while instrumenting the number of records that the filter sees, the number that it passes, the number that it fails, and the amount of time that it spends computing the predicate.
        Parameters:
        pred - a boolean predicate to filter on
        pipelineSize - the number of futures from applications of the predicate to start ahead of time
        timer - a StoreTimer to log the counts and events
        inSet - a set StoreTimer.Count that will be incremented for each record the filter sees
        duringSet - a set of StoreTimer.Event that will log the time spent computing the predicate
        successSet - a set of StoreTimer.Count that will be increment for each record on which the predicate evaluates true
        failureSet - a set of StoreTimer.Count that will be increment for each record on which the predicate evaluates false
        Returns:
        a new cursor that filters out records for which pred returned a future that completed to false
      • forEach

        @Nonnull
        default CompletableFuture<Void> forEach​(Consumer<T> consumer)
        Call the given consumer as each record becomes available.
        Parameters:
        consumer - function to be applied to each record
        Returns:
        a future that is complete when the consumer has been called on all remaining records
      • forEachResult

        @Nonnull
        default CompletableFuture<RecordCursorResult<T>> forEachResult​(@Nonnull
                                                                       Consumer<RecordCursorResult<T>> consumer)
        Call the given consumer as each record result becomes available. Each of the results given to the consumer is guaranteed to have a value, i.e., calling hasNext() on the result will return true. The returned future will then contain the first result that does not have an associated value, i.e., hasNext() on the result will return false. This allows the caller to get a continuation for this cursor and determine why this cursor stopped producing values.
        Parameters:
        consumer - function to be applied to each result
        Returns:
        a future that is complete when the consumer has been called on all remaining records
      • forEachAsync

        @Nonnull
        default CompletableFuture<Void> forEachAsync​(@Nonnull
                                                     Function<T,​CompletableFuture<Void>> func,
                                                     int pipelineSize)
        Call the function as each record becomes available. This will be ready when all of the elements of this cursor have been read and when all of the futures associated with those elements have completed.
        Parameters:
        func - function to be applied to each record
        pipelineSize - the number of futures from applications of the function to start ahead of time
        Returns:
        a future that is complete when the function has been called and all remaining records and the result has then completed
      • forEachResultAsync

        @Nonnull
        default CompletableFuture<RecordCursorResult<T>> forEachResultAsync​(@Nonnull
                                                                            Function<RecordCursorResult<T>,​CompletableFuture<Void>> func)
        Call the function as each record result becomes available. This will be ready when all of the elements of this cursor have been read and all of the futures associated with those elements have been completed. Each of the results given to the function is guaranteed to have a value, i.e., calling hasNext() on the result will return true. The return future will then contain the first result that does not have an associated value, i.e., hasNext() on the result will return false. This allows the caller to get a continuation and determine why this cursor stopped producing values.
        Parameters:
        func - function to be applied to each result
        Returns:
        a future that is complete when the consumer has been called on all remaining records
      • orElse

        @Nonnull
        static <T> RecordCursor<T> orElse​(@Nonnull
                                          Function<byte[],​? extends RecordCursor<T>> innerFunc,
                                          @Nonnull
                                          BiFunction<Executor,​byte[],​? extends RecordCursor<T>> elseFunc,
                                          @Nullable
                                          byte[] continuation)
        Get a new cursor that substitutes another cursor if a given inner cursor is empty. If a nonnull continuation is provided, it must come from a cursor that is structurally identical to the cursor being defined.
        Type Parameters:
        T - the type of result returned by the cursor
        Parameters:
        innerFunc - a function that takes a continuation and creates an inner cursor
        elseFunc - a function to be called if the cursor is empty to give another source of records
        continuation - a continuation (from a cursor with the same structure) to resume where it left off
        Returns:
        a new cursor that returns the same records as the generated inner cursor or the result of func if this cursor does not produce any records
      • fromIterator

        @Nonnull
        static <T> RecordCursor<T> fromIterator​(@Nonnull
                                                Iterator<T> iterator)
        Get a new cursor from an ordinary Iterator.
        Type Parameters:
        T - the type of elements of iterator
        Parameters:
        iterator - the iterator of records
        Returns:
        a new cursor that produces the elements of the given iterator
      • fromList

        @Nonnull
        static <T> RecordCursor<T> fromList​(@Nonnull
                                            List<T> list)
        Get a new cursor from an ordinary List.
        Type Parameters:
        T - the type of elements of list
        Parameters:
        list - the list of records
        Returns:
        a new cursor that produces the items of list
      • fromList

        @Nonnull
        static <T> RecordCursor<T> fromList​(@Nonnull
                                            List<T> list,
                                            @Nullable
                                            byte[] continuation)
        Get a new cursor from an ordinary List, skipping ahead according to the given continuation.
        Type Parameters:
        T - the type of elements of list
        Parameters:
        list - the list of records
        continuation - the result of getContinuation() from an earlier list cursor.
        Returns:
        a new cursor that produces the items of list, resuming if continuation is not null
      • fromFuture

        @Nonnull
        static <T> RecordCursor<T> fromFuture​(@Nonnull
                                              CompletableFuture<T> future)
        Get a new cursor that has the contents of the given future as its only record The record will be available when the future is complete.
        Type Parameters:
        T - the result type of the future
        Parameters:
        future - a future that completes to the only element of the cursor
        Returns:
        a new cursor producing the contents of future
      • fromFuture

        @Nonnull
        static <T> RecordCursor<T> fromFuture​(@Nonnull
                                              Executor executor,
                                              @Nonnull
                                              CompletableFuture<T> future,
                                              @Nullable
                                              byte[] continuation)
        Get a new cursor that has the contents of the given future as its only record. If the continuation is nonnull, return an empty cursor since a FutureCursor returns only a single record.
        Type Parameters:
        T - the result type of the future
        Parameters:
        executor - an executor for executing the future
        future - a future that completes to the only element of the cursor
        continuation - a continuation from a future cursor to determine whether the cursor has a single element or no elements
        Returns:
        a new cursor producing the contents of future if the continuation is nonnull and an empty cursor otherwise
      • mapFuture

        static <T,​V> RecordCursor<T> mapFuture​(@Nonnull
                                                     Executor executor,
                                                     @Nonnull
                                                     CompletableFuture<V> future,
                                                     @Nullable
                                                     byte[] continuation,
                                                     @Nonnull
                                                     BiFunction<V,​byte[],​? extends RecordCursor<T>> function)
        Get a new cursor by applying the contents of the given future to the given function, with proper continuation handling.
        Type Parameters:
        T - the type of elements of the cursor
        V - the return type of the function
        Parameters:
        executor - an executor in which to run asynchronous calls
        future - a future that completes to the argument to the function
        continuation - any continuation from a previous invocation of this method
        function - a function that takes the contents of the future and a continuation and returns a cursor
        Returns:
        a new cursor from applying function to future and continuation
      • empty

        @Nonnull
        static <T> RecordCursor<T> empty()
        Get a new cursor that does not return any records.
        Type Parameters:
        T - the type of elements of the cursor
        Returns:
        a new empty cursor
      • reduce

        @Nullable
        default <U> CompletableFuture<U> reduce​(U identity,
                                                BiFunction<U,​? super T,​U> accumulator)
        Reduce contents of cursor to single value.
        Type Parameters:
        U - the result type of the reduction
        Parameters:
        identity - initial value for reduction
        accumulator - function that takes previous reduced value and computes new value by combining with each record
        Returns:
        a future that completes to the result of reduction