forked from samanbarghi/goring
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqueue.go
105 lines (90 loc) · 1.73 KB
/
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package goring
import "sync"
type ringBuffer struct {
buffer []interface{}
head int
tail int
mod int
}
type Queue struct {
content *ringBuffer
len int
lock sync.Mutex
}
func New(initialSize int) *Queue {
return &Queue{
content: &ringBuffer{
buffer: make([]interface{}, initialSize),
head: 0,
tail: 0,
mod: initialSize,
},
len: 0,
}
}
func (q *Queue) Push(item interface{}) {
q.lock.Lock()
c := q.content
c.tail = ((c.tail + 1) % c.mod)
if c.tail == c.head {
fillFactor := 50
//we need to resize
newLen := c.mod * fillFactor
newBuff := make([]interface{}, newLen)
for i := 0; i < c.mod; i++ {
buffIndex := (c.tail + i) % c.mod
newBuff[i] = c.buffer[buffIndex]
}
//set the new buffer and reset head and tail
newContent := &ringBuffer{
buffer: newBuff,
head: 0,
tail: c.mod,
mod: c.mod * fillFactor,
}
q.content = newContent
}
q.len++
q.content.buffer[q.content.tail] = item
q.lock.Unlock()
}
func (q *Queue) Length() int {
q.lock.Lock()
len := q.len
q.lock.Unlock()
return len
}
func (q *Queue) Empty() bool {
return q.Length() == 0
}
func (q *Queue) Pop() (interface{}, bool) {
q.lock.Lock()
if q.len == 0 {
q.lock.Unlock()
return nil, false
}
c := q.content
c.head = ((c.head + 1) % c.mod)
q.len--
q.lock.Unlock()
return c.buffer[c.head], true
}
func (q *Queue) PopMany(count int) ([]interface{}, bool) {
q.lock.Lock()
if q.len == 0 {
q.lock.Unlock()
return nil, false
}
c := q.content
if count >= q.len {
count = q.len
}
buffer := make([]interface{}, count)
for i := 0; i < count; i++ {
buffer[i] = c.buffer[(c.head+1+i)%c.mod]
}
c.head = (c.head + count) % c.mod
q.len -= count
q.lock.Unlock()
return buffer, true
}