X-Git-Url: https://git.giacomolli.uk/onechat/blobdiff_plain/503486b8364f07ef44c06bcc1be566f62600b0eb..c781f79f3c8cb9a7577ee1574d196988da2719b3:/build_queue.go?ds=sidebyside diff --git a/build_queue.go b/build_queue.go index 2458f5a..540e396 100644 --- a/build_queue.go +++ b/build_queue.go @@ -14,14 +14,6 @@ const ( buildLeafWindow = 8 ) -func newBuildQueue() *BuildQueue { - return &BuildQueue{ - queued: make(map[nodeKey]bool), - running: make(map[nodeKey]bool), - failed: make(map[nodeKey]bool), - } -} - // BuildQueue holds the nodes that wait for a model build. A leaf joins it when // its message is too long to be its own node. A merge joins it when both of its // children are built and their texts do not fit in one node. So the core never @@ -36,10 +28,21 @@ func newBuildQueue() *BuildQueue { type BuildQueue struct { leaves []int merges BuildMergeHeap - queued map[nodeKey]bool - running map[nodeKey]bool - failed map[nodeKey]bool - retry []nodeKey + queued map[NodeKey]bool + running map[NodeKey]bool + failed map[NodeKey]bool + retry []NodeKey +} + +// BuildMergeHeap holds the merges that can start, by the end of their context. +type BuildMergeHeap []NodeKey + +func newBuildQueue() *BuildQueue { + return &BuildQueue{ + queued: make(map[NodeKey]bool), + running: make(map[NodeKey]bool), + failed: make(map[NodeKey]bool), + } } // AddLeaf adds the leaf of message id. The IDs must come in increasing order. @@ -49,7 +52,7 @@ func (q *BuildQueue) AddLeaf(id int) { // AddMerge adds a merge whose children are built. A merge that is in the queue // already stays as it is. -func (q *BuildQueue) AddMerge(key nodeKey) { +func (q *BuildQueue) AddMerge(key NodeKey) { if q.queued[key] { return } @@ -59,14 +62,14 @@ func (q *BuildQueue) AddMerge(key nodeKey) { } // Next returns the next node that can start, and marks it as running. -func (q *BuildQueue) Next() (nodeKey, bool) { +func (q *BuildQueue) Next() (NodeKey, bool) { if len(q.running) >= buildMax { - return nodeKey{}, false + return NodeKey{}, false } leaf, found := q.nextLeaf() if len(q.merges) > 0 && (!found || nodeEnd(q.merges[0].level, q.merges[0].index) <= leaf.index) { - key := heap.Pop(&q.merges).(nodeKey) + key := heap.Pop(&q.merges).(NodeKey) q.running[key] = true return key, true @@ -80,10 +83,12 @@ func (q *BuildQueue) Next() (nodeKey, bool) { } // Done removes a built node from the queue. -func (q *BuildQueue) Done(key nodeKey) { +func (q *BuildQueue) Done(key NodeKey) { delete(q.running, key) + if key.level > 0 { delete(q.queued, key) + return } @@ -94,8 +99,9 @@ func (q *BuildQueue) Done(key nodeKey) { } // Fail keeps a node in the queue, but it cannot start until Retry. -func (q *BuildQueue) Fail(key nodeKey) { +func (q *BuildQueue) Fail(key NodeKey) { delete(q.running, key) + if key.level > 0 { q.retry = append(q.retry, key) return @@ -107,6 +113,7 @@ func (q *BuildQueue) Fail(key nodeKey) { // Retry lets the failed nodes start again. func (q *BuildQueue) Retry() { clear(q.failed) + for _, key := range q.retry { heap.Push(&q.merges, key) } @@ -120,20 +127,17 @@ func (q *BuildQueue) Running() int { } // nextLeaf returns the oldest leaf in the window that can start. -func (q *BuildQueue) nextLeaf() (nodeKey, bool) { +func (q *BuildQueue) nextLeaf() (NodeKey, bool) { for _, id := range q.leaves[:min(len(q.leaves), buildLeafWindow)] { - key := nodeKey{0, id} + key := NodeKey{0, id} if !q.running[key] && !q.failed[key] { return key, true } } - return nodeKey{}, false + return NodeKey{}, false } -// BuildMergeHeap holds the merges that can start, by the end of their context. -type BuildMergeHeap []nodeKey - func (h BuildMergeHeap) Len() int { return len(h) } @@ -147,7 +151,7 @@ func (h BuildMergeHeap) Swap(a, b int) { } func (h *BuildMergeHeap) Push(value any) { - *h = append(*h, value.(nodeKey)) + *h = append(*h, value.(NodeKey)) } func (h *BuildMergeHeap) Pop() any {