-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathring_buff_mimo.go
More file actions
73 lines (62 loc) · 1.25 KB
/
ring_buff_mimo.go
File metadata and controls
73 lines (62 loc) · 1.25 KB
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
package container
import (
"sync"
"sync/atomic"
)
// 数组实现的环形链表
type RingBuffMIMO[T any] struct {
buff []T
head int32
tail int32
cap int32
len int32
zeroV T
mut sync.RWMutex
}
func NewRingBuffMIMO[T any](size int32) *RingBuffMIMO[T] {
buf := RingBuffMIMO[T]{
buff: make([]T, size),
cap: size,
}
return &buf
}
// push到最后
func (q *RingBuffMIMO[T]) Push(val T) {
q.mut.Lock()
defer q.mut.Unlock()
q.tail = (q.tail + 1) % q.cap
if q.head == q.tail {
// need more memory
buf := make([]T, q.cap*2)
copy(buf[:], q.buff[q.head:])
copy(buf[q.cap-q.head:], q.buff[:q.tail])
q.buff = buf
q.head = 0
q.tail = q.cap
atomic.StoreInt32(&q.cap, int32(len(buf)))
}
q.buff[q.tail] = val
atomic.AddInt32(&q.len, 1)
}
func (q *RingBuffMIMO[T]) Len() int32 {
return atomic.LoadInt32(&q.len)
}
func (q *RingBuffMIMO[T]) Empty() bool {
return q.Len() == 0
}
func (q *RingBuffMIMO[T]) IsFull() bool {
return q.Len() == atomic.LoadInt32(&q.cap)
}
// 弹出最前面的一个
func (q *RingBuffMIMO[T]) Pop() (T, bool) {
if q.Empty() {
return q.zeroV, false
}
atomic.AddInt32(&q.len, -1)
q.mut.Lock()
defer q.mut.Unlock()
q.head = (q.head + 1) % q.cap
v := q.buff[q.head]
q.buff[q.head] = q.zeroV
return v, true
}