github.com/sunvim/utils@v0.1.0/cachem/cache.go (about) 1 package cachem 2 3 import ( 4 "math/bits" 5 "sync" 6 ) 7 8 const maxSize = 46 9 10 // index contains []byte which cap is 1<<index 11 var caches [maxSize]sync.Pool 12 13 func init() { 14 for i := 0; i < maxSize; i++ { 15 size := 1 << i 16 caches[i].New = func() interface{} { 17 buf := make([]byte, 0, size) 18 return buf 19 } 20 } 21 } 22 23 // calculates which pool to get from 24 func calcIndex(size int) int { 25 if size == 0 { 26 return 0 27 } 28 if isPowerOfTwo(size) { 29 return bsr(size) 30 } 31 return bsr(size) + 1 32 } 33 34 // Malloc supports one or two integer argument. 35 // The size specifies the length of the returned slice, which means len(ret) == size. 36 // A second integer argument may be provided to specify the minimum capacity, which means cap(ret) >= cap. 37 func Malloc(size int, capacity ...int) []byte { 38 if len(capacity) > 1 { 39 panic("too many arguments to Malloc") 40 } 41 var c = size 42 if len(capacity) > 0 && capacity[0] > size { 43 c = capacity[0] 44 } 45 var ret = caches[calcIndex(c)].Get().([]byte) 46 ret = ret[:size] 47 return ret 48 } 49 50 // Free should be called when the buf is no longer used. 51 func Free(buf []byte) { 52 size := cap(buf) 53 if !isPowerOfTwo(size) { 54 return 55 } 56 buf = buf[:0] 57 caches[bsr(size)].Put(buf) 58 } 59 60 func bsr(x int) int { 61 return bits.Len(uint(x)) - 1 62 } 63 64 func isPowerOfTwo(x int) bool { 65 return (x & (-x)) == x 66 }