Class MergeCursor<T,​U,​S extends MergeCursorState<T>>

    • Method Detail

      • checkNextStateTimeout

        protected void checkNextStateTimeout​(long startTime)
      • getStrongestNoNextReason

        @Nonnull
        protected static <T,​S extends MergeCursorState<T>> RecordCursor.NoNextReason getStrongestNoNextReason​(@Nonnull
                                                                                                                    List<S> cursorStates)
        Gets the strongest reason for stopping of all cursor states. An out-of-band reason is stronger than an in-band limit, and an in-band limit is stronger than RecordCursor.NoNextReason.SOURCE_EXHAUSTED. Cursors that have not been stopped are ignored, but if no cursor has stopped, this throws an error.
        Type Parameters:
        T - the type of elements returned by this cursor
        S - the type of cursor state in the list of cursors
        Parameters:
        cursorStates - the list of cursor states to consider
        Returns:
        the strongest reason to stop from the list of all cursors
      • getWeakestNoNextReason

        @Nonnull
        protected static <T,​S extends MergeCursorState<T>> RecordCursor.NoNextReason getWeakestNoNextReason​(@Nonnull
                                                                                                                  List<S> cursorStates)
        Gets the weakest reason for stopping of all cursor states. The weakest reason is RecordCursor.NoNextReason.SOURCE_EXHAUSTED, followed by an in-band limit, then an out of band limit.
        Type Parameters:
        T - the type of elements returned by this cursor
        S - the type of cursor state in the list of cursors
        Parameters:
        cursorStates - the list of cursor states to consider
        Returns:
        the strongest reason to stop from the list of all cursors
      • getCursorStates

        @Nonnull
        protected List<S> getCursorStates()
        Get the child cursors along with associated mutable state.
        Returns:
        the child cursors of this cursor
      • computeNextResultStates

        @Nonnull
        protected abstract CompletableFuture<List<S>> computeNextResultStates()
        Determine which cursors should have their values included in the next iteration. This list should include the state associated with each cursor, and the returned value should be a (not necessarily proper) sublist of the result states of this cursor. (This list can be retrieved by calling getCursorStates().) To indicate that this cursor is done returning elements, this function should return the empty list.
        Returns:
        the list of cursors to include in the next iteration
      • getNextResult

        @Nonnull
        protected abstract U getNextResult​(@Nonnull
                                           List<S> resultStates)
        Determine the next result to return based on the results of the child cursors. This will be called with the return value of computeNextResultStates().
        Parameters:
        resultStates - the list of cursors to be included in the result
        Returns:
        a result somehow combining the results of the input cursors
      • mergeNoNextReasons

        @Nonnull
        protected abstract RecordCursor.NoNextReason mergeNoNextReasons()
        Merge the RecordCursor.NoNextReasons for child cursors. This will only be called after it is determined that the merge cursor itself will not return a NoNextReason. Note that this may (or may) not imply that all child cursors are done (depending on the implementation of the extending cursor). This NoNextReason will be the reason returned by the merge cursor.
        Returns:
        a RecordCursor.NoNextReason based on the child cursors' NoNextReasons
      • onNext

        @Nonnull
        public CompletableFuture<RecordCursorResult<U>> onNext()
        Description copied from interface: RecordCursor
        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.
        Specified by:
        onNext in interface RecordCursor<T>
        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
      • getContinuation

        @Nullable
        @Deprecated
        public byte[] getContinuation()
        Deprecated.
        Description copied from interface: RecordCursor
        Get a byte string that can be used to continue a query after the last record returned.
        Specified by:
        getContinuation in interface RecordCursor<T>
        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.
      • accept

        public boolean accept​(@Nonnull
                              RecordCursorVisitor visitor)
        Description copied from interface: RecordCursor
        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.
        Specified by:
        accept in interface RecordCursor<T>
        Parameters:
        visitor - a hierarchical visitor
        Returns:
        true if the subsequent siblings of the cursor should be visited, and false otherwise