...
1
2
3
4
5
6
7 package util
8
9 import (
10 "fmt"
11 "sync"
12 "sync/atomic"
13 )
14
15
16 type BufferPool struct {
17 pool [6]sync.Pool
18 baseline [5]int
19
20 get uint32
21 put uint32
22 less uint32
23 equal uint32
24 greater uint32
25 miss uint32
26 }
27
28 func (p *BufferPool) poolNum(n int) int {
29 for i, x := range p.baseline {
30 if n <= x {
31 return i
32 }
33 }
34 return len(p.baseline)
35 }
36
37
38 func (p *BufferPool) Get(n int) []byte {
39 if p == nil {
40 return make([]byte, n)
41 }
42 atomic.AddUint32(&p.get, 1)
43
44 poolNum := p.poolNum(n)
45
46 b := p.pool[poolNum].Get().(*[]byte)
47
48 if cap(*b) == 0 {
49
50 atomic.AddUint32(&p.miss, 1)
51
52 if poolNum == len(p.baseline) {
53 *b = make([]byte, n)
54 return *b
55 }
56
57 *b = make([]byte, p.baseline[poolNum])
58 *b = (*b)[:n]
59 return *b
60 } else {
61
62
63 if n < cap(*b) {
64 atomic.AddUint32(&p.less, 1)
65 *b = (*b)[:n]
66 return *b
67 } else if n == cap(*b) {
68 atomic.AddUint32(&p.equal, 1)
69 *b = (*b)[:n]
70 return *b
71 } else if n > cap(*b) {
72 atomic.AddUint32(&p.greater, 1)
73 }
74 }
75
76 if poolNum == len(p.baseline) {
77 *b = make([]byte, n)
78 return *b
79 }
80 *b = make([]byte, p.baseline[poolNum])
81 *b = (*b)[:n]
82 return *b
83 }
84
85
86 func (p *BufferPool) Put(b []byte) {
87 if p == nil {
88 return
89 }
90
91 poolNum := p.poolNum(cap(b))
92
93 atomic.AddUint32(&p.put, 1)
94 p.pool[poolNum].Put(&b)
95 }
96
97 func (p *BufferPool) String() string {
98 if p == nil {
99 return "<nil>"
100 }
101 return fmt.Sprintf("BufferPool{B·%d G·%d P·%d <·%d =·%d >·%d M·%d}",
102 p.baseline, p.get, p.put, p.less, p.equal, p.greater, p.miss)
103 }
104
105
106 func NewBufferPool(baseline int) *BufferPool {
107 if baseline <= 0 {
108 panic("baseline can't be <= 0")
109 }
110 bufPool := &BufferPool{
111 baseline: [...]int{baseline / 4, baseline / 2, baseline, baseline * 2, baseline * 4},
112 pool: [6]sync.Pool{
113 {
114 New: func() interface{} { return new([]byte) },
115 },
116 {
117 New: func() interface{} { return new([]byte) },
118 },
119 {
120 New: func() interface{} { return new([]byte) },
121 },
122 {
123 New: func() interface{} { return new([]byte) },
124 },
125 {
126 New: func() interface{} { return new([]byte) },
127 },
128 {
129 New: func() interface{} { return new([]byte) },
130 },
131 },
132 }
133
134 return bufPool
135 }
136
View as plain text