@@ -568,55 +568,24 @@ final class Stream[+F[_], +O] private[fs2] (private[fs2] val underlying: Pull[F,
568
568
Stream .eval(fstream)
569
569
}
570
570
571
- def conflate [F2 [x] >: F [x], O2 >: O ](implicit
572
- F : Concurrent [F2 ],
573
- O : Semigroup [O2 ]
574
- ): Stream [F2 , O2 ] =
575
- conflateWithSeed[F2 , O2 ](identity)((s, o) => O .combine(s, o))
571
+ def conflateChunks [F2 [x] >: F [x]: Concurrent ](chunkLimit : Int ): Stream [F2 , Chunk [O ]] =
572
+ Stream .eval(Channel .bounded[F2 , Chunk [O ]](chunkLimit)).flatMap { chan =>
573
+ val producer = chunks.through(chan.sendAll)
574
+ val consumer = chan.stream.underlying.unconsFlatMap(chunks => Pull .output1(chunks.iterator.reduce(_ ++ _))).stream
575
+ consumer.concurrently(producer)
576
+ }
576
577
577
- def conflateWithSeed [F2 [x] >: F [x], S ](
578
- seed : O => S
579
- )(aggregate : (S , O ) => S )(implicit F : Concurrent [F2 ]): Stream [F2 , S ] = {
578
+ def conflate [F2 [x] >: F [x]: Concurrent , O2 ](chunkLimit : Int , zero : O2 )(f : (O2 , O ) => O2 ): Stream [F2 , O2 ] =
579
+ conflateChunks[F2 ](chunkLimit).map(_.foldLeft(zero)(f))
580
580
581
- sealed trait State
582
- case object Closed extends State
583
- case object Quiet extends State
584
- case class Accumulating (value : S ) extends State
585
- case class Awaiting (waiter : Deferred [F2 , S ]) extends State
586
-
587
- Stream .eval(F .ref(Quiet : State )).flatMap { ref =>
588
- val producer = foreach { o =>
589
- ref.flatModify {
590
- case Closed =>
591
- (Closed , F .unit)
592
- case Quiet =>
593
- (Accumulating (seed(o)), F .unit)
594
- case Accumulating (acc) =>
595
- (Accumulating (aggregate(acc, o)), F .unit)
596
- case Awaiting (waiter) =>
597
- (Quiet , waiter.complete(seed(o)).void)
598
- }
599
- }
581
+ def conflate1 [F2 [x] >: F [x]: Concurrent , O2 >: O ](chunkLimit : Int )(f : (O2 , O2 ) => O2 ): Stream [F2 , O2 ] =
582
+ conflateChunks[F2 ](chunkLimit).map(c => c.drop(1 ).foldLeft(c(0 ): O2 )((x, y) => f(x, y)))
600
583
601
- def consumerLoop : Pull [F2 , S , Unit ] =
602
- Pull .eval {
603
- F .deferred[S ].flatMap { waiter =>
604
- ref.modify {
605
- case Closed =>
606
- (Closed , Pull .done)
607
- case Quiet =>
608
- (Awaiting (waiter), Pull .eval(waiter.get).flatMap(Pull .output1) >> consumerLoop)
609
- case Accumulating (s) =>
610
- (Quiet , Pull .output1(s) >> consumerLoop)
611
- case Awaiting (_) =>
612
- sys.error(" Impossible" )
613
- }
614
- }
615
- }.flatten
584
+ def conflateSemigroup [F2 [x] >: F [x]: Concurrent , O2 >: O : Semigroup ](chunkLimit : Int ): Stream [F2 , O2 ] =
585
+ conflate1[F2 , O2 ](chunkLimit)(Semigroup [O2 ].combine)
616
586
617
- consumerLoop.stream.concurrently(producer)
618
- }
619
- }
587
+ def conflateMap [F2 [x] >: F [x]: Concurrent , O2 : Semigroup ](chunkLimit : Int )(f : O => O2 ): Stream [F2 , O2 ] =
588
+ map(f).conflateSemigroup[F2 , O2 ](chunkLimit)
620
589
621
590
/** Prepends a chunk onto the front of this stream.
622
591
*
@@ -2448,10 +2417,9 @@ final class Stream[+F[_], +O] private[fs2] (private[fs2] val underlying: Pull[F,
2448
2417
Stream .eval(Channel .bounded[F2 , Chunk [O ]](n)).flatMap { chan =>
2449
2418
chan.stream.unchunks.concurrently {
2450
2419
chunks.through(chan.sendAll)
2451
-
2452
2420
}
2453
2421
}
2454
-
2422
+
2455
2423
/** Prints each element of this stream to standard out, converting each element to a `String` via `Show`. */
2456
2424
def printlns [F2 [x] >: F [x], O2 >: O ](implicit
2457
2425
F : Console [F2 ],
0 commit comments