viewPending = "(not summarized yet: zoom it)"
)
-// newView returns an empty view with the limits high and low.
-func newView(high, low int) *View {
- return &View{
- high: high,
- low: low,
- nodes: make(map[NodeKey]Node),
- }
-}
-
-// restoreView returns the view of state with the limits high and low. Each line
-// must continue the one before it, and each line above level 0 must be built.
-func restoreView(state ViewState, high, low int, tree ViewNodeReader) (*View, error) {
- v := newView(high, low)
- v.merging = state.Merging
- for _, pair := range state.Lines {
- line := NodeKey{pair[0], pair[1]}
- if line.level < 0 || line.level >= bits.UintSize-2 || line.index < 0 || line.index<<line.level != v.end {
- return nil, fmt.Errorf("view line (%d, %d) does not start at message %d", line.level, line.index, v.end)
- }
-
- built, err := v.load(tree, line)
- if err != nil {
- return nil, err
- }
-
- if line.level > 0 && !built {
- return nil, fmt.Errorf("view line (%d, %d) is not built", line.level, line.index)
- }
-
- v.lines = append(v.lines, line)
- v.end = nodeEnd(line.level, line.index)
- }
-
- return v, nil
-}
-
// View is a list of tree nodes that covers messages 0 to end-1 without a gap,
// oldest first. Each new message appends its leaf as a line. Once the size of
// the view goes above high, one batch merges the most due sibling pairs until
merging bool
}
+// ViewState is the saved form of a View. The limits are not part of it.
+type ViewState struct {
+ Lines [][2]int `json:"lines"`
+ Merging bool `json:"merging"`
+}
+
+// ViewNodeReader gives the built nodes of a tree.
+type ViewNodeReader interface {
+ Built(level, index int) (bool, error)
+ Node(level, index int) (Node, bool, error)
+}
+
+// newView returns an empty view with the limits high and low.
+func newView(high, low int) *View {
+ return &View{
+ high: high,
+ low: low,
+ nodes: make(map[NodeKey]Node),
+ }
+}
+
// State returns the saved form of the view.
func (v *View) State() ViewState {
state := ViewState{
}
var text strings.Builder
+
v.renderLine(&text, line)
+
lines = append(lines, text.String())
}
// sees a pending mark or a part of a message.
func (v *View) Context(end int) string {
var text strings.Builder
+
text.WriteString("<chat>\n")
+
for _, line := range v.lines {
_, built := v.nodes[line]
if !built || nodeEnd(line.level, line.index) > end {
size += v.lineSize(parent) - v.lineSize(left) - v.lineSize(right)
delete(v.nodes, left)
delete(v.nodes, right)
+
v.lines[best] = parent
v.lines = append(v.lines[:best+1], v.lines[best+2:]...)
merged = true
built, err := tree.Built(left.level+1, left.index/2)
if err != nil {
- return -1, err
+ return -1, fmt.Errorf("check parent node: %w", err)
}
if built {
return node.Size
}
-// ViewState is the saved form of a View. The limits are not part of it.
-type ViewState struct {
- Lines [][2]int `json:"lines"`
- Merging bool `json:"merging"`
-}
+// restoreView returns the view of state with the limits high and low. Each line
+// must continue the one before it, and each line above level 0 must be built.
+func restoreView(state ViewState, high, low int, tree ViewNodeReader) (*View, error) {
+ v := newView(high, low)
+ v.merging = state.Merging
+ for _, pair := range state.Lines {
+ line := NodeKey{pair[0], pair[1]}
+ if line.level < 0 || line.level >= bits.UintSize-2 || line.index < 0 || line.index<<line.level != v.end {
+ return nil, fmt.Errorf("view line (%d, %d) does not start at message %d", line.level, line.index, v.end)
+ }
-// ViewNodeReader gives the built nodes of a tree.
-type ViewNodeReader interface {
- Built(level, index int) (bool, error)
- Node(level, index int) (Node, bool, error)
+ built, err := v.load(tree, line)
+ if err != nil {
+ return nil, err
+ }
+
+ if line.level > 0 && !built {
+ return nil, fmt.Errorf("view line (%d, %d) is not built", line.level, line.index)
+ }
+
+ v.lines = append(v.lines, line)
+ v.end = nodeEnd(line.level, line.index)
+ }
+
+ return v, nil
}