This repository was archived by the owner on May 10, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbufferpool.go
83 lines (74 loc) · 1.98 KB
/
bufferpool.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
package bufferpool
import (
"sync"
)
// BufferPool provides a pool of byte slice, made from a single huge byte array.
type BufferPool struct {
mx sync.RWMutex
bufferCount, bufferSize int
pool [][]byte
}
// New makes a new *BufferPool
func New(bufferSize, bufferCount int) *BufferPool {
pool, _ := newBufferPool(bufferSize, bufferCount)
return pool
}
func newBufferPool(bufferSize, bufferCount int) (pool *BufferPool, back []byte) {
var res BufferPool
res.bufferSize = bufferSize
res.bufferCount = bufferCount
res.pool, back = makePartitions(bufferSize, bufferCount)
pool = &res
return
}
func makePartitions(bufferSize, bufferCount int) (pool [][]byte, back []byte) {
size := bufferCount * bufferSize
back = make([]byte, size, size)
for i := 0; i < bufferCount; i++ {
low := i * bufferSize
high := low + bufferSize
pool = append(pool, back[low:high:high])
}
return
}
// Len returns the length of the pool.
func (bf *BufferPool) Len() int {
bf.mx.RLock()
defer bf.mx.RUnlock()
l := len(bf.pool)
return l
}
// Take returns a byte slice from the pool or nil if the pool is depleted.
func (bf *BufferPool) Take() (buffer []byte) {
bf.mx.Lock()
defer bf.mx.Unlock()
l := len(bf.pool)
if l == 0 {
return nil
}
buffer, bf.pool = bf.pool[l-1], bf.pool[:l-1]
return buffer
}
// Put puts back a []byte into the pool unless the pool if full or
// the provided buffer has a different length than the initial buffer size.
func (bf *BufferPool) Put(buffer []byte) bool {
bf.mx.Lock()
defer bf.mx.Unlock()
l := len(bf.pool)
if l == bf.bufferCount {
return false
}
if len(buffer) != bf.bufferSize {
return false
}
bf.pool = append(bf.pool, buffer)
return true
}
// Expand expands the pool bufferCount times, creating a new underlying array.
func (bf *BufferPool) Expand(bufferCount int) {
bf.mx.Lock()
defer bf.mx.Unlock()
pool, _ := makePartitions(bf.bufferSize, bufferCount)
bf.pool = append(bf.pool, pool...)
bf.bufferCount += bufferCount
}