github.com/kiali/kiali@v1.84.0/tracing/tempo/tempopb/pool/pool.go (about) 1 // Forked with love from: https://github.com/prometheus/prometheus/tree/c954cd9d1d4e3530be2939d39d8633c38b70913f/util/pool 2 // This package was forked to provide better protection against putting byte slices back into the pool that 3 // did not originate from it. 4 5 package pool 6 7 import ( 8 "sync" 9 ) 10 11 // Pool is a bucketed pool for variably sized byte slices. 12 type Pool struct { 13 buckets []sync.Pool 14 sizes []int 15 // make is the function used to create an empty slice when none exist yet. 16 make func(int) []byte 17 } 18 19 // New returns a new Pool with size buckets for minSize to maxSize 20 // increasing by the given factor. 21 func New(minSize, maxSize int, factor float64, makeFunc func(int) []byte) *Pool { 22 if minSize < 1 { 23 panic("invalid minimum pool size") 24 } 25 if maxSize < 1 { 26 panic("invalid maximum pool size") 27 } 28 if factor < 1 { 29 panic("invalid factor") 30 } 31 32 var sizes []int 33 34 for s := minSize; s <= maxSize; s = int(float64(s) * factor) { 35 sizes = append(sizes, s) 36 } 37 38 p := &Pool{ 39 buckets: make([]sync.Pool, len(sizes)), 40 sizes: sizes, 41 make: makeFunc, 42 } 43 44 return p 45 } 46 47 // Get returns a new byte slices that fits the given size. 48 func (p *Pool) Get(sz int) []byte { 49 for i, bktSize := range p.sizes { 50 if sz > bktSize { 51 continue 52 } 53 b := p.buckets[i].Get() 54 if b == nil { 55 b = p.make(bktSize) 56 } 57 return b.([]byte) 58 } 59 return p.make(sz) 60 } 61 62 // Put adds a slice to the right bucket in the pool. This method has been adjusted from its initial 63 // implementation to ignore byte slices that dont have the correct size 64 func (p *Pool) Put(s []byte) { 65 c := cap(s) 66 for i, size := range p.sizes { 67 if c == size { 68 p.buckets[i].Put(s) // nolint: staticcheck 69 } 70 if c < size { 71 return 72 } 73 } 74 }