-
Notifications
You must be signed in to change notification settings - Fork 68
/
bytes_buffer_pool.go
102 lines (84 loc) · 2.17 KB
/
bytes_buffer_pool.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
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
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package gxbytes
import (
"bytes"
"sync"
)
import (
uatomic "go.uber.org/atomic"
)
var (
poolObjectNumber uatomic.Int64
defaultPool *ObjectPool
minBufCap = 512
maxBufCap = 20 * 1024
maxPoolObjectNum = int64(4000)
)
func init() {
defaultPool = NewObjectPool(func() PoolObject {
return new(bytes.Buffer)
})
poolObjectNumber.Store(0)
}
// GetBytesBuffer returns bytes.Buffer from pool
func GetBytesBuffer() *bytes.Buffer {
buf := defaultPool.Get().(*bytes.Buffer)
bufCap := buf.Cap()
if bufCap >= minBufCap && bufCap <= maxBufCap && poolObjectNumber.Load() > 0 {
poolObjectNumber.Dec()
}
return buf
}
// PutIoBuffer returns IoBuffer to pool
func PutBytesBuffer(buf *bytes.Buffer) {
if poolObjectNumber.Load() > maxPoolObjectNum {
return
}
bufCap := buf.Cap()
if bufCap < minBufCap || bufCap > maxBufCap {
return
}
defaultPool.Put(buf)
poolObjectNumber.Add(1)
}
// Pool object
type PoolObject interface {
Reset()
}
type New func() PoolObject
// Pool is bytes.Buffer Pool
type ObjectPool struct {
New New
pool sync.Pool
}
func NewObjectPool(n New) *ObjectPool {
return &ObjectPool{New: n}
}
// take returns *bytes.Buffer from Pool
func (p *ObjectPool) Get() PoolObject {
v := p.pool.Get()
if v == nil {
return p.New()
}
return v.(PoolObject)
}
// give returns *byes.Buffer to Pool
func (p *ObjectPool) Put(o PoolObject) {
o.Reset()
p.pool.Put(o)
}