forked from influxdata/kapacitor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
circularqueue.gen.go.tmpl
115 lines (103 loc) · 2.62 KB
/
circularqueue.gen.go.tmpl
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
//lint:file-ignore U1000 this is generated code
package kapacitor
{{with $types := .}}{{range $k := $types}}
// {{ $k }}CircularQueue defines a circular queue, always use the contructor to create one.
type {{ $k }}CircularQueue struct {
data []{{ $k }}
head int
tail int
l int
}
// {{ if eq (substr 0 1 $k ) (substr 0 1 $k | upper) -}} New {{- else -}} new {{- end -}}
{{- substr 0 1 $k | upper -}}{{- substr 1 (len $k) $k -}} constructs a Circular Queue
// with a given buffer buf. It is ok for buf to be nil.
func {{ if eq (substr 0 1 $k ) (substr 0 1 $k | upper) -}} New {{- else -}} new {{- end -}}
{{- substr 0 1 $k | upper -}}{{- substr 1 (len $k) $k -}} CircularQueue(buf ...{{ $k }}) *{{ $k }}CircularQueue {
// if we have a useless buffer, make one that is at least useful
if cap(buf) < 4{
buf = append(make([]{{ $k }}, 0, 4), buf...)
}
return &{{ $k }}CircularQueue{
data: buf[:cap(buf)],
tail: len(buf), // tail is here we insert
l: len(buf),
}
}
// Enqueue adds an item to the queue.
func (q * {{- $k -}} CircularQueue) Enqueue(v {{ $k }}) {
// if full we must grow and insert together. This is an expensive op
if cap(q.data) > q.l {// no need to grow
if q.tail == len(q.data){
q.tail = 0
}
q.data[q.tail] = v
}else{ // we need to grow
buf := make([]{{ $k }}, cap(q.data)*2)
if q.head < q.tail{
copy(buf, q.data[q.head:q.tail])
} else {
partialWriteLen := copy(buf, q.data[q.head:])
copy(buf[partialWriteLen:], q.data[:q.tail])
}
q.head = 0
q.tail = cap(q.data)
buf[q.tail] = v
q.data = buf
}
q.l++
q.tail++
return
}
// Dequeue removes n items from the queue. If n is longer than the number of the items in the queue it will clear them all out.
func (q *{{ $k }}CircularQueue) Dequeue(n int) {
if n<=0{
return
}
if q.l <= n{
n = q.l
}
ni:=n
var fill {{ $k }}
if q.head>q.tail{
for i:=q.head;i<len(q.data)&&ni>0;i++{
q.data[i] = fill
ni--
}
for i:=0;i<q.tail&&ni>0;i++{
q.data[i] = fill
ni--
}
} else {
for i:=q.head;i<q.tail&&ni>0;i++{
q.data[i] = fill
ni--
}
}
q.head+=n
if q.head>len(q.data){
q.head -= len(q.data)
}
q.l-=n
if q.l==0{
q.head = 0
q.tail = 0
}
return
}
// Peek peeks i ahead of the current head of queue. It should be used in conjunction with .Len() to prevent a panic.
func (q *{{ $k }}CircularQueue) Peek(i int) {{ $k }} {
if i<0 || i>= q.l{
panic("peek index is out of bounds")
}
p := q.head + i
if p >= len(q.data) {
p-=len(q.data)
}
return q.data[p]
}
// Len returns the current number of items in the queue.
func (q *{{ $k }}CircularQueue) Len() int {
return q.l
}
{{end}}
{{end}}