Class IntersectionMultiCursor<T>

  • Type Parameters:
    T - the type of elements returned by the child cursors
    All Implemented Interfaces:
    RecordCursor<List<T>>, AutoCloseable, Iterator<List<T>>

    @API(EXPERIMENTAL)
    public class IntersectionMultiCursor<T>
    extends Object
    A cursor that implements an intersection of matching elements from a set of cursors all of whom are ordered compatibly. This operates like the IntersectionCursor except that for each set of matching results, this returns a list of all of the elements from all of the child cursors rather than just one.
    See Also:
    IntersectionCursor
    • Method Detail

      • create

        @Nonnull
        public static <T> IntersectionMultiCursor<T> create​(@Nonnull
                                                            Function<? super T,​? extends List<Object>> comparisonKeyFunction,
                                                            boolean reverse,
                                                            @Nonnull
                                                            List<Function<byte[],​RecordCursor<T>>> cursorFunctions,
                                                            @Nullable
                                                            byte[] continuation,
                                                            @Nullable
                                                            FDBStoreTimer timer)
        Create an intersection cursor from two or more compatibly-ordered cursors. Note that this will throw an error if the list of cursors does not have at least two elements. The returned cursor will return lists of elements, all of which compare equal according to the comparison key function, though they might contain different information outside of what the comparison key function examines. This is useful, for example, if one needs to scan multiple segments of an index and then find all entries that correspond to the same primary key (which can be done by setting a comparison key function that identifies the primary key) and then also apply some filter on all of the entries that come back.

        Otherwise, this function returns a cursor that is subject to all of the constraints as an IntersectionCursor returned by its equivalent create() method.

        Type Parameters:
        T - the type of elements returned by this cursor
        Parameters:
        comparisonKeyFunction - the function evaluated to compare elements from different cursors
        reverse - whether records are returned in descending or ascending order by the comparison key
        cursorFunctions - a list of functions to produce RecordCursors from a continuation
        continuation - any continuation from a previous scan
        timer - the timer used to instrument events
        Returns:
        a cursor containing all records in all child cursors
      • computeNextResultStates

        @Nonnull
        protected CompletableFuture<List<com.apple.foundationdb.record.provider.foundationdb.cursors.KeyedMergeCursorState<T>>> computeNextResultStates()
        Compute the next result states for the cursor based on the status of the existing states. This should return a (not necessarily proper) sublist of this cursor's cursor states. By default, this assumes the cursors return results in a compatible order based on their comparison key and loops until they all have matching values. Extenders of this class may choose an alternative approach depending on the semantics of that cursor.

        To indicate that the intersection cursor should stop, this function should either return an empty list of states or a list containing at least one state that does not have a next item.

        Returns:
        the list of states included in the next result
      • mergeNoNextReasons

        @Nonnull
        protected RecordCursor.NoNextReason mergeNoNextReasons()
        Merges all of the cursors and whether they have stopped and returns the "weakest" reason for the result to stop. It will return RecordCursor.NoNextReason.SOURCE_EXHAUSTED if any of the cursors are exhausted. If any of the cursors have stopped due to an in-band limit, it will return an in-band limit as well. Finally, if all of the stopped cursors have done so due to hitting an out-of-band limit, it will return an out-of-band limit as well. Note that, in practice, because an intersection cursor will return false from onHasNext if any of its child cursors have stopped, it is likely that there are only a small number (maybe one or two) cursors that have actually stopped when this method is called (e.g., the first cursor to exhaust its source or the first cursor to hit a limit imposed by the element scan limiter).
        Returns:
        the weakest reason for stopping
      • 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