github.com/abemedia/go-don@v0.2.2-0.20240329015135-be88e32bb73b/pool.go (about) 1 package don 2 3 import ( 4 "reflect" 5 "sync" 6 ) 7 8 type pool[T any] interface { 9 Get() *T 10 Put(x *T) 11 } 12 13 type requestPool[T any] struct { 14 pool sync.Pool 15 reset func(*T) 16 } 17 18 func newRequestPool[T any](zero T) pool[T] { 19 typ := reflect.TypeOf(zero) 20 if typ == nil { 21 return &fakePool[T]{&zero} 22 } 23 24 p := &requestPool[T]{} 25 26 if typ.Kind() != reflect.Pointer { 27 p.pool.New = func() any { 28 return new(T) 29 } 30 p.reset = func(v *T) { 31 *v = zero 32 } 33 } else { 34 rtype := dataOf(typ) 35 elem := typ.Elem() 36 elemrtype := dataOf(elem) 37 zero := dataOf(reflect.New(elem).Elem().Interface()) 38 39 p.pool.New = func() any { 40 v := packEface(rtype, unsafe_New(elemrtype)).(T) //nolint:forcetypeassert 41 return &v 42 } 43 p.reset = func(v *T) { 44 typedmemmove(elemrtype, dataOf(*v), zero) 45 } 46 } 47 48 return p 49 } 50 51 func (p *requestPool[T]) Get() *T { 52 return p.pool.Get().(*T) //nolint:forcetypeassert 53 } 54 55 func (p *requestPool[T]) Put(v *T) { 56 p.reset(v) 57 p.pool.Put(v) 58 } 59 60 type fakePool[T any] struct{ v *T } 61 62 func (p *fakePool[T]) Get() *T { return p.v } 63 64 func (p *fakePool[T]) Put(*T) {}