-
Notifications
You must be signed in to change notification settings - Fork 0
/
priority_queue.go
89 lines (69 loc) · 1.54 KB
/
priority_queue.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package prioritize
import (
"container/heap"
"sync"
)
type PriorityQueuer[T any] interface {
Pop() Item[T]
Push(x Item[T])
Update(item Item[T], value T, priority int64)
Peek() Item[T]
Range() []Item[T]
}
type PriorityQueue[T any] struct {
mu sync.RWMutex
internalHeap *internalHeap[T]
}
func NewPriorityQueue[T any](items []Item[T]) *PriorityQueue[T] {
for i := range items {
items[i].index = i
}
iHeap := &internalHeap[T]{
items: items,
}
heap.Init(iHeap)
return &PriorityQueue[T]{
mu: sync.RWMutex{},
internalHeap: iHeap,
}
}
func (h *PriorityQueue[T]) Push(x Item[T]) {
h.mu.Lock()
defer h.mu.Unlock()
h.internalHeap.Push(x)
h.internalHeap.Fix(h.internalHeap.Len() - 1)
}
func (h *PriorityQueue[T]) Pop() Item[T] {
h.mu.Lock()
defer h.mu.Unlock()
return h.internalHeap.Pop().(Item[T])
}
func (h *PriorityQueue[T]) Peek() Item[T] {
h.mu.RLock()
defer h.mu.RUnlock()
if h.internalHeap.Len() == 0 {
return Item[T]{}
}
return h.internalHeap.items[0]
}
func (h *PriorityQueue[T]) Update(item Item[T], value T, priority int64) {
h.mu.Lock()
defer h.mu.Unlock()
item.Value = value
item.Priority = priority
h.internalHeap.items[item.index] = item
h.internalHeap.Fix(item.index)
}
func (h *PriorityQueue[T]) Range() []Item[T] {
h.mu.RLock()
defer h.mu.RUnlock()
items := make([]Item[T], 0, h.internalHeap.Len())
for _, item := range h.internalHeap.items {
items = append(items, Item[T]{
Value: item.Value,
Priority: item.Priority,
index: item.index,
})
}
return items
}