forked from x1m3/priorityQueue
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpriortyQueue.go
More file actions
92 lines (74 loc) · 1.96 KB
/
priortyQueue.go
File metadata and controls
92 lines (74 loc) · 1.96 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
package priorityQueue
import (
"container/heap"
)
type Interface interface {
HigherPriorityThan(Interface) bool
}
const shrinkMinCap = 1000
const shrinkNewSizeFactor = 2
const shrinkCapLenFactorCondition = 4
type Queue struct {
queue heap.Interface
}
func New() *Queue {
pq := &Queue{}
pq.queue = newHeapMemory(
shrinkMinCap,
shrinkNewSizeFactor,
shrinkCapLenFactorCondition,
)
return pq
}
func (pq *Queue) Push(something Interface) {
heap.Push(pq.queue, something)
}
func (pq *Queue) Pop() Interface {
if pq.queue.Len() <= 0 {
return nil
}
r := heap.Pop(pq.queue)
return r.(Interface)
}
type heapMemory struct {
slice internalSlice
ShrinkMinCap int
ShrinkNewSizeFactor int
ShrinkCapLenFactorCondition int
}
func newHeapMemory(shrinkMinCap, shrinkNewSizeFactor, shrinkCapLenFactorCondition int) *heapMemory {
return &heapMemory{
slice: make(internalSlice, 0),
ShrinkMinCap: shrinkMinCap,
ShrinkNewSizeFactor: shrinkNewSizeFactor,
ShrinkCapLenFactorCondition: shrinkCapLenFactorCondition,
}
}
type internalSlice []Interface
func (pq *heapMemory) Len() int { return len(pq.slice) }
func (pq *heapMemory) Less(i, j int) bool {
return pq.slice[i].HigherPriorityThan(pq.slice[j])
}
func (pq *heapMemory) Swap(i, j int) {
pq.slice[i], pq.slice[j] = pq.slice[j], pq.slice[i]
}
func (pq *heapMemory) Push(x interface{}) {
pq.slice = append(pq.slice, x.(Interface))
}
func (pq *heapMemory) Pop() interface{} {
old, n := pq.shrinkIfNeeded()
item := (*old)[n-1]
pq.slice = (*old)[0: n-1]
return item
}
func (pq *heapMemory) shrinkIfNeeded() (*internalSlice, int) {
l, c := len(pq.slice), cap(pq.slice)
if cap(pq.slice) > pq.ShrinkMinCap && c/l > pq.ShrinkCapLenFactorCondition {
newSlice := make(internalSlice, pq.ShrinkNewSizeFactor*l, pq.ShrinkNewSizeFactor*l)
for i, v := range pq.slice {
newSlice[i] = v
}
return &newSlice, l
}
return &pq.slice, l
}