pool.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package util
  2. import (
  3. "sync"
  4. )
  5. // A pool of vector maps for mapping float64 timestamps
  6. // to float64 values
  7. type VectorMapPool interface {
  8. Get() map[uint64]float64
  9. Put(map[uint64]float64)
  10. }
  11. // ------------
  12. // A buffered channel implementation of a vector map pool which
  13. // controls the total number of maps allowed in/out of the pool
  14. // at any given moment. Attempting to Get() with no available
  15. // maps will block until one is available. You will be unable to
  16. // Put() a map if the buffer is full.
  17. type FixedMapPool struct {
  18. maps chan map[uint64]float64
  19. size int
  20. }
  21. // Returns a map from the pool. Blocks if no maps are available for re-use
  22. func (mp *FixedMapPool) Get() map[uint64]float64 {
  23. return <-mp.maps
  24. }
  25. // Adds a map back to the pool if there is room. Does not block on overflow.
  26. func (mp *FixedMapPool) Put(m map[uint64]float64) {
  27. if len(mp.maps) >= mp.size {
  28. return
  29. }
  30. for k := range m {
  31. delete(m, k)
  32. }
  33. mp.maps <- m
  34. }
  35. // Creates a new fixed map pool which maintains a fixed pool size
  36. func NewFixedMapPool(size int) VectorMapPool {
  37. mp := &FixedMapPool{
  38. maps: make(chan map[uint64]float64, size),
  39. size: size,
  40. }
  41. // Pre-Populate the buffer with maps
  42. for i := 0; i < size; i++ {
  43. mp.maps <- make(map[uint64]float64)
  44. }
  45. return mp
  46. }
  47. // ------------
  48. // A buffered channel implementation of a vector map pool which
  49. // controls the total number of maps allowed in/out of the pool
  50. // at any given moment. Unlike the FixedMapPool, this pool will
  51. // not block if maps are over requested, but will only maintain
  52. // a buffer up the size limitation.
  53. type FlexibleMapPool struct {
  54. maps chan map[uint64]float64
  55. }
  56. // Returns a map from the pool. Does not block on over-request.
  57. func (mp *FlexibleMapPool) Get() map[uint64]float64 {
  58. select {
  59. case m := <-mp.maps:
  60. return m
  61. default:
  62. return make(map[uint64]float64)
  63. }
  64. }
  65. // Adds a map back to the pool if there is room. Does not block on overflow.
  66. func (mp *FlexibleMapPool) Put(m map[uint64]float64) {
  67. for k := range m {
  68. delete(m, k)
  69. }
  70. // Either return the map to the buffered channel, or do nothing
  71. select {
  72. case mp.maps <- m:
  73. return
  74. default:
  75. return
  76. }
  77. }
  78. // Creates a new fixed map pool which maintains a fixed pool size
  79. func NewFlexibleMapPool(size int) VectorMapPool {
  80. return &FlexibleMapPool{
  81. maps: make(chan map[uint64]float64, size),
  82. }
  83. }
  84. // ------------
  85. // Implementation backed by sync.Pool
  86. type UnboundedMapPool struct {
  87. maps *sync.Pool
  88. }
  89. // Returns a map from the pool. Does not block on over-request.
  90. func (mp *UnboundedMapPool) Get() map[uint64]float64 {
  91. return mp.maps.Get().(map[uint64]float64)
  92. }
  93. // Adds a map back to the pool if there is room. Does not block on overflow.
  94. func (mp *UnboundedMapPool) Put(m map[uint64]float64) {
  95. for k := range m {
  96. delete(m, k)
  97. }
  98. mp.maps.Put(m)
  99. }
  100. // Creates a new unbounded map pool which allows the runtime to decide when
  101. // pooled values should be evicted
  102. func NewUnboundedMapPool() VectorMapPool {
  103. return &UnboundedMapPool{
  104. maps: &sync.Pool{
  105. New: func() interface{} {
  106. return make(map[uint64]float64)
  107. },
  108. },
  109. }
  110. }