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  }