-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgfreequeue.go
114 lines (91 loc) · 1.46 KB
/
gfreequeue.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
package gfreequeue
import (
"github.com/hlts2/lock-free"
)
type node struct {
value interface{}
next *node
}
// Queue -
type Queue interface {
Enqueue(value interface{})
Dequeue() interface{}
Length() int
Iterator() []interface{}
}
type queue struct {
node *node
length int
lf lockfree.LockFree
tail *node
}
// New initialize new instance
func New() Queue {
return &queue{
node: nil,
length: 0,
lf: lockfree.New(),
tail: nil,
}
}
// Enqueue -
func (q *queue) Enqueue(value interface{}) {
q.lf.Wait()
q.enqueue(value)
q.lf.Signal()
}
func (q *queue) enqueue(value interface{}) {
n := &node{
value: value,
next: nil,
}
q.length++
if q.node == nil || q.tail == nil {
q.node = n
q.tail = n
return
}
q.tail.next = n
q.tail = n
}
// Dequeue -
func (q *queue) Dequeue() interface{} {
q.lf.Wait()
v := q.dequeue()
q.lf.Signal()
return v
}
func (q *queue) dequeue() interface{} {
if q.node == nil {
return nil
}
n := q.node
q.node = n.next
if q.node == nil {
q.tail = nil
q.length = 0
} else {
q.length--
}
return n.value
}
func (q *queue) Length() int {
q.lf.Wait()
l := q.length
q.lf.Signal()
return l
}
// Iterator -
func (q *queue) Iterator() []interface{} {
q.lf.Wait()
values := q.iterator()
q.lf.Signal()
return values
}
func (q *queue) iterator() []interface{} {
values := make([]interface{}, 0, q.length)
for q.length != 0 {
values = append(values, q.dequeue())
}
return values
}