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

     1  package pool
     2  
     3  import (
     4  	"gitee.com/sy_183/go-common/option"
     5  	"sync"
     6  )
     7  
     8  type StackPool[O any] struct {
     9  	stack []O
    10  	mu    sync.Mutex
    11  }
    12  
    13  func NewStackPool[O any](new func(p *StackPool[O]) O, size uint, options ...option.AnyOption) *StackPool[O] {
    14  	if size == 0 {
    15  		size = 1
    16  	}
    17  	p := &StackPool[O]{stack: make([]O, size)}
    18  	for _, opt := range options {
    19  		opt.Apply(p)
    20  	}
    21  	for i := range p.stack {
    22  		p.stack[i] = new(p)
    23  	}
    24  	return p
    25  }
    26  
    27  func StackPoolProvider[O any](size uint) PoolProvider[O] {
    28  	return func(new func(p Pool[O]) O, options ...option.AnyOption) Pool[O] {
    29  		return NewStackPool(func(p *StackPool[O]) O {
    30  			return new(p)
    31  		}, size, options...)
    32  	}
    33  }
    34  
    35  func (p *StackPool[O]) Len() int {
    36  	p.mu.Lock()
    37  	defer p.mu.Unlock()
    38  	return len(p.stack)
    39  }
    40  
    41  func (p *StackPool[O]) Cap() int {
    42  	return cap(p.stack)
    43  }
    44  
    45  func (p *StackPool[O]) Get() (o O) {
    46  	p.mu.Lock()
    47  	defer p.mu.Unlock()
    48  	l := len(p.stack)
    49  	if l == 0 {
    50  		return
    51  	}
    52  	o = p.stack[l-1]
    53  	p.stack = p.stack[:l-1]
    54  	return
    55  }
    56  
    57  func (p *StackPool[O]) Put(obj O) {
    58  	p.mu.Lock()
    59  	defer p.mu.Unlock()
    60  	if len(p.stack) == cap(p.stack) {
    61  		return
    62  	}
    63  	p.stack = append(p.stack, obj)
    64  }