go/protocol/internal/container/priority_map.go (79 lines of code) (raw):

// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. package container import "container/heap" type ( // PriorityMap provides a map with a built-in priority queue for trimming. PriorityMap[K comparable, V any, P Priority] struct { q priorityQueue[K, V, P] m map[K]*entry[K, V, P] } // Priority defines the number types available to use as a priority value. Priority interface{ ~int64 | ~float64 } // https://pkg.go.dev/container/heap#example-package-PriorityQueue priorityQueue[K comparable, V any, P Priority] []*entry[K, V, P] entry[K comparable, V any, P Priority] struct { key K val V pri P idx int } ) func (pq priorityQueue[K, V, P]) Len() int { return len(pq) } func (pq priorityQueue[K, V, P]) Less(i, j int) bool { return pq[i].pri < pq[j].pri } func (pq priorityQueue[K, V, P]) Swap(i, j int) { pq[i], pq[j] = pq[j], pq[i] pq[i].idx = i pq[j].idx = j } func (pq *priorityQueue[K, V, P]) Push(v any) { //nolint:forcetypeassert // The type is guaranteed by the implementation. e := v.(*entry[K, V, P]) e.idx = len(*pq) *pq = append(*pq, e) } func (pq *priorityQueue[K, V, P]) Pop() any { o := *pq n := len(o) e := o[n-1] o[n-1] = nil *pq = o[0 : n-1] return e } // Len returns the number of elements in the queue. func (p *PriorityMap[K, V, P]) Len() int { return len(p.q) } // Get an element in the map by its key. func (p *PriorityMap[K, V, P]) Get(key K) (V, bool) { if e, ok := p.m[key]; ok { return e.val, true } var zv V return zv, false } // Set an element in the map to the given value and priority. func (p *PriorityMap[K, V, P]) Set(key K, val V, pri P) { if e, ok := p.m[key]; ok { e.val = val e.pri = pri heap.Fix(&p.q, e.idx) } else { e := &entry[K, V, P]{key, val, pri, 0} p.m[key] = e heap.Push(&p.q, e) } } // Next returns the next value in the map with the lowest priority. func (p *PriorityMap[K, V, P]) Next() (K, V, bool) { if len(p.q) == 0 { var zk K var zv V return zk, zv, false } e := p.q[0] return e.key, e.val, true } // Delete an element from the map. func (p *PriorityMap[K, V, P]) Delete(key K) { if e, ok := p.m[key]; ok { heap.Remove(&p.q, e.idx) delete(p.m, key) } } // NewPriorityMap creates a new empty priority queue. func NewPriorityMap[K comparable, V any, P Priority]() PriorityMap[K, V, P] { return PriorityMap[K, V, P]{m: map[K]*entry[K, V, P]{}} }