Class MergeCursor<T,U,S extends MergeCursorState<T>>
- java.lang.Object
-
- com.apple.foundationdb.record.provider.foundationdb.cursors.MergeCursor<T,U,S>
-
- Type Parameters:
T
- type of input elementsU
- type of output elementsS
- type of merge state
- All Implemented Interfaces:
RecordCursor<U>
,AutoCloseable
,Iterator<U>
- Direct Known Subclasses:
IntersectionCursor
,IntersectionMultiCursor
,ProbableIntersectionCursor
,UnionCursor
,UnorderedUnionCursor
@API(INTERNAL) public abstract class MergeCursor<T,U,S extends MergeCursorState<T>> extends Object implements RecordCursor<U>
An abstract class that corresponds to some kind of cursor merging multiple children together. It forms a common basis for various union and intersection cursors. Extenders should also extend:MergeCursorContinuation
with an implementation that constructs an appropriate Protobuf message.MergeCursorState
if additional state is needed to accompany each cursor.
-
-
Nested Class Summary
-
Nested classes/interfaces inherited from interface com.apple.foundationdb.record.RecordCursor
RecordCursor.NoNextReason
-
-
Constructor Summary
Constructors Modifier Constructor Description protected
MergeCursor(List<S> cursorStates, FDBStoreTimer timer)
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Deprecated Methods Modifier and Type Method Description boolean
accept(RecordCursorVisitor visitor)
Accept a visit from hierarchical visitor, which implementsRecordCursorVisitor
.protected void
checkNextStateTimeout(long startTime)
void
close()
protected abstract CompletableFuture<List<S>>
computeNextResultStates()
Determine which cursors should have their values included in the next iteration.protected List<RecordCursorContinuation>
getChildContinuations()
byte[]
getContinuation()
Deprecated.protected abstract RecordCursorContinuation
getContinuationObject()
Produce aRecordCursorContinuation
for this cursor.protected List<S>
getCursorStates()
Get the child cursors along with associated mutable state.Executor
getExecutor()
protected abstract U
getNextResult(List<S> resultStates)
Determine the next result to return based on the results of the child cursors.RecordCursor.NoNextReason
getNoNextReason()
Deprecated.protected static <T,S extends MergeCursorState<T>>
RecordCursor.NoNextReasongetStrongestNoNextReason(List<S> cursorStates)
Gets the strongest reason for stopping of all cursor states.FDBStoreTimer
getTimer()
Get theFDBStoreTimer
used to instrument events of this cursor.protected static <T,S extends MergeCursorState<T>>
RecordCursor.NoNextReasongetWeakestNoNextReason(List<S> cursorStates)
Gets the weakest reason for stopping of all cursor states.protected abstract RecordCursor.NoNextReason
mergeNoNextReasons()
Merge theRecordCursor.NoNextReason
s for child cursors.U
next()
Deprecated.CompletableFuture<Boolean>
onHasNext()
Deprecated.CompletableFuture<RecordCursorResult<U>>
onNext()
Asynchronously return the next result from this cursor.protected static <T,S extends MergeCursorState<T>>
CompletableFuture<Void>whenAll(List<S> cursorStates)
protected static <T,S extends MergeCursorState<T>>
CompletableFuture<?>whenAny(List<S> cursorStates)
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface java.util.Iterator
forEachRemaining, remove
-
Methods inherited from interface com.apple.foundationdb.record.RecordCursor
asIterator, asList, filter, filterAsync, filterAsyncInstrumented, filterAsyncInstrumented, filterInstrumented, filterInstrumented, first, flatMapPipelined, forEach, forEachAsync, forEachResult, forEachResultAsync, getCount, getNext, hasNext, limitRowsTo, limitTo, map, mapEffect, mapEffect, mapPipelined, orElse, reduce, skip, skipThenLimit
-
-
-
-
Constructor Detail
-
MergeCursor
protected MergeCursor(@Nonnull List<S> cursorStates, @Nullable FDBStoreTimer timer)
-
-
Method Detail
-
whenAll
@Nonnull protected static <T,S extends MergeCursorState<T>> CompletableFuture<Void> whenAll(@Nonnull List<S> cursorStates)
-
whenAny
@Nonnull protected static <T,S extends MergeCursorState<T>> CompletableFuture<?> whenAny(@Nonnull List<S> cursorStates)
-
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 thanRecordCursor.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 cursorS
- 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 isRecordCursor.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 cursorS
- 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 callinggetCursorStates()
.) 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 ofcomputeNextResultStates()
.- 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 theRecordCursor.NoNextReason
s for child cursors. This will only be called after it is determined that the merge cursor itself will not return aNoNextReason
. Note that this may (or may) not imply that all child cursors are done (depending on the implementation of the extending cursor). ThisNoNextReason
will be the reason returned by the merge cursor.- Returns:
- a
RecordCursor.NoNextReason
based on the child cursors'NoNextReason
s
-
getContinuationObject
@Nonnull protected abstract RecordCursorContinuation getContinuationObject()
Produce aRecordCursorContinuation
for this cursor. The super-class itself handles constructing the byte array continuation from this continuation. Most continuations will be based on the continuations of this cursors child cursors. These can be retrieved by callinggetChildContinuations()
. This will only be called aftercomputeNextResultStates()
has completed.- Returns:
- a
RecordCursorContinuation
for this cursor based on the state of its child cursors
-
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 aRecordCursorResult
, which represents exactly one of the following:-
The next object of type
T
produced by the cursor. In addition to the next record, this result includes aRecordCursorContinuation
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 alwaysfalse
on the returned continuation. -
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'sNoNextReason
is anything other thanRecordCursor.NoNextReason.SOURCE_EXHAUSTED
, the returned continuation must not be an end continuation. Conversely, if the result'sNoNextReason
isSOURCE_EXHAUSTED
, then the returned continuation must be an an "end continuation".
RecordCursorContinuation
can be serialized to an opaque byte array usingRecordCursorContinuation.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 interfaceRecordCursor<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
-
The next object of type
-
onHasNext
@Nonnull @Deprecated public CompletableFuture<Boolean> onHasNext()
Deprecated.Description copied from interface:RecordCursor
Asynchronously check whether there are more records available from the cursor.- Specified by:
onHasNext
in interfaceRecordCursor<T>
- Returns:
- a future that when complete will hold
true
ifRecordCursor.next()
would return a record. - See Also:
AsyncIterator.onHasNext()
-
next
@Nullable @Deprecated public U next()
Deprecated.Description copied from interface:RecordCursor
Return the next value.
-
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 interfaceRecordCursor<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 acceptnull
to mean no continuation, that is, start from the beginning, one must check fornull
fromgetContinuation
to keep from starting over. Result is not always defined if called beforeonHasNext
or beforenext
afteronHasNext
has returnedtrue
. That is, a continuation is only guaranteed when called "between" records from awhile (hasNext) next
loop or after its end.
-
getNoNextReason
@Nonnull @Deprecated public RecordCursor.NoNextReason getNoNextReason()
Deprecated.Description copied from interface:RecordCursor
Get the reason that the cursor has reached the end and returnedfalse
forRecordCursor.hasNext()
. IfhasNext
was not called or returnedtrue
last time, the result is undefined and may be an exception.- Specified by:
getNoNextReason
in interfaceRecordCursor<T>
- Returns:
- the reason that the cursor stopped
-
getChildContinuations
@Nonnull protected List<RecordCursorContinuation> getChildContinuations()
-
close
public void close()
- Specified by:
close
in interfaceAutoCloseable
- Specified by:
close
in interfaceRecordCursor<T>
-
getExecutor
@Nonnull public Executor getExecutor()
- Specified by:
getExecutor
in interfaceRecordCursor<T>
-
getTimer
@Nullable public FDBStoreTimer getTimer()
Get theFDBStoreTimer
used to instrument events of this cursor.- Returns:
- the timer used to instrument this cursor
-
accept
public boolean accept(@Nonnull RecordCursorVisitor visitor)
Description copied from interface:RecordCursor
Accept a visit from hierarchical visitor, which implementsRecordCursorVisitor
. By contract, implementations of this method must return the value ofvisitor.visitLeave(this)
, which determines whether or not subsequent siblings of this cursor should be visited.- Specified by:
accept
in interfaceRecordCursor<T>
- Parameters:
visitor
- a hierarchical visitor- Returns:
true
if the subsequent siblings of thecursor
should be visited, andfalse
otherwise
-
-