-
Notifications
You must be signed in to change notification settings - Fork 50
/
pools.go
45 lines (39 loc) · 1.21 KB
/
pools.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
package astits
import "sync"
// bytesPool global variable is used to ease access to pool from any place of the code
var bytesPool = &bytesPooler{
sp: sync.Pool{
New: func() interface{} {
// Prepare the slice of somewhat sensible initial size to minimize calls to runtime.growslice
return &bytesPoolItem{
s: make([]byte, 0, 1024),
}
},
},
}
// bytesPoolItem is an object containing payload slice
type bytesPoolItem struct {
s []byte
}
// bytesPooler is a pool for temporary payload in parseData()
// Don't use it anywhere else to avoid pool pollution
type bytesPooler struct {
sp sync.Pool
}
// get returns the bytesPoolItem object with byte slice of a 'size' length
func (bp *bytesPooler) get(size int) (payload *bytesPoolItem) {
payload = bp.sp.Get().(*bytesPoolItem)
// Reset slice length or grow it to requested size for use with copy
if cap(payload.s) >= size {
payload.s = payload.s[:size]
} else {
n := size - cap(payload.s)
payload.s = append(payload.s[:cap(payload.s)], make([]byte, n)...)[:size]
}
return
}
// put returns reference to the payload slice back to pool
// Don't use the payload after a call to put
func (bp *bytesPooler) put(payload *bytesPoolItem) {
bp.sp.Put(payload)
}