-
Notifications
You must be signed in to change notification settings - Fork 0
/
priority_queue.go
83 lines (63 loc) · 1.47 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
package main
/* BEGIN PRIORITY QUEUE
Source: http://golang.org/pkg/container/heap/
*/
import (
"sync"
"container/heap"
)
type PriorityQueue struct {
items *PriorityList
sync.RWMutex
}
type PriorityList []*PriorityItem
func NewPriorityQueue() *PriorityQueue {
pq := &PriorityQueue{
items: &PriorityList{},
}
heap.Init(pq.items)
return pq
}
type PriorityItem struct {
value interface{}
priority int
}
func (pl PriorityList) Len() int { return len(pl) }
func (pl PriorityList) Less(i, j int) bool { return pl[i].priority < pl[j].priority }
func (pl PriorityList) Swap(i, j int) { pl[i], pl[j] = pl[j], pl[i] }
func (pq *PriorityQueue) Push(x interface{}, priority int) {
pq.Lock()
defer pq.Unlock()
heap.Push(pq.items, &PriorityItem{x, priority})
}
func (pl *PriorityList) Push(x interface{}) {
// Push and Pop use pointer receivers because they modify the slice's length,
// not just its contents.
*pl = append(*pl, x.(*PriorityItem))
}
func (pq *PriorityQueue) Pop() *PriorityItem {
pq.Lock()
defer pq.Unlock()
return heap.Pop(pq.items).(*PriorityItem)
}
func (pq *PriorityQueue) Len() int {
pq.RLock()
defer pq.RUnlock()
return pq.items.Len()
}
func (pq *PriorityQueue) Peek() *PriorityItem {
pq.RLock()
defer pq.RUnlock()
if pq.items.Len() == 0 {
return nil
}
return (*pq.items)[0]
}
func (pl *PriorityList) Pop() interface{} {
old := *pl
n := len(old)
x := old[n-1]
*pl = old[0 : n-1]
return x
}
/* END PRIORITY QUEUE */