gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/pool/dynamic-data-pool.go (about) 1 package pool 2 3 import ( 4 "gitee.com/sy_183/go-common/option" 5 "sort" 6 ) 7 8 type DynamicDataPool struct { 9 pools []*StaticDataPool 10 sizes []uint 11 } 12 13 func NewDynamicDataPool(pools ...*StaticDataPool) *DynamicDataPool { 14 sort.Slice(pools, func(i, j int) bool { 15 return pools[i].Size() < pools[j].Size() 16 }) 17 p := new(DynamicDataPool) 18 var last uint 19 for _, pool := range pools { 20 if size := pool.Size(); size > last { 21 p.pools = append(p.pools, pool) 22 p.sizes = append(p.sizes, size) 23 last = size 24 } 25 } 26 return p 27 } 28 29 func NewDynamicDataPoolWithThresholds(thresholds []int, poolProvider PoolProvider[*Data], poolOptions ...option.AnyOption) *DynamicDataPool { 30 sort.Ints(thresholds) 31 p := new(DynamicDataPool) 32 var last int 33 for _, threshold := range thresholds { 34 if threshold > last { 35 p.pools = append(p.pools, NewStaticDataPool(uint(threshold), poolProvider, poolOptions...)) 36 p.sizes = append(p.sizes, uint(threshold)) 37 last = threshold 38 } 39 } 40 return p 41 } 42 43 func NewDynamicDataPoolWithExp(min, max uint, poolProvider PoolProvider[*Data], poolOptions ...option.AnyOption) *DynamicDataPool { 44 var thresholds []int 45 for i := 1; i < 63; i++ { 46 if uint(1<<i) >= min && uint(1<<(i-1)) < max { 47 thresholds = append(thresholds, 1<<i) 48 } else if uint(1<<(i-1)) >= max { 49 break 50 } 51 } 52 return NewDynamicDataPoolWithThresholds(thresholds, poolProvider, poolOptions...) 53 } 54 55 func (p *DynamicDataPool) Alloc(len uint) *Data { 56 for i, pool := range p.pools { 57 if len <= p.sizes[i] { 58 return pool.Alloc(len) 59 } 60 } 61 return nil 62 } 63 64 func (p *DynamicDataPool) AllocCap(len, cap uint) *Data { 65 for i, pool := range p.pools { 66 if len <= p.sizes[i] { 67 return pool.AllocCap(len, cap) 68 } 69 } 70 return nil 71 }