-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpq.go
More file actions
95 lines (86 loc) · 1.8 KB
/
pq.go
File metadata and controls
95 lines (86 loc) · 1.8 KB
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
90
91
92
93
94
95
package priority
type PriorityQueue struct {
lowest, highest int
main <-chan interface{}
ins map[int]chan<- interface{}
}
const (
_ = -iota
Lowest
Highest
)
func NewPriorityQueue(numQueues int, ascendingPriority, blocking bool) *PriorityQueue {
main := make(chan interface{})
pq := &PriorityQueue{
ins: make(map[int]chan<- interface{}, numQueues),
main: main,
}
queues := make([]*queue, numQueues)
lastIndex := numQueues - 1
for i := range queues {
j := i
if ascendingPriority {
j = lastIndex - i
}
in, out, closer := generate(blocking)
pq.ins[j] = in
if i == 0 {
queues[j] = newQueue(main, out, closer)
continue
}
link := make(chan interface{})
queues[j] = newQueue(link, out, closer)
if ascendingPriority {
queues[j+1].start(link)
} else {
queues[j-1].start(link)
}
}
if ascendingPriority {
queues[0].start(nil)
pq.lowest = 0
pq.highest = lastIndex
} else {
queues[lastIndex].start(nil)
pq.lowest = lastIndex
pq.highest = 0
}
queues = nil
return pq
}
func (pq *PriorityQueue) Close() {
close(pq.ins[pq.lowest])
}
func (pq *PriorityQueue) Write(priority int) chan<- interface{} {
switch priority {
case Lowest:
priority = pq.lowest
case Highest:
priority = pq.highest
}
in, ok := pq.ins[priority]
if !ok {
in = pq.ins[pq.lowest]
}
return in
}
func (pq *PriorityQueue) ReadChan() <-chan interface{} {
return pq.main
}
func (pq *PriorityQueue) ReadValue() (interface{}, bool) {
val, ok := <-pq.main
return val, ok
}
func generate(blocking bool) (in chan<- interface{}, out <-chan interface{}, closer func()) {
if blocking {
in, out = newChan()
} else {
in, out = newInf()
}
closer = func() { close(in) }
return
}
func newChan() (chan<- interface{}, <-chan interface{}) {
c := make(chan interface{})
return c, c
}