github.com/scottcagno/storage@v1.8.0/pkg/util/lowerlevellibs/bytealloc/bytealloc.go (about) 1 package bytealloc 2 3 import "github.com/scottcagno/storage/pkg/util/lowerlevellibs/bytealloc/rawalloc" 4 5 // An A provides chunk allocation of []byte, amortizing the overhead of each 6 // allocation. Because the underlying storage for the slices is shared, they 7 // should share a similar lifetime in order to avoid pinning large amounts of 8 // memory unnecessarily. The allocator itself is a []byte where cap() indicates 9 // the total amount of memory and len() is the amount already allocated. The 10 // size of the buffer to allocate from is grown exponentially when it runs out 11 // of room up to a maximum size (chunkAllocMaxSize). 12 type A []byte 13 14 const chunkAllocMinSize = 512 15 const chunkAllocMaxSize = 16384 16 17 func (a A) reserve(n int) A { 18 allocSize := cap(a) * 2 19 if allocSize < chunkAllocMinSize { 20 allocSize = chunkAllocMinSize 21 } else if allocSize > chunkAllocMaxSize { 22 allocSize = chunkAllocMaxSize 23 } 24 if allocSize < n { 25 allocSize = n 26 } 27 return rawalloc.New(0, allocSize) 28 } 29 30 // Alloc allocates a new chunk of memory with the specified length. 31 func (a A) Alloc(n int) (A, []byte) { 32 if cap(a)-len(a) < n { 33 a = a.reserve(n) 34 } 35 p := len(a) 36 r := a[p : p+n : p+n] 37 a = a[:p+n] 38 return a, r 39 } 40 41 // Copy allocates a new chunk of memory, initializing it from src. 42 func (a A) Copy(src []byte) (A, []byte) { 43 var alloc []byte 44 a, alloc = a.Alloc(len(src)) 45 copy(alloc, src) 46 return a, alloc 47 }