gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/pool/slice-pool.go (about)

     1  package pool
     2  
     3  import (
     4  	"gitee.com/sy_183/go-common/option"
     5  	"sync"
     6  )
     7  
     8  type SlicePool[O any] struct {
     9  	slice []O
    10  	newFn func(p *SlicePool[O]) O
    11  	limiter
    12  	mu sync.Mutex
    13  }
    14  
    15  func NewSlicePool[O any](new func(p *SlicePool[O]) O, options ...option.AnyOption) *SlicePool[O] {
    16  	p := &SlicePool[O]{newFn: new}
    17  	for _, opt := range options {
    18  		opt.Apply(p)
    19  	}
    20  	return p
    21  }
    22  
    23  func ProvideSlicePool[O any](new func(p Pool[O]) O, options ...option.AnyOption) Pool[O] {
    24  	return NewSlicePool(func(p *SlicePool[O]) O {
    25  		return new(p)
    26  	}, options...)
    27  }
    28  
    29  func (p *SlicePool[O]) Len() int {
    30  	p.mu.Lock()
    31  	defer p.mu.Unlock()
    32  	return len(p.slice)
    33  }
    34  
    35  func (p *SlicePool[O]) Cap() int {
    36  	p.mu.Lock()
    37  	defer p.mu.Unlock()
    38  	return cap(p.slice)
    39  }
    40  
    41  func (p *SlicePool[O]) getCached() (o O, ok bool) {
    42  	p.mu.Lock()
    43  	defer p.mu.Unlock()
    44  	ok = true
    45  	if !p.alloc() {
    46  		return
    47  	}
    48  	l := len(p.slice)
    49  	if l == 0 {
    50  		ok = false
    51  		return
    52  	}
    53  	o = p.slice[l-1]
    54  	p.slice = p.slice[:l-1]
    55  	return
    56  }
    57  
    58  func (p *SlicePool[O]) Get() (o O) {
    59  	var ok bool
    60  	o, ok = p.getCached()
    61  	if ok {
    62  		return
    63  	}
    64  	return p.newFn(p)
    65  }
    66  
    67  func (p *SlicePool[O]) Put(obj O) {
    68  	p.mu.Lock()
    69  	defer p.mu.Unlock()
    70  	p.slice = append(p.slice, obj)
    71  	p.release()
    72  }