+
+ return merged, nil
+}
+
+// Coarsen takes each merge of other, a view of the same messages, and then
+// merges in one batch until the size is at most low. Each line of the result is
+// the coarser of the two lines that start at its first message. Dyadic ranges
+// either nest or do not overlap, so the result covers the messages without a
+// gap.
+func (v *View) Coarsen(other *View, tree nodeReader) error {
+ lines := make([]nodeKey, 0, len(v.lines))
+ nodes := make(map[nodeKey]Node, len(v.nodes))
+ mine, theirs := 0, 0
+ for start := 0; start < v.end; {
+ line := v.lines[mine]
+ node, built := v.nodes[line]
+ if other.lines[theirs].level > line.level {
+ line = other.lines[theirs]
+ node, built = other.nodes[line]
+ }
+
+ lines = append(lines, line)
+ if built {
+ nodes[line] = node
+ }
+
+ start = nodeEnd(line.level, line.index)
+ for mine < len(v.lines) && v.lines[mine].index<<v.lines[mine].level < start {
+ mine++
+ }
+
+ for theirs < len(other.lines) && other.lines[theirs].index<<other.lines[theirs].level < start {
+ theirs++
+ }
+ }
+
+ v.lines = lines
+ v.nodes = nodes
+ v.merging = true
+ _, err := v.fit(tree)
+
+ return err