-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstorage.go
More file actions
85 lines (74 loc) · 1.31 KB
/
storage.go
File metadata and controls
85 lines (74 loc) · 1.31 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
74
75
76
77
78
79
80
81
82
83
84
85
package lbpool
import (
"math"
"strconv"
"sync/atomic"
)
type storage interface {
get() (any, string)
put(any) (bool, string)
}
type single struct {
ch chan any
}
func newSingle(size uint) storage {
return &single{ch: make(chan any, size)}
}
func (s *single) get() (any, string) {
select {
case x := <-s.ch:
return x, "0"
default:
return nil, "0"
}
}
func (s *single) put(x any) (bool, string) {
select {
case s.ch <- x:
return true, "0"
default:
return false, "0"
}
}
type sharded struct {
buf []shard
l, r, w uint64
}
type shard struct {
ch chan any
name string
}
func newSharded(size uint, shards uint) storage {
ssize := uint64(math.Ceil(float64(size) / float64(shards)))
s := &sharded{
buf: make([]shard, shards),
r: math.MaxUint64,
w: math.MaxUint64,
l: ssize,
}
for i := uint(0); i < shards; i++ {
s.buf[i].ch = make(chan any, ssize)
s.buf[i].name = strconv.Itoa(int(i))
}
return s
}
func (s *sharded) get() (any, string) {
_ = s.buf[s.l-1]
ss := s.buf[atomic.AddUint64(&s.r, 1)%s.l]
select {
case x := <-ss.ch:
return x, ss.name
default:
return nil, ss.name
}
}
func (s *sharded) put(x any) (bool, string) {
_ = s.buf[s.l-1]
ss := s.buf[atomic.AddUint64(&s.w, 1)%s.l]
select {
case ss.ch <- x:
return true, ss.name
default:
return false, ss.name
}
}