diff --git a/pool/pool.go b/pool/pool.go new file mode 100644 index 0000000..b80a99f --- /dev/null +++ b/pool/pool.go @@ -0,0 +1,41 @@ +package pool + +type pool[T any] struct { + noCopy struct{} + c chan T + new func() T +} + +func NewPool[T any](poolSize int) *pool[T] { + return &pool[T]{ + c: make(chan T, poolSize), + } +} + +func NewPoolWithNew[T any](poolSize int, f func() T) *pool[T] { + return &pool[T]{ + c: make(chan T, poolSize), + new: f, + } +} + +func (p *pool[T]) Get() (o T) { + select { + case o = <-p.c: + default: + if p.new != nil { + o = p.new() + } else { + o = *new(T) + } + } + + return +} + +func (p *pool[T]) Put(o T) { + select { + case p.c <- o: + default: + } +} diff --git a/pool/pool_test.go b/pool/pool_test.go new file mode 100644 index 0000000..bcaf577 --- /dev/null +++ b/pool/pool_test.go @@ -0,0 +1,54 @@ +package pool_test + +import ( + "testing" + + "github.com/charlienet/go-mixed/pool" +) + +type PoolObject struct { + Name string +} + +func TestPool(t *testing.T) { + p := pool.NewPool[PoolObject](10) + o := p.Get() + o.Name = "abc" + t.Logf("%p", &o) + + p.Put(o) + o2 := p.Get() + t.Logf("取出对象:%s %p", o2, &o2) +} + +func TestPoolSize(t *testing.T) { + p := pool.NewPool[PoolObject](10) + for i := 0; i < 15; i++ { + o := p.Get() + t.Logf("%02d 取出对象:%p %v %s", i, &o, o, o.Name) + + if i%2 == 0 { + p.Put(o) + } + } +} + +func TestPut(t *testing.T) { + p := pool.NewPool[PoolObject](10) + for i := 0; i < 15; i++ { + p.Put(PoolObject{}) + } + + t.Logf("%+v", *p) +} + +func BenchmarkPool(b *testing.B) { + p := pool.NewPool[int](100) + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + p.Put(1) + p.Get() + } + }) +}