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 }