-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathring.go
74 lines (56 loc) · 1.06 KB
/
ring.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
package ring
import (
"runtime"
_ "unsafe"
"github.com/xtracker/ring/internal/slot"
)
func NewRing[T any](sz int) *Ring[T] {
r := &Ring[T]{
slots: make([]*slot.Ring[T], runtime.GOMAXPROCS(0)),
}
for i := range r.slots {
r.slots[i] = slot.NewRing[T](sz)
}
return r
}
type Ring[T any] struct {
slots []*slot.Ring[T]
}
func (r *Ring[T]) Offer(dp T) bool {
pid := procPin()
defer procUnPin()
if pid >= len(r.slots) {
return false
}
return r.slots[pid].Offer(dp)
}
func (r *Ring[T]) Snapshot() Iterator[T] {
its := iterators[T]{}
for _, s := range r.slots {
its = append(its, s.Snapshot())
}
return its
}
type Iterator[T any] interface {
slot.Iterator[T]
}
type iterators[T any] []slot.Iterator[T]
func (i iterators[T]) Next() (T, bool) {
for _, it := range i {
v, ok := it.Next()
if ok {
return v, true
}
}
var zero T
return zero, false
}
func (i iterators[T]) Close() {
for _, it := range i {
it.Close()
}
}
//go:linkname procPin runtime.procPin
func procPin() int
//go:linkname procUnPin runtime.procUnpin
func procUnPin()