Interface RecordCursor<T>
-
- Type Parameters:
T
- the type of elements of the cursor
- All Superinterfaces:
AutoCloseable
,Iterator<T>
- All Known Subinterfaces:
BaseCursor<T>
- All Known Implementing Classes:
AsyncIteratorCursor
,AutoContinuingCursor
,ChainedCursor
,ConcatCursor
,EmptyCursor
,FilterCursor
,FlatMapPipelinedCursor
,FutureCursor
,IntersectionCursor
,IntersectionMultiCursor
,IteratorCursor
,KeyValueCursor
,LazyCursor
,ListCursor
,MapCursor
,MapPipelinedCursor
,MapWhileCursor
,MergeCursor
,OrElseCursor
,ProbableIntersectionCursor
,RowLimitedCursor
,SizeStatisticsCollectorCursor
,SkipCursor
,SplitHelper.KeyValueUnsplitter
,UnionCursor
,UnorderedUnionCursor
@API(STABLE) public interface RecordCursor<T> extends AutoCloseable, Iterator<T>
An asynchronous iterator that supports continuations. Much like anIterator
, aRecordCursor
provides one-item-at-a-time access to an ordered collection. It differs in three primary respects:-
A
RecordCursor
is asynchronous. Instead of the synchronousIterator.hasNext()
andIterator.next()
methods,RecordCursor
advances the iteration using the asynchronousonNext()
method, which returns aCompletableFuture
. -
RecordCursor
supports continuations, which are opaque tokens that represent the position of the cursor between records. Continuations can be used to restart the iteration at the same point later. Continuations represent all of the state needed to do this restart, even if the original objects no longer exist. -
Finally,
RecordCursor
's API offers correctness by construction. In contrast to thehasNext()
/next()
API used byIterator
,RecordCursor
's primary API isonNext()
which produces the next value if one is present, or an object indicating that there is no such record. The presence of a next value is instead indicated byRecordCursorResult.hasNext()
. This API serves to bundle a continuation (and possible aRecordCursor.NoNextReason
) with the result, ensuring that a continuation is obtained only when it is valid. For compatibility withIterator
,RecordCursor
also supportsonHasNext()
andnext()
, but continuations must be used carefully with this API, as described below.
RecordCursor
supportsgetContinuation()
for use with theIterator
-style API. A cursor is between records and valid for getting its continuation after callingnext()
or afterhasNext()
returnsfalse
.When a cursor stops producing values, it can report why using a
RecordCursor.NoNextReason
. This can be returned as part of aRecordCursorResult
if using theonNext()
API or usinggetNoNextReason()
if using theIterator
-style API. No-next-reasons are fundamentally distinguished between those that are due to the data itself (in-band) and those that are due to the environment / context (out-of-band). For example, running out of data or having returned the maximum number of records requested are in-band, while reaching a limit on the number of key-value pairs scanned by the transaction or the time that a transaction has been open are out-of-band.
-
-
Nested Class Summary
Nested Classes Modifier and Type Interface Description static class
RecordCursor.NoNextReason
The reason thathasNext()
returnedfalse
.
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Default Methods Deprecated Methods Modifier and Type Method Description boolean
accept(RecordCursorVisitor visitor)
Accept a visit from hierarchical visitor, which implementsRecordCursorVisitor
.default RecordCursorIterator<T>
asIterator()
Return a view of this cursor as aRecordCursorIterator
.default CompletableFuture<List<T>>
asList()
Return the entire stream of records as an asynchronous list.void
close()
static <T> RecordCursor<T>
empty()
Get a new cursor that does not return any records.static <T> RecordCursor<T>
empty(Executor executor)
default RecordCursor<T>
filter(Function<T,Boolean> pred)
Get a new cursor that skips records that do not satisfy the given predicate.default RecordCursor<T>
filterAsync(Function<T,CompletableFuture<Boolean>> pred, int pipelineSize)
Get a new cursor that skips records that do not satisfy the given asynchronous predicate.default RecordCursor<T>
filterAsyncInstrumented(Function<T,CompletableFuture<Boolean>> pred, int pipelineSize, StoreTimer timer, StoreTimer.Count in, StoreTimer.Event during, StoreTimer.Count success, StoreTimer.Count failure)
default RecordCursor<T>
filterAsyncInstrumented(Function<T,CompletableFuture<Boolean>> pred, int pipelineSize, StoreTimer timer, Set<StoreTimer.Count> inSet, Set<StoreTimer.Event> duringSet, Set<StoreTimer.Count> successSet, 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.default RecordCursor<T>
filterInstrumented(Function<T,Boolean> pred, StoreTimer timer, StoreTimer.Count in, StoreTimer.Event during, StoreTimer.Count success, StoreTimer.Count failure)
default RecordCursor<T>
filterInstrumented(Function<T,Boolean> pred, StoreTimer timer, Set<StoreTimer.Count> inSet, Set<StoreTimer.Event> duringSet, Set<StoreTimer.Count> successSet, 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.default CompletableFuture<Optional<T>>
first()
Fetches the first item returned by the cursor.static <T,V>
RecordCursor<V>flatMapPipelined(Function<byte[],? extends RecordCursor<T>> outerFunc, BiFunction<T,byte[],? extends RecordCursor<V>> innerFunc, byte[] continuation, int pipelineSize)
static <T,V>
RecordCursor<V>flatMapPipelined(Function<byte[],? extends RecordCursor<T>> outerFunc, BiFunction<T,byte[],? extends RecordCursor<V>> innerFunc, Function<T,byte[]> checker, byte[] continuation, int pipelineSize)
Resume a nested cursor with the given continuation or start ifnull
.default <V> RecordCursor<V>
flatMapPipelined(Function<T,? extends RecordCursor<V>> func, int pipelineSize)
Deprecated.because it does not support continuations and is easy to misuse.default CompletableFuture<Void>
forEach(Consumer<T> consumer)
Call the given consumer as each record becomes available.default CompletableFuture<Void>
forEachAsync(Function<T,CompletableFuture<Void>> func, int pipelineSize)
Call the function as each record becomes available.default CompletableFuture<RecordCursorResult<T>>
forEachResult(Consumer<RecordCursorResult<T>> consumer)
Call the given consumer as each record result becomes available.default CompletableFuture<RecordCursorResult<T>>
forEachResultAsync(Function<RecordCursorResult<T>,CompletableFuture<Void>> func)
Call the function as each record result becomes available.static <T> RecordCursor<T>
fromFuture(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.static <T> RecordCursor<T>
fromFuture(Executor executor, CompletableFuture<T> future)
static <T> RecordCursor<T>
fromFuture(Executor executor, CompletableFuture<T> future, byte[] continuation)
Get a new cursor that has the contents of the given future as its only record.static <T> RecordCursor<T>
fromIterator(Executor executor, Iterator<T> iterator)
static <T> RecordCursor<T>
fromIterator(Iterator<T> iterator)
Get a new cursor from an ordinaryIterator
.static <T> RecordCursor<T>
fromList(Executor executor, List<T> list)
static <T> RecordCursor<T>
fromList(Executor executor, List<T> list, byte[] continuation)
static <T> RecordCursor<T>
fromList(List<T> list)
Get a new cursor from an ordinaryList
.static <T> RecordCursor<T>
fromList(List<T> list, byte[] continuation)
Get a new cursor from an ordinaryList
, skipping ahead according to the given continuation.byte[]
getContinuation()
Deprecated.in favor of theonNext()
method or advancing the cursorasIterator()
default CompletableFuture<Integer>
getCount()
Count the number of records remaining.Executor
getExecutor()
default RecordCursorResult<T>
getNext()
Get the next result from this cursor.RecordCursor.NoNextReason
getNoNextReason()
Deprecated.in favor of theonNext()
method or advancing the cursorasIterator()
default boolean
hasNext()
Deprecated.in favor of theonNext()
method or advancing the cursorasIterator()
default RecordCursor<T>
limitRowsTo(int limit)
Get a new cursor that will only return records up to the given limit.default RecordCursor<T>
limitTo(int limit)
Deprecated.UselimitRowsTo(int)
instead.default <V> RecordCursor<V>
map(Function<T,V> func)
Get a new cursor by applying the given function to the records in this cursor.default RecordCursor<T>
mapEffect(Runnable runnable)
Get a new cursor that runs the given runnable every time a record arrives, without modifying the cursor records.default RecordCursor<T>
mapEffect(Consumer<T> consumer)
Get a new cursor that applies the given consumer to the records in this cursor, without modifying the cursor records.static <T,V>
RecordCursor<T>mapFuture(Executor executor, CompletableFuture<V> future, byte[] continuation, 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.default <V> RecordCursor<V>
mapPipelined(Function<T,CompletableFuture<V>> func, int pipelineSize)
Get a new cursor by applying the given asynchronous function to the records in this cursor.T
next()
Deprecated.in favor of theonNext()
method or advancing the cursorasIterator()
CompletableFuture<Boolean>
onHasNext()
Deprecated.in favor of theonNext()
method or advancing the cursorasIterator()
CompletableFuture<RecordCursorResult<T>>
onNext()
Asynchronously return the next result from this cursor.static <T> RecordCursor<T>
orElse(Function<byte[],? extends RecordCursor<T>> innerFunc, BiFunction<Executor,byte[],? extends RecordCursor<T>> elseFunc, byte[] continuation)
Get a new cursor that substitutes another cursor if a given inner cursor is empty.default RecordCursor<T>
orElse(Function<Executor,RecordCursor<T>> func)
Deprecated.because it does not support continuations and is easy to misuse.default <U> CompletableFuture<U>
reduce(U identity, BiFunction<U,? super T,U> accumulator)
Reduce contents of cursor to single value.default RecordCursor<T>
skip(int skip)
Get a new cursor that skips the given number of records.default RecordCursor<T>
skipThenLimit(int skip, int limit)
-
Methods inherited from interface java.util.Iterator
forEachRemaining, remove
-
-
-
-
Method Detail
-
onHasNext
@API(DEPRECATED) @Deprecated @Nonnull CompletableFuture<Boolean> onHasNext()
Deprecated.in favor of theonNext()
method or advancing the cursorasIterator()
Asynchronously check whether there are more records available from the cursor.- Returns:
- a future that when complete will hold
true
ifnext()
would return a record. - See Also:
AsyncIterator.onHasNext()
-
hasNext
@API(DEPRECATED) @Deprecated default boolean hasNext()
Deprecated.in favor of theonNext()
method or advancing the cursorasIterator()
Synchronously check whether there are more records available from the cursor.
-
next
@API(DEPRECATED) @Deprecated @Nullable T next()
Deprecated.in favor of theonNext()
method or advancing the cursorasIterator()
Return the next value.
-
getContinuation
@API(DEPRECATED) @Deprecated @Nullable byte[] getContinuation()
Deprecated.in favor of theonNext()
method or advancing the cursorasIterator()
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 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
@API(DEPRECATED) @Nonnull @Deprecated RecordCursor.NoNextReason getNoNextReason()
Deprecated.in favor of theonNext()
method or advancing the cursorasIterator()
Get the reason that the cursor has reached the end and returnedfalse
forhasNext()
. IfhasNext
was not called or returnedtrue
last time, the result is undefined and may be an exception.- Returns:
- the reason that the cursor stopped
-
onNext
@Nonnull CompletableFuture<RecordCursorResult<T>> onNext()
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.- 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
-
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
-
asIterator
@Nonnull @API(STABLE) default RecordCursorIterator<T> asIterator()
Return a view of this cursor as aRecordCursorIterator
. This allows the cursor to be consumed by methods that takeIterator
s orAsyncIterator
s.- Returns:
- a view of this cursor as an
RecordCursorIterator
-
close
void close()
- Specified by:
close
in interfaceAutoCloseable
-
accept
boolean accept(@Nonnull RecordCursorVisitor visitor)
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.- Parameters:
visitor
- a hierarchical visitor- Returns:
true
if the subsequent siblings of thecursor
should be visited, andfalse
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 anOptional
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
returnsfalse
-
filterInstrumented
@Nonnull default RecordCursor<T> filterInstrumented(@Nonnull Function<T,Boolean> pred, @Nullable StoreTimer timer, @Nullable StoreTimer.Count in, @Nullable StoreTimer.Event during, @Nullable StoreTimer.Count success, @Nullable StoreTimer.Count failure)
-
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 ontimer
- a StoreTimer to log the counts and eventsinSet
- a set StoreTimer.Count that will be incremented for each record the filter seesduringSet
- a set of StoreTimer.Event that will log the time spent computing the predicatesuccessSet
- a set of StoreTimer.Count that will be increment for each record on which the predicate evaluatestrue
failureSet
- a set of StoreTimer.Count that will be increment for each record on which the predicate evaluatesfalse
- Returns:
- a new cursor that skips records for which
pred
returnsfalse
-
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.UselimitRowsTo(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
-
skipThenLimit
@Nonnull default RecordCursor<T> skipThenLimit(int skip, int limit)
-
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 recordpipelineSize
- 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. UseflatMapPipelined(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 recordpipelineSize
- 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 byte[] continuation, int pipelineSize)
-
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 ifnull
.- Type Parameters:
T
- the result type of the outer cursorV
- 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 ornull
. When computing the continuation, this is called on the current outer record and the result, if notnull
, 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 ornull
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 applypipelineSize
- 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 tofalse
-
filterAsyncInstrumented
@Nonnull default RecordCursor<T> filterAsyncInstrumented(@Nonnull Function<T,CompletableFuture<Boolean>> pred, int pipelineSize, @Nullable StoreTimer timer, @Nullable StoreTimer.Count in, @Nullable StoreTimer.Event during, @Nullable StoreTimer.Count success, @Nullable StoreTimer.Count failure)
-
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 onpipelineSize
- the number of futures from applications of the predicate to start ahead of timetimer
- a StoreTimer to log the counts and eventsinSet
- a set StoreTimer.Count that will be incremented for each record the filter seesduringSet
- a set of StoreTimer.Event that will log the time spent computing the predicatesuccessSet
- a set of StoreTimer.Count that will be increment for each record on which the predicate evaluatestrue
failureSet
- a set of StoreTimer.Count that will be increment for each record on which the predicate evaluatesfalse
- Returns:
- a new cursor that filters out records for which
pred
returned a future that completed tofalse
-
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., callinghasNext()
on the result will returntrue
. The returned future will then contain the first result that does not have an associated value, i.e.,hasNext()
on the result will returnfalse
. 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 recordpipelineSize
- 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., callinghasNext()
on the result will returntrue
. The return future will then contain the first result that does not have an associated value, i.e.,hasNext()
on the result will returnfalse
. 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
@API(DEPRECATED) @Deprecated @Nonnull default RecordCursor<T> orElse(@Nonnull Function<Executor,RecordCursor<T>> func)
Deprecated.because it does not support continuations and is easy to misuse. UseflatMapPipelined(Function, BiFunction, byte[], int)
instead.Get a new cursor that substitutes another cursor if this cursor is empty.- Parameters:
func
- function to be called if the cursor is empty to give another source of records- Returns:
- a new cursor that returns the same records as this cursor
or the result of
func
if this cursor does not produce any 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 cursorelseFunc
- a function to be called if the cursor is empty to give another source of recordscontinuation
- 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 ordinaryIterator
.- Type Parameters:
T
- the type of elements ofiterator
- Parameters:
iterator
- the iterator of records- Returns:
- a new cursor that produces the elements of the given iterator
-
fromIterator
@Nonnull static <T> RecordCursor<T> fromIterator(@Nonnull Executor executor, @Nonnull Iterator<T> iterator)
-
fromList
@Nonnull static <T> RecordCursor<T> fromList(@Nonnull List<T> list)
Get a new cursor from an ordinaryList
.- Type Parameters:
T
- the type of elements oflist
- Parameters:
list
- the list of records- Returns:
- a new cursor that produces the items of
list
-
fromList
@Nonnull static <T> RecordCursor<T> fromList(@Nonnull Executor executor, @Nonnull List<T> list)
-
fromList
@Nonnull static <T> RecordCursor<T> fromList(@Nonnull List<T> list, @Nullable byte[] continuation)
Get a new cursor from an ordinaryList
, skipping ahead according to the given continuation.- Type Parameters:
T
- the type of elements oflist
- Parameters:
list
- the list of recordscontinuation
- the result ofgetContinuation()
from an earlier list cursor.- Returns:
- a new cursor that produces the items of
list
, resuming ifcontinuation
is notnull
-
fromList
@Nonnull static <T> RecordCursor<T> fromList(@Nonnull Executor executor, @Nonnull List<T> list, @Nullable byte[] continuation)
-
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)
-
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 aFutureCursor
returns only a single record.- Type Parameters:
T
- the result type of the future- Parameters:
executor
- an executor for executing the futurefuture
- a future that completes to the only element of the cursorcontinuation
- 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 cursorV
- the return type of the function- Parameters:
executor
- an executor in which to run asynchronous callsfuture
- a future that completes to the argument to the functioncontinuation
- any continuation from a previous invocation of this methodfunction
- a function that takes the contents of the future and a continuation and returns a cursor- Returns:
- a new cursor from applying
function
tofuture
andcontinuation
-
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
-
empty
@Nonnull static <T> RecordCursor<T> empty(@Nonnull Executor executor)
-
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 reductionaccumulator
- 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
-
-