-
Couldn't load subscription status.
- Fork 1.4k
Add ZStream.mapZIOChunked
#9697
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5bae6ea
83fa3bb
483b24f
6a7b889
017239b
ecdb5ca
a785f17
fa76682
8a837bb
ef680b7
560c438
29a3bb9
16ded37
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -482,6 +482,25 @@ final class ZPipeline[-Env, +Err, -In, +Out] private ( | |
| )(implicit trace: Trace): ZPipeline[Env2, Err2, In, Out2] = | ||
| self >>> ZPipeline.mapZIO(f) | ||
|
|
||
| /** | ||
| * Creates a pipeline that maps over elements of the stream with the specified | ||
| * effectful function. | ||
| * | ||
| * Unlike `mapZIO` processing is done chunk by chunk. This means that | ||
| * `mapZIOChunked` provides weaker guarantees than `mapZIO`. While | ||
| * `stream.mapZIO(f).mapZIO(g)` is guaranteed to be equivalent to | ||
| * `stream.mapZIO(x => f(x).flatMap(g))`, the same is not true for | ||
| * `mapZIOChunked`. For example, `mapZIO` guarantees that the first element of | ||
| * a stream will first be processed with `f` and then `g` before the second | ||
| * element is processed with `f`. `mapZIOChunked` may process the first two | ||
| * elements with `f` and only then move on to process the first element with | ||
| * `g`. | ||
| */ | ||
| def mapZIOChunked[Env2 <: Env, Err2 >: Err, Out2]( | ||
| f: Out => ZIO[Env2, Err2, Out2] | ||
| )(implicit trace: Trace): ZPipeline[Env2, Err2, In, Out2] = | ||
| self >>> ZPipeline.mapZIOChunked(f) | ||
|
|
||
| /** | ||
| * Maps over elements of the stream with the specified effectful function, | ||
| * executing up to `n` invocations of `f` concurrently. Transformed elements | ||
|
|
@@ -1798,6 +1817,49 @@ object ZPipeline extends ZPipelinePlatformSpecificConstructors { | |
| new ZPipeline(loop(Chunk.ChunkIterator.empty, 0)) | ||
| } | ||
|
|
||
| /** | ||
| * Creates a pipeline that maps over elements of the stream with the specified | ||
| * effectful function. | ||
| * | ||
| * Unlike `mapZIO` processing is done chunk by chunk. This means that | ||
| * `mapZIOChunked` provides weaker guarantees than `mapZIO`. While | ||
| * `stream.mapZIO(f).mapZIO(g)` is guaranteed to be equivalent to | ||
| * `stream.mapZIO(x => f(x).flatMap(g))`, the same is not true for | ||
| * `mapZIOChunked`. For example, `mapZIO` guarantees that the first element of | ||
| * a stream will first be processed with `f` and then `g` before the second | ||
| * element is processed with `f`. `mapZIOChunked` may process the first two | ||
| * elements with `f` and only then move on to process the first element with | ||
| * `g`. | ||
| */ | ||
| def mapZIOChunked[Env, Err, In, Out]( | ||
| f: In => ZIO[Env, Err, Out] | ||
| )(implicit trace: Trace): ZPipeline[Env, Err, In, Out] = { | ||
| def writeWithNext( | ||
| builder: ChunkBuilder[Out], | ||
| next: ZChannel[Env, Err, Chunk[In], Any, Err, Chunk[Out], Any] | ||
| ): ZChannel[Env, Err, Chunk[In], Any, Err, Chunk[Out], Any] = { | ||
| val out = builder.result() | ||
| if (out.nonEmpty) ZChannel.write(out) *> next else next | ||
| } | ||
|
|
||
| lazy val reader: ZChannel[Env, Err, Chunk[In], Any, Err, Chunk[Out], Any] = | ||
| ZChannel.readWithCause( | ||
| chunk => | ||
| ZChannel.unwrap { | ||
| val builder = ChunkBuilder.make[Out](chunk.size) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As a side-note: I wonder if we could reuse the ChunkBuilder after calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I looked into this a bit and I think it is not going to help. The thing is, as long as the stream is not failing or ending, we give the chunk builder a 'sizeHint' that is spot-on; the backing array will be filled to exactlty that size. You should know that if the |
||
| chunk | ||
| .mapZIODiscard(f(_).map(builder += _)) | ||
| .foldCause( | ||
| cause => writeWithNext(builder, ZChannel.refailCause(cause)), | ||
| _ => writeWithNext(builder, reader) | ||
| ) | ||
| }, | ||
| err => ZChannel.refailCause(err), | ||
| done => ZChannel.succeed(done) | ||
| ) | ||
| new ZPipeline(reader) | ||
| } | ||
|
|
||
| /** | ||
| * Maps over elements of the stream with the specified effectful function, | ||
| * executing up to `n` invocations of `f` concurrently. Transformed elements | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.