-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlbpool.go
More file actions
106 lines (95 loc) · 2.01 KB
/
lbpool.go
File metadata and controls
106 lines (95 loc) · 2.01 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package lbpool
const (
// Default size of the pool.
defaultPoolSize = 64
)
// A Pool is a set of temporary objects.
// Object must implement release logic.
type Pool interface {
// Get selects an arbitrary item from the pool, removes it from the pool, and returns it to the caller.
Get() any
// Put adds x to the pool.
Put(x Releaser) bool
}
// Releaser is the interface that wraps the basic Release method.
type Releaser interface {
Release()
}
type pool struct {
// Maximum size of the pool.
size uint
// Function to make new object if pool didn't deliver existing.
newfn func() any
// Shards count.
shards uint
// Internal storage.
storage storage
// Sampler to equal should item be stored or not.
sampler Sampler
// Metrics writer component.
mw MetricsWriter
}
// NewPool inits new pool with given size.
// Deprecated: use New instead.
func NewPool(size uint, options ...Option) Pool {
return New(size, options...)
}
// New inits new pool with given size.
func New(size uint, options ...Option) Pool {
p := &pool{size: size}
for _, fn := range options {
fn(p)
}
p.init()
return p
}
func (p *pool) Get() any {
x, s := p.storage.get()
if x != nil {
// Return existing object.
p.mw.Hit(s)
return x
} else if p.newfn != nil {
x = p.newfn()
p.mw.New(s)
return x
}
return nil
}
func (p *pool) Put(x Releaser) bool {
// Check sampler first.
if !p.sampler.Sample() {
// Drop x on the floor.
x.Release()
p.mw.Leak("-1", "factor")
return false
}
// Implement leaky buffer logic.
ok, s := p.storage.put(x)
if ok {
p.mw.Store(s)
return true
} else {
// Storage is full, release object manually and leak it.
x.Release()
p.mw.Leak(s, "overflow")
return false
}
}
func (p *pool) init() {
if p.sampler == nil {
p.sampler = dummySampler{}
}
// Check size and init the storage.
if p.size == 0 {
p.size = defaultPoolSize
}
if p.shards > 0 {
p.storage = newSharded(p.size, p.shards)
} else {
p.storage = newSingle(p.size)
}
if p.mw == nil {
p.mw = dummyMetricsWriter{}
}
}