-// leafSource returns the text that the leaf of message holds or summarizes.
-func leafSource(message Message) string {
- return message.Kind + ": " + message.Text
-}
-
-// freeLeaf returns the leaf of message when its source fits in a node. Such a
-// leaf holds the source word for word and needs no model call.
-func freeLeaf(message Message) (Node, bool) {
- text := leafSource(message)
- if len(text) > nodeBytes {
- return Node{}, false
- }
-
- return Node{
- Level: 0,
- Index: message.ID,
- Text: text,
- Size: len(text),
- }, true
-}
-
-// freeMerge returns the parent of two sibling nodes when both texts, joined by
-// a newline, fit in a node. Such a parent needs no model call.
-func freeMerge(left, right Node) (Node, bool) {
- if left.Size+1+right.Size > nodeBytes {
- return Node{}, false
- }
-
- text := left.Text + "\n" + right.Text
-
- return Node{
- Level: left.Level + 1,
- Index: left.Index / 2,
- Text: text,
- Size: len(text),
- }, true
-}
-
-// nodeEnd returns the ID after the last message of node (l, i).
-func nodeEnd(level, index int) int {
- return (index + 1) << level
-}
-
-// Tree holds the built nodes of one chat. It writes one JSON line for each node
-// to tree/YYYY-MM-DD.jsonl, named for the local day of the build. Each node is
-// built once and never again. A node of a higher level is built only after both
-// of its children. After a failed write, the tree refuses all writes until it
-// is opened again. The caller holds the lock of the chat and serializes all
-// calls.
-//
-// The tree keeps no node in memory. The index index/tree.idx lists the node
-// lines in file order, and index/tree-L.idx holds the position of node (L, i)
-// in record i, with a zero record for a node that is not built. At open the
-// tree indexes the lines after the last indexed one, so a missing index is
-// built again from the day files.
-type Tree struct {
- clock func() time.Time
- journal Journal
- dir string
- order *Records
- levels map[int]*Records
- failure error
-}
-