pool.go 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package dynamic
  2. import (
  3. "reflect"
  4. "sync"
  5. )
  6. var UsePool bool
  7. type Reset interface {
  8. Reset()
  9. }
  10. var reflectTypePools = &typePools{
  11. pools: make(map[reflect.Type]*sync.Pool),
  12. New: func(t reflect.Type) interface{} {
  13. var argv reflect.Value
  14. if t.Kind() == reflect.Ptr { // reply must be ptr
  15. argv = reflect.New(t.Elem())
  16. } else {
  17. argv = reflect.New(t)
  18. }
  19. return argv.Interface()
  20. },
  21. }
  22. type typePools struct {
  23. mu sync.RWMutex
  24. pools map[reflect.Type]*sync.Pool
  25. New func(t reflect.Type) interface{}
  26. }
  27. func (p *typePools) Init(t reflect.Type) {
  28. tp := &sync.Pool{}
  29. tp.New = func() interface{} {
  30. return p.New(t)
  31. }
  32. p.mu.Lock()
  33. defer p.mu.Unlock()
  34. p.pools[t] = tp
  35. }
  36. func (p *typePools) Put(t reflect.Type, x interface{}) {
  37. if !UsePool {
  38. return
  39. }
  40. if o, ok := x.(Reset); ok {
  41. o.Reset()
  42. }
  43. p.mu.RLock()
  44. pool := p.pools[t]
  45. p.mu.RUnlock()
  46. pool.Put(x)
  47. }
  48. func (p *typePools) Get(t reflect.Type) interface{} {
  49. if !UsePool {
  50. return p.New(t)
  51. }
  52. p.mu.RLock()
  53. pool := p.pools[t]
  54. p.mu.RUnlock()
  55. return pool.Get()
  56. }