回答this question,Odomontois展示了如何实现一个懒惰的group-by运算符,它可以通过键对预先排序的流进行分组,而无需将整个内容存储在内存中。有没有办法用Akka的流(即Source对象)做这样的事情?或者,有没有办法从Akka Source中提取常规的Stream对象,这样我就可以使用Odomontois的chopBy?
这是完全失败的尝试做到这一点并不起作用:
implicit class SourceChopOps[T, NU](s: Source[T, NU]) {
def chopBy[U](f: T => U) = {
s.prefixAndTail(1)
.map(pt => (pt._1.head, pt._2))
.map {
case (prefix, tail) =>
// what to do with pulled off head???
tail.takeWhile(e => f(e) == f(prefix)) ++ tail.dropWhile(e => f(e) == f(prefix)).chopBy(f) // fails here
}
}
}
}
答案 0 :(得分:0)
groupBy
将保留您在内存中分组的密钥,但是流区域总是“懒惰”,因为它们具有反压,因此它将在有限的内存中运行。如果下游不接受新元素,则不会在上游生成新元素。
例如:
case class Record(id: Int)
Source.fromIterator(() =>
Iterator
.fill(1000)(Iterator(1,2).map { n => println("creating"); Record(n) })
.flatten)
.groupBy(maxSubstreams = 2, _.id)
.map { r => println("Consuming"); r }
.fold(0)((acc, _) => acc + 1)
.mergeSubstreams
.runForeach(println)
将向您展示如何生成Record
个实例的速度,因为它们可以在两个子流中的每一个中消耗,而不是预先全部消耗。