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  }