github.com/m3db/m3@v1.5.0/src/aggregator/aggregation/quantile/cm/heap_pool.go (about) 1 // Copyright (c) 2021 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package cm 22 23 import ( 24 "sync" 25 ) 26 27 const ( 28 // create buckets of 64, 256, 1024, 4096, 16484, 65536 floats 29 _initialHeapBucketSize = 64 30 _heapSizeBuckets = 6 31 _heapSizeBucketGrowthFactor = 4 32 ) 33 34 var sharedHeapPool heapPool 35 36 type heapPool struct { 37 pools []*sync.Pool 38 sizes []int 39 } 40 41 func newHeapPool() heapPool { 42 var ( 43 p = heapPool{ 44 pools: make([]*sync.Pool, _heapSizeBuckets), 45 sizes: make([]int, _heapSizeBuckets), 46 } 47 sz = _initialHeapBucketSize 48 ) 49 50 for i := 0; i < _heapSizeBuckets; i++ { 51 size := sz 52 53 p.sizes[i] = size 54 p.pools[i] = &sync.Pool{ 55 New: func() interface{} { 56 buf := make(minHeap, 0, size) 57 return &buf 58 }, 59 } 60 61 sz *= _heapSizeBucketGrowthFactor 62 } 63 64 return p 65 } 66 67 func (p heapPool) Get(size int) *minHeap { 68 for i := range p.sizes { 69 if p.sizes[i] < size { 70 continue 71 } 72 73 v, ok := p.pools[i].Get().(*minHeap) 74 if !ok { // should never happen 75 goto makeNew 76 } 77 78 *v = (*v)[:0] 79 return v 80 } 81 makeNew: 82 newVal := make(minHeap, 0, size) 83 84 return &newVal 85 } 86 87 func (p heapPool) Put(value minHeap) { 88 size := cap(value) 89 for i := 0; i < len(p.sizes); i++ { 90 if p.sizes[i] < size { 91 continue 92 } 93 pool := p.pools[i] 94 value = value[:0] 95 pool.Put(&value) 96 return 97 } 98 } 99 100 func init() { 101 sharedHeapPool = newHeapPool() 102 }