-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathringbuffer.go
87 lines (71 loc) · 1.37 KB
/
ringbuffer.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
package main
const ringBufferInitialSize = 1000
type ringbuffer struct {
buf []int
head int
size int
}
func (r *ringbuffer) get() (val int, ok bool) {
if r.size > 0 {
val = r.buf[r.head]
r.buf[r.head] = 0
r.head = (r.head + 1) % len(r.buf)
r.size--
ok = true
}
return
}
func (r *ringbuffer) put(val int) {
if len(r.buf) == 0 {
// First call to put.
r.buf = make([]int, ringBufferInitialSize)
}
if r.size == len(r.buf) {
// Make a new ring buffer 50% bigger.
newBuf := make([]int, int(float64(len(r.buf))*1.5))
// Copy from old ring buffer to new.
var i int
cur := r.head
for {
if i == r.size {
break
}
newBuf[i] = r.buf[cur]
i++
cur = (cur + 1) % len(r.buf)
}
r.buf = newBuf
r.head = 0
}
r.buf[(r.head+r.size)%len(r.buf)] = val
r.size++
return
}
func (r *ringbuffer) remove(val int) {
var checkedCount int
cur := r.head
for {
if checkedCount == r.size {
// We checked all elements, and we did not find val.
break
}
checkedCount++
if r.buf[cur] == val {
// Element to remove was found. Remove item by moving all subsequent items one back.
for {
next := (cur + 1) % len(r.buf)
r.buf[cur] = r.buf[next]
if checkedCount == r.size {
r.buf[cur] = 0
break
}
checkedCount++
cur = (cur + 1) % len(r.buf)
}
r.size--
break
}
cur = (cur + 1) % len(r.buf)
}
return
}