-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathringbuf.go
132 lines (108 loc) · 1.78 KB
/
ringbuf.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package vqueue
import (
"sync"
)
type varNode struct {
next *varNode
val interface{}
}
type varRing struct {
head *varNode
tail *varNode
free func(interface{})
}
var nodePool = sync.Pool{
New: func() interface{} {
return new(varNode)
},
}
func new_var_node() *varNode {
n := nodePool.Get().(*varNode)
n.next = nil
n.val = nil
return n
}
func del_var_node(n *varNode) {
n.next = nil
n.val = nil
nodePool.Put(n)
}
func dummy_free(interface{}) {}
func newRing(free func(interface{})) *varRing {
if free == nil {
free = dummy_free
}
n := new_var_node()
n.next = n
return &varRing{head: n, tail: n, free: free}
}
func (vb *varRing) is_closed() bool {
return vb.tail == nil || vb.head == nil
}
func (vb *varRing) is_full() bool {
return vb.tail.next == vb.head
}
func (vb *varRing) add() {
n := new_var_node()
n.next = vb.tail.next
vb.tail.next = n
}
func (vb *varRing) purge() {
cur := vb.tail.next
vb.tail.next = vb.tail
vb.head = vb.tail
for cur != vb.tail {
d := cur
cur = cur.next
if d.val != nil {
vb.free(d.val)
}
del_var_node(d)
}
}
func (vb *varRing) IsEmpty() bool {
return vb.head == vb.tail
}
func (vb *varRing) Close() {
if vb.is_closed() {
return
}
vb.purge()
del_var_node(vb.tail)
vb.tail = nil
vb.head = nil
}
func (vb *varRing) Shrink() {
if vb.is_closed() {
return
}
if vb.is_full() {
return
}
cur := vb.tail.next
vb.tail.next = vb.head
for {
del := cur
cur = cur.next
del_var_node(del)
if cur == vb.head {
break
}
}
}
func (vb *varRing) Pop() (interface{}, bool) {
if vb.IsEmpty() {
return nil, false
}
res := vb.head.val
vb.head.val = nil
vb.head = vb.head.next
return res, true
}
func (vb *varRing) Push(v interface{}) {
if vb.is_full() {
vb.add()
}
vb.tail.val = v
vb.tail = vb.tail.next
}