// Package iobufpool implements a global segregated-fit pool of buffers for IO. // // It uses *[]byte instead of []byte to avoid the sync.Pool allocation with Put. Unfortunately, using a pointer to avoid // an allocation is purposely not documented. https://github.com/golang/go/issues/16323
package iobufpool import ( ) const minPoolExpOf2 = 8 var pools [18]*sync.Pool func () { for := range pools { := 1 << (minPoolExpOf2 + ) pools[] = &sync.Pool{ New: func() any { := make([]byte, ) return & }, } } } // Get gets a []byte of len size with cap <= size*2. func ( int) *[]byte { := getPoolIdx() if >= len(pools) { := make([]byte, ) return & } := (pools[].Get().(*[]byte)) * = (*)[:] return } func ( int) int { if < 2 { return 0 } := bits.Len(uint(-1)) - minPoolExpOf2 if < 0 { return 0 } return } // Put returns buf to the pool. func ( *[]byte) { := putPoolIdx(cap(*)) if < 0 { return } pools[].Put() } func ( int) int { // Only exact power-of-2 sizes match pool buckets if &(-1) != 0 { return -1 } // Calculate log2(size) using trailing zeros count := bits.TrailingZeros(uint()) := - minPoolExpOf2 if < 0 || >= len(pools) { return -1 } return }