Lazy and fast concat and prepend (#30252)

This commit is contained in:
Johan Andrén 2021-05-27 17:18:47 +02:00 committed by GitHub
parent cbb12e6ef3
commit 4ade8ef2d1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 825 additions and 77 deletions

View file

@ -1470,10 +1470,13 @@ class SubSource[Out, Mat](
* Flows input is exhausted and all result elements have been generated,
* the Sources elements will be produced.
*
* Note that the [[Source]] is materialized together with this Flow and just kept
* from producing elements by asserting back-pressure until its time comes.
* Note that the [[Source]] is materialized together with this Flow and is "detached" meaning it will
* in effect behave as a one element buffer in front of both the sources, that eagerly demands an element on start
* (so it can not be combined with `Source.lazy` to defer materialization of `that`).
*
* If this [[Flow]] gets upstream error - no elements from the given [[Source]] will be pulled.
* The second source is then kept from producing elements by asserting back-pressure until its time comes.
*
* When needing a concat operator that is not detached use [[#concatLazyMat]]
*
* '''Emits when''' element is available from current stream or from the given [[Source]] when current is completed
*
@ -1486,15 +1489,44 @@ class SubSource[Out, Mat](
def concat[M](that: Graph[SourceShape[Out], M]): SubSource[Out, Mat] =
new SubSource(delegate.concat(that))
/**
* Concatenate the given [[Source]] to this [[Flow]], meaning that once this
* Flows input is exhausted and all result elements have been generated,
* the Sources elements will be produced.
*
* Note that the [[Source]] is materialized together with this Flow. If `lazy` materialization is what is needed
* the operator can be combined with for example `Source.lazySource` to defer materialization of `that` until the
* time when this source completes.
*
* The second source is then kept from producing elements by asserting back-pressure until its time comes.
*
* For a concat operator that is detached, use [[#concat]]
*
* If this [[Flow]] gets upstream error - no elements from the given [[Source]] will be pulled.
*
* '''Emits when''' element is available from current stream or from the given [[Source]] when current is completed
*
* '''Backpressures when''' downstream backpressures
*
* '''Completes when''' given [[Source]] completes
*
* '''Cancels when''' downstream cancels
*/
def concatLazy[M](that: Graph[SourceShape[Out], M]): SubSource[Out, Mat] =
new SubSource(delegate.concatLazy(that))
/**
* Prepend the given [[Source]] to this [[Flow]], meaning that before elements
* are generated from this Flow, the Source's elements will be produced until it
* is exhausted, at which point Flow elements will start being produced.
*
* Note that this Flow will be materialized together with the [[Source]] and just kept
* from producing elements by asserting back-pressure until its time comes.
* Note that the [[Source]] is materialized together with this Flow and is "detached" meaning
* in effect behave as a one element buffer in front of both the sources, that eagerly demands an element on start
* (so it can not be combined with `Source.lazy` to defer materialization of `that`).
*
* If the given [[Source]] gets upstream error - no elements from this [[Flow]] will be pulled.
* This flow will then be kept from producing elements by asserting back-pressure until its time comes.
*
* When needing a prepend operator that is not detached use [[#prependLazy]]
*
* '''Emits when''' element is available from the given [[Source]] or from current stream when the [[Source]] is completed
*
@ -1507,6 +1539,29 @@ class SubSource[Out, Mat](
def prepend[M](that: Graph[SourceShape[Out], M]): SubSource[Out, Mat] =
new SubSource(delegate.prepend(that))
/**
* Prepend the given [[Source]] to this [[Flow]], meaning that before elements
* are generated from this Flow, the Source's elements will be produced until it
* is exhausted, at which point Flow elements will start being produced.
*
* Note that the [[Source]] is materialized together with this Flow and will then be kept from producing elements
* by asserting back-pressure until its time comes.
*
* When needing a prepend operator that is also detached use [[#prepend]]
*
* If the given [[Source]] gets upstream error - no elements from this [[Flow]] will be pulled.
*
* '''Emits when''' element is available from the given [[Source]] or from current stream when the [[Source]] is completed
*
* '''Backpressures when''' downstream backpressures
*
* '''Completes when''' this [[Flow]] completes
*
* '''Cancels when''' downstream cancels
*/
def prependLazy[M](that: Graph[SourceShape[Out], M]): SubSource[Out, Mat] =
new SubSource(delegate.prependLazy(that))
/**
* Provides a secondary source that will be consumed if this source completes without any
* elements passing by. As soon as the first element comes through this stream, the alternative