-
Notifications
You must be signed in to change notification settings - Fork 38
/
pool.go
62 lines (55 loc) · 1.9 KB
/
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
// Copyright (c) 2017 Western Digital Corporation or its affiliates. All rights reserved.
// SPDX-License-Identifier: MIT
//
// Specialized pools for a few sizes: 8MB (tract length), 4MB (RS encoding block
// size), and 1MB (smaller buffers), all including one checksumblock overhead
// for ChecksumFile.ReadAt.
package rpc
import (
"sync"
"github.com/westerndigitalcorporation/blb/pkg/disk"
)
const (
buf8MBSize = 8<<20 + disk.ExtraRoom
buf4MBSize = 4<<20 + disk.ExtraRoom
buf1MBSize = 1<<20 + disk.ExtraRoom
)
var (
buf8MBPool = sync.Pool{New: func() interface{} { b := make([]byte, buf8MBSize); return &b }}
buf4MBPool = sync.Pool{New: func() interface{} { b := make([]byte, buf4MBSize); return &b }}
buf1MBPool = sync.Pool{New: func() interface{} { b := make([]byte, buf1MBSize); return &b }}
)
// GetBuffer returns a []byte with length n and capacity >= n.
// The buffer may not be zeroed!
func GetBuffer(n int) []byte {
if n <= 128*1024+disk.ExtraRoom {
// Don't bother with pools for small buffers.
return make([]byte, n)
} else if n <= buf1MBSize {
return (*buf1MBPool.Get().(*[]byte))[:n]
} else if n <= buf4MBSize {
return (*buf4MBPool.Get().(*[]byte))[:n]
} else if n <= buf8MBSize {
return (*buf8MBPool.Get().(*[]byte))[:n]
}
// Or large ones.
return make([]byte, n)
}
// PutBuffer returns a buffer to the pool. It's okay to call this on any buffer
// that isn't going to be used again, whether it came from GetBuffer or not.
// 'exclusive' indicates whether the caller is the exclusive owner of the
// buffer. (If exclusive is false, obviously, the buffer cannot be put in a
// pool. PutBuffer has this signature to be able to use it conveniently with
// BulkData.Get)
func PutBuffer(b []byte, exclusive bool) {
if !exclusive {
return
}
if cap(b) == buf8MBSize {
buf8MBPool.Put(&b)
} else if cap(b) == buf4MBSize {
buf4MBPool.Put(&b)
} else if cap(b) == buf1MBSize {
buf1MBPool.Put(&b)
}
}