...
1
18
19 package grpc
20
21 import "sync"
22
23
24
25
26
27
28
29
30
31 type SharedBufferPool interface {
32
33
34
35 Get(length int) []byte
36
37
38 Put(*[]byte)
39 }
40
41
42
43
44
45
46
47
48
49 func NewSharedBufferPool() SharedBufferPool {
50 return &simpleSharedBufferPool{
51 pools: [poolArraySize]simpleSharedBufferChildPool{
52 newBytesPool(level0PoolMaxSize),
53 newBytesPool(level1PoolMaxSize),
54 newBytesPool(level2PoolMaxSize),
55 newBytesPool(level3PoolMaxSize),
56 newBytesPool(level4PoolMaxSize),
57 newBytesPool(0),
58 },
59 }
60 }
61
62
63 type simpleSharedBufferPool struct {
64 pools [poolArraySize]simpleSharedBufferChildPool
65 }
66
67 func (p *simpleSharedBufferPool) Get(size int) []byte {
68 return p.pools[p.poolIdx(size)].Get(size)
69 }
70
71 func (p *simpleSharedBufferPool) Put(bs *[]byte) {
72 p.pools[p.poolIdx(cap(*bs))].Put(bs)
73 }
74
75 func (p *simpleSharedBufferPool) poolIdx(size int) int {
76 switch {
77 case size <= level0PoolMaxSize:
78 return level0PoolIdx
79 case size <= level1PoolMaxSize:
80 return level1PoolIdx
81 case size <= level2PoolMaxSize:
82 return level2PoolIdx
83 case size <= level3PoolMaxSize:
84 return level3PoolIdx
85 case size <= level4PoolMaxSize:
86 return level4PoolIdx
87 default:
88 return levelMaxPoolIdx
89 }
90 }
91
92 const (
93 level0PoolMaxSize = 16
94 level1PoolMaxSize = level0PoolMaxSize * 16
95 level2PoolMaxSize = level1PoolMaxSize * 16
96 level3PoolMaxSize = level2PoolMaxSize * 16
97 level4PoolMaxSize = level3PoolMaxSize * 16
98 )
99
100 const (
101 level0PoolIdx = iota
102 level1PoolIdx
103 level2PoolIdx
104 level3PoolIdx
105 level4PoolIdx
106 levelMaxPoolIdx
107 poolArraySize
108 )
109
110 type simpleSharedBufferChildPool interface {
111 Get(size int) []byte
112 Put(any)
113 }
114
115 type bufferPool struct {
116 sync.Pool
117
118 defaultSize int
119 }
120
121 func (p *bufferPool) Get(size int) []byte {
122 bs := p.Pool.Get().(*[]byte)
123
124 if cap(*bs) < size {
125 p.Pool.Put(bs)
126
127 return make([]byte, size)
128 }
129
130 return (*bs)[:size]
131 }
132
133 func newBytesPool(size int) simpleSharedBufferChildPool {
134 return &bufferPool{
135 Pool: sync.Pool{
136 New: func() any {
137 bs := make([]byte, size)
138 return &bs
139 },
140 },
141 defaultSize: size,
142 }
143 }
144
145
146 type nopBufferPool struct {
147 }
148
149 func (nopBufferPool) Get(length int) []byte {
150 return make([]byte, length)
151 }
152
153 func (nopBufferPool) Put(*[]byte) {
154 }
155
View as plain text