Class UnionCursor<T>
- java.lang.Object
-
- com.apple.foundationdb.record.provider.foundationdb.cursors.MergeCursor<T,T,S>
-
- com.apple.foundationdb.record.provider.foundationdb.cursors.UnionCursor<T>
-
- Type Parameters:
T
- the type of elements returned by the cursor
- All Implemented Interfaces:
RecordCursor<T>
,AutoCloseable
,Iterator<T>
@API(MAINTAINED) public class UnionCursor<T> extends MergeCursor<T,T,S>
A cursor that implements a union of all the records from a set of cursors, all of whom are ordered compatibly. In this instance, "compatibly ordered" means that all cursors should return results sorted by the "comparison key". For instance, aUnionCursor
of typeFDBQueriedRecord
might get the primary key of each record as the comparison key function. This is legal as long as all its children also return records ordered by primary key. This cursor removes any duplicates (relying solely on the comparison key to indicate that two elements are equal), and it returns results ordered by the comparison key.If any child of this cursor stops because it hits a limit, then this cursor will also stop. This differs from the behavior of the
UnorderedUnionCursor
. This cursor requires all of its children have returned a value before it can determine which value to return next (as otherwise, it does not know what the minimum value is according to the comparison key). If it were to continue returning results, there may be anomalies in the order of returned results across continuation boundaries.
-
-
Nested Class Summary
-
Nested classes/interfaces inherited from interface com.apple.foundationdb.record.RecordCursor
RecordCursor.NoNextReason
-
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description protected CompletableFuture<List<com.apple.foundationdb.record.provider.foundationdb.cursors.KeyedMergeCursorState<T>>>
computeNextResultStates()
Determine which cursors should have their values included in the next iteration.static <M extends Message,S extends FDBRecord<M>>
UnionCursor<S>create(FDBRecordStoreBase<M> store, KeyExpression comparisonKey, boolean reverse, Function<byte[],RecordCursor<S>> left, Function<byte[],RecordCursor<S>> right, byte[] continuation)
Create a union cursor from two compatibly-ordered cursors.static <M extends Message,S extends FDBRecord<M>>
UnionCursor<S>create(FDBRecordStoreBase<M> store, KeyExpression comparisonKey, boolean reverse, List<Function<byte[],RecordCursor<S>>> cursorFunctions, byte[] continuation)
Create a union cursor from two or more compatibly-ordered cursors.static <T> UnionCursor<T>
create(Function<? super T,? extends List<Object>> comparisonKeyFunction, boolean reverse, Function<byte[],RecordCursor<T>> left, Function<byte[],RecordCursor<T>> right, byte[] byteContinuation, FDBStoreTimer timer)
Create a union cursor from two compatibly-ordered cursors.static <T> UnionCursor<T>
create(Function<? super T,? extends List<Object>> comparisonKeyFunction, boolean reverse, List<Function<byte[],RecordCursor<T>>> cursorFunctions, byte[] byteContinuation, FDBStoreTimer timer)
Create a union cursor from two or more compatibly-ordered cursors.protected static <T> List<com.apple.foundationdb.record.provider.foundationdb.cursors.KeyedMergeCursorState<T>>
createCursorStates(Function<byte[],RecordCursor<T>> left, Function<byte[],RecordCursor<T>> right, byte[] byteContinuation, Function<? super T,? extends List<Object>> comparisonKeyFunction)
protected static <T> List<com.apple.foundationdb.record.provider.foundationdb.cursors.KeyedMergeCursorState<T>>
createCursorStates(List<Function<byte[],RecordCursor<T>>> cursorFunctions, byte[] byteContinuation, Function<? super T,? extends List<Object>> comparisonKeyFunction)
protected com.apple.foundationdb.record.provider.foundationdb.cursors.UnionCursorContinuation
getContinuationObject()
Produce aRecordCursorContinuation
for this cursor.protected T
getNextResult(List<S> chosenStates)
Get the result from the list of chosen states.protected RecordCursor.NoNextReason
mergeNoNextReasons()
Merges all of the cursors and whether they have stopped and returns the "strongest" reason for the result to stop.-
Methods inherited from class com.apple.foundationdb.record.provider.foundationdb.cursors.MergeCursor
accept, checkNextStateTimeout, close, getChildContinuations, getContinuation, getCursorStates, getExecutor, getNoNextReason, getStrongestNoNextReason, getTimer, getWeakestNoNextReason, next, onHasNext, onNext, whenAll, whenAny
-
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
-
-
-
-
Method Detail
-
computeNextResultStates
@Nonnull protected CompletableFuture<List<com.apple.foundationdb.record.provider.foundationdb.cursors.KeyedMergeCursorState<T>>> computeNextResultStates()
Description copied from class:MergeCursor
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 callingMergeCursor.getCursorStates()
.) To indicate that this cursor is done returning elements, this function should return the empty list.- Specified by:
computeNextResultStates
in classMergeCursor<T,T,com.apple.foundationdb.record.provider.foundationdb.cursors.KeyedMergeCursorState<T>>
- Returns:
- the list of cursors to include in the next iteration
-
createCursorStates
@Nonnull protected static <T> List<com.apple.foundationdb.record.provider.foundationdb.cursors.KeyedMergeCursorState<T>> createCursorStates(@Nonnull Function<byte[],RecordCursor<T>> left, @Nonnull Function<byte[],RecordCursor<T>> right, @Nullable byte[] byteContinuation, @Nonnull Function<? super T,? extends List<Object>> comparisonKeyFunction)
-
createCursorStates
@Nonnull protected static <T> List<com.apple.foundationdb.record.provider.foundationdb.cursors.KeyedMergeCursorState<T>> createCursorStates(@Nonnull List<Function<byte[],RecordCursor<T>>> cursorFunctions, @Nullable byte[] byteContinuation, @Nonnull Function<? super T,? extends List<Object>> comparisonKeyFunction)
-
create
@Nonnull public static <M extends Message,S extends FDBRecord<M>> UnionCursor<S> create(@Nonnull FDBRecordStoreBase<M> store, @Nonnull KeyExpression comparisonKey, boolean reverse, @Nonnull Function<byte[],RecordCursor<S>> left, @Nonnull Function<byte[],RecordCursor<S>> right, @Nullable byte[] continuation)
Create a union cursor from two compatibly-ordered cursors. This cursor is identical to the cursor that would be produced by calling the overload ofcreate()
that takes a list of cursors.- Type Parameters:
M
- the type of the Protobuf record elements of the cursorS
- the type of record wrapping a record of typeM
- Parameters:
store
- record store from which records will be fetchedcomparisonKey
- the key expression used to compare records from different cursorsreverse
- whether records are returned in descending or ascending order by the comparison keyleft
- a function to produce the firstRecordCursor
from a continuationright
- a function to produce the secondRecordCursor
from a continuationcontinuation
- any continuation from a previous scan- Returns:
- a cursor containing any records in any child cursors
- See Also:
create(FDBRecordStoreBase, KeyExpression, boolean, List, byte[])
-
create
@Nonnull public static <T> UnionCursor<T> create(@Nonnull Function<? super T,? extends List<Object>> comparisonKeyFunction, boolean reverse, @Nonnull Function<byte[],RecordCursor<T>> left, @Nonnull Function<byte[],RecordCursor<T>> right, @Nullable byte[] byteContinuation, @Nullable FDBStoreTimer timer)
Create a union cursor from two compatibly-ordered cursors. This cursor is identical to the cursor that would be produced by calling the overload ofcreate()
that takes a list of cursors.- Type Parameters:
T
- the type of elements returned by the cursor- Parameters:
comparisonKeyFunction
- the function expression used to compare elements from different cursorsreverse
- whether records are returned in descending or ascending order by the comparison keyleft
- a function to produce the firstRecordCursor
from a continuationright
- a function to produce the secondRecordCursor
from a continuationbyteContinuation
- any continuation from a previous scantimer
- the timer used to instrument events- Returns:
- a cursor containing all elements in both child cursors
-
create
@Nonnull public static <M extends Message,S extends FDBRecord<M>> UnionCursor<S> create(@Nonnull FDBRecordStoreBase<M> store, @Nonnull KeyExpression comparisonKey, boolean reverse, @Nonnull List<Function<byte[],RecordCursor<S>>> cursorFunctions, @Nullable byte[] continuation)
Create a union cursor from two or more compatibly-ordered cursors. As its comparison key function, it will evaluate the provided comparison key on each record from each cursor. This otherwise behaves exactly the same way as the overload of this function that takes a function to extract a comparison key.- Type Parameters:
M
- the type of the Protobuf record elements of the cursorS
- the type of record wrapping a record of typeM
- Parameters:
store
- record store from which records will be fetchedcomparisonKey
- the key expression used to compare records from different cursorsreverse
- whether records are returned in descending or ascending order by the comparison keycursorFunctions
- a list of functions to produceRecordCursor
s from a continuationcontinuation
- any continuation from a previous scan- Returns:
- a cursor containing any records in any child cursors
- See Also:
create(Function, boolean, List, byte[], FDBStoreTimer)
-
create
@Nonnull public static <T> UnionCursor<T> create(@Nonnull Function<? super T,? extends List<Object>> comparisonKeyFunction, boolean reverse, @Nonnull List<Function<byte[],RecordCursor<T>>> cursorFunctions, @Nullable byte[] byteContinuation, @Nullable FDBStoreTimer timer)
Create a union 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 any records that appear in any of the provided cursors, preserving order. All cursors must return records in the same order, and that order should be determined by the comparison key function, i.e., ifreverse
isfalse
, then the records should be returned in ascending order by that key, and ifreverse
istrue
, they should be returned in descending order. Additionally, if the comparison key function evaluates to the same value when applied to two records (possibly from different cursors), then those two elements should be equal. In other words, the value of the comparison key should be the only necessary data that need to be extracted from each element returned by the child cursors to perform the union. Additionally, the provided comparison key function should not have any side-effects and should produce the same output every time it is applied to the same input.The cursors are provided as a list of functions rather than a list of
RecordCursor
s. These functions should create a newRecordCursor
instance with a given continuation appropriate for that cursor type. The value of that continuation will be determined by this function from thecontinuation
parameter for the union cursor as a whole.- Type Parameters:
T
- the type of elements returned by this cursor- Parameters:
comparisonKeyFunction
- the function evaluated to compare elements from different cursorsreverse
- whether records are returned in descending or ascending order by the comparison keycursorFunctions
- a list of functions to produceRecordCursor
s from a continuationbyteContinuation
- any continuation from a previous scantimer
- the timer used to instrument events- Returns:
- a cursor containing any records in any child cursors
-
getContinuationObject
@Nonnull protected com.apple.foundationdb.record.provider.foundationdb.cursors.UnionCursorContinuation getContinuationObject()
Description copied from class:MergeCursor
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 callingMergeCursor.getChildContinuations()
. This will only be called afterMergeCursor.computeNextResultStates()
has completed.- Specified by:
getContinuationObject
in classMergeCursor<T,T,S extends MergeCursorState<T>>
- Returns:
- a
RecordCursorContinuation
for this cursor based on the state of its child cursors
-
getNextResult
@Nonnull protected T getNextResult(@Nonnull List<S> chosenStates)
Get the result from the list of chosen states. These states have all been identified as equivalent from the point of view of the union, so only one element should be returned from all of them. Implementations may choose to combine the results from the various child results if that is useful.- Specified by:
getNextResult
in classMergeCursor<T,T,S extends MergeCursorState<T>>
- Parameters:
chosenStates
- the states that contain the next value to return- Returns:
- the result to return from this cursor given these elements appear in the union
-
mergeNoNextReasons
@Nonnull protected RecordCursor.NoNextReason mergeNoNextReasons()
Merges all of the cursors and whether they have stopped and returns the "strongest" reason for the result to stop. It will return an out-of-band reason if any of the children stopped for an out-of-band reason, and it will only returnSOURCE_EXHAUSTED
if all of the cursors are exhausted.- Specified by:
mergeNoNextReasons
in classMergeCursor<T,T,S extends MergeCursorState<T>>
- Returns:
- the strongest reason for stopping
-
-