81 lines
1.8 KiB
Go
81 lines
1.8 KiB
Go
package fixedpool
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/karmada-io/karmada/pkg/metrics"
|
|
)
|
|
|
|
// A FixedPool like sync.Pool. But it's limited capacity.
|
|
// When pool is full, Put will abandon and call destroyFunc to destroy the object.
|
|
type FixedPool struct {
|
|
name string
|
|
lock sync.Mutex
|
|
pool []any
|
|
capacity int
|
|
|
|
newFunc func() (any, error)
|
|
destroyFunc func(any)
|
|
}
|
|
|
|
// New return a FixedPool
|
|
func New(name string, newFunc func() (any, error), destroyFunc func(any), capacity int) *FixedPool {
|
|
return &FixedPool{
|
|
name: name,
|
|
pool: make([]any, 0, capacity),
|
|
capacity: capacity,
|
|
newFunc: newFunc,
|
|
destroyFunc: destroyFunc,
|
|
}
|
|
}
|
|
|
|
// Get selects an arbitrary item from the pool, removes it from the
|
|
// pool, and returns it to the caller.
|
|
// Get may choose to ignore the pool and treat it as empty.
|
|
// Callers should not assume any relation between values passed to Put and
|
|
// the values returned by Get.
|
|
//
|
|
// If pool is empty, Get returns the result of calling newFunc.
|
|
func (p *FixedPool) Get() (any, error) {
|
|
o, ok := p.pop()
|
|
if ok {
|
|
metrics.RecordPoolGet(p.name, false)
|
|
return o, nil
|
|
}
|
|
|
|
metrics.RecordPoolGet(p.name, true)
|
|
return p.newFunc()
|
|
}
|
|
|
|
// Put adds x to the pool. If pool is full, x will be abandoned,
|
|
// and it's destroy function will be called.
|
|
func (p *FixedPool) Put(x any) {
|
|
if p.push(x) {
|
|
metrics.RecordPoolPut(p.name, false)
|
|
return
|
|
}
|
|
metrics.RecordPoolPut(p.name, true)
|
|
p.destroyFunc(x)
|
|
}
|
|
|
|
func (p *FixedPool) pop() (any, bool) {
|
|
p.lock.Lock()
|
|
defer p.lock.Unlock()
|
|
if s := len(p.pool); s > 0 {
|
|
o := p.pool[s-1]
|
|
p.pool = p.pool[:s-1]
|
|
return o, true
|
|
}
|
|
return nil, false
|
|
}
|
|
|
|
func (p *FixedPool) push(o any) bool {
|
|
p.lock.Lock()
|
|
defer p.lock.Unlock()
|
|
if s := len(p.pool); s < p.capacity {
|
|
p.pool = append(p.pool, o)
|
|
return true
|
|
}
|
|
return false
|
|
}
|