私のコードには共通のパターンがあります。データベースからの結果を並べ替えましたが、ネストされた構造でそれらを出力する必要があります。これをストリーミングしたいので、一度にメモリに保持するレコードをできるだけ少なくしたいと考えています。TravesableLike.groupBy を使用すると、データがソートされていないと想定されるため、変更可能なマップが不必要に埋められます。これを真にストリーミングし続けたいと思います。ここで scalaz-stream は役に立ちますか?
val sql = """select grandparent_id, parent_id, child_id
from children
where grandparent_id = ?
order by grandparent_id, parent_id, child_id"""
def elementsR[P, R](invoker: Invoker[P, R], param: P): Process[Task, R] =
// Invoker.elements returns trait CloseableIterator[+T] extends Iterator[T] with Closeable
resource(Task.delay(invoker.elements(param)))(
src => Task.delay(src.close)) { src =>
Task.delay { if (src.hasNext) src.next else throw End }
}
def dbWookie {
// grandparent_id, (grandparent_id, parent_id, child_id)
val invoker = Q.query[Int, (Int, Int, Int)](sql)
val es = elementsR(invoker, 42)
// ?, ?, ?
// nested emits (42, ((35, (1, 3, 7)), (36, (8, 9, 12))))
}
プロセスに foldLeft や scanLeft などの関数があまりないので、grandparent_id、parent_id、または child_id の変更を検出してグループを発行する方法がわかりません。何か案は?