handle.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package go_int32_handle
  2. import (
  3. "fmt"
  4. "github.com/gammazero/deque"
  5. "sync"
  6. )
  7. type Payload interface {
  8. }
  9. var ErrHandleExceedMax = fmt.Errorf("handle exceed max")
  10. type HandleManager[T Payload] struct {
  11. handles map[int32]T
  12. lock sync.RWMutex
  13. counter int32
  14. releasedHandles *deque.Deque[int32]
  15. max int32
  16. }
  17. // New returns a new handle manager, same as NewWithRange(0, 2147483647)
  18. func New[T Payload]() *HandleManager[T] {
  19. return &HandleManager[T]{
  20. handles: make(map[int32]T),
  21. releasedHandles: deque.New[int32](),
  22. counter: 0,
  23. lock: sync.RWMutex{},
  24. max: 2147483647,
  25. }
  26. }
  27. // NewWithRange returns a new handle manager.
  28. // `shouldAbove` is the first handle - 1. this should be greater than 0 or equal to 0.
  29. // `max` is the last handle. this should be greater than 0.
  30. func NewWithRange[T Payload](shouldAbove int32, max int32) *HandleManager[T] {
  31. return &HandleManager[T]{
  32. handles: make(map[int32]T),
  33. releasedHandles: deque.New[int32](),
  34. counter: shouldAbove,
  35. lock: sync.RWMutex{},
  36. max: max,
  37. }
  38. }
  39. func (hm *HandleManager[T]) getNewHandle() int32 {
  40. if hm.releasedHandles.Len() > 0 {
  41. return hm.releasedHandles.PopFront()
  42. } else {
  43. hm.counter = hm.counter + 1
  44. return hm.counter
  45. }
  46. }
  47. func (hm *HandleManager[T]) AllocateAndPut(value T) (int32, error) {
  48. hm.lock.Lock()
  49. defer hm.lock.Unlock()
  50. h := hm.getNewHandle()
  51. if h >= hm.max {
  52. return 0, ErrHandleExceedMax
  53. }
  54. _, ok := hm.handles[h]
  55. if ok {
  56. return 0, fmt.Errorf("internal error: failed to allocate handle: next val %d is already in use", h)
  57. }
  58. hm.handles[h] = value
  59. return h, nil
  60. }
  61. func (hm *HandleManager[T]) Get(h int32) (T, bool) {
  62. hm.lock.RLock()
  63. defer hm.lock.RUnlock()
  64. if h <= 0 {
  65. var emptyT T
  66. return emptyT, false
  67. }
  68. value, ok := hm.handles[h]
  69. return value, ok
  70. }
  71. func (hm *HandleManager[T]) Release(h int32) (T, bool) {
  72. hm.lock.Lock()
  73. defer hm.lock.Unlock()
  74. if h <= 0 {
  75. var emptyT T
  76. return emptyT, false
  77. }
  78. value, ok := hm.handles[h]
  79. if ok {
  80. delete(hm.handles, h)
  81. hm.releasedHandles.PushBack(h)
  82. }
  83. return value, ok
  84. }
  85. func (hm *HandleManager[T]) ReleaseSilently(h int32) {
  86. hm.lock.Lock()
  87. defer hm.lock.Unlock()
  88. if h <= 0 {
  89. return
  90. }
  91. _, ok := hm.handles[h]
  92. if ok {
  93. delete(hm.handles, h)
  94. hm.releasedHandles.PushBack(h)
  95. }
  96. }
  97. func (hm *HandleManager[T]) Count() int {
  98. hm.lock.RLock()
  99. defer hm.lock.RUnlock()
  100. return len(hm.handles)
  101. }