store.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. package store
  2. import (
  3. "sync"
  4. )
  5. type CallCreate func(key any) (value any, created bool)
  6. type CallCreateMulti func(key any) (m map[any]any, created bool)
  7. type CallCheck func(key, value any, exists bool) (rKey, rValue any, created bool)
  8. func FromMap(m map[any]any) *Store {
  9. return &Store{
  10. locker: new(sync.RWMutex),
  11. items: m,
  12. }
  13. }
  14. func New() *Store {
  15. return &Store{
  16. locker: new(sync.RWMutex),
  17. items: make(map[any]any),
  18. }
  19. }
  20. type Store struct {
  21. locker *sync.RWMutex
  22. items map[any]any
  23. }
  24. func (s *Store) delete(key any) (any, bool) {
  25. item, check := s.items[key]
  26. delete(s.items, key)
  27. return item, check
  28. }
  29. func (s *Store) Delete(key any) (any, bool) {
  30. s.locker.Lock()
  31. item, check := s.delete(key)
  32. s.locker.Unlock()
  33. return item, check
  34. }
  35. func (s *Store) DeleteMulti(keys []any) {
  36. s.locker.Lock()
  37. for _, key := range keys {
  38. delete(s.items, key)
  39. }
  40. s.locker.Unlock()
  41. }
  42. func (s *Store) set(key, val any) {
  43. s.items[key] = val
  44. }
  45. func (s *Store) setMulti(m map[any]any) {
  46. for key, val := range m {
  47. s.items[key] = val
  48. }
  49. }
  50. func (s *Store) Set(key, val any) {
  51. s.locker.Lock()
  52. s.set(key, val)
  53. s.locker.Unlock()
  54. }
  55. func (s *Store) SetMulti(m map[any]any) {
  56. s.locker.Lock()
  57. s.setMulti(m)
  58. s.locker.Unlock()
  59. }
  60. func (s *Store) get(key any) (val any, check bool) {
  61. val, check = s.items[key]
  62. return
  63. }
  64. func (s *Store) Get(key any) (val any, check bool) {
  65. s.locker.RLock()
  66. val, check = s.get(key)
  67. s.locker.RUnlock()
  68. return
  69. }
  70. func (s *Store) GetCreate(key any, mCreate CallCreate) (res any, check bool) {
  71. if res, check = s.Get(key); !check {
  72. s.locker.Lock()
  73. if res, check = s.get(key); check {
  74. s.locker.Unlock()
  75. return
  76. }
  77. if res, check = mCreate(key); check {
  78. s.set(key, res)
  79. }
  80. s.locker.Unlock()
  81. }
  82. return
  83. }
  84. func (s *Store) GetCreateMulti(key any, mCreateMulti CallCreateMulti) (res any, check bool) {
  85. if res, check = s.Get(key); !check {
  86. s.locker.Lock()
  87. if res, check = s.get(key); check {
  88. s.locker.Unlock()
  89. return
  90. }
  91. var m map[any]any
  92. if m, check = mCreateMulti(key); check {
  93. s.setMulti(m)
  94. res, check = s.items[key]
  95. }
  96. s.locker.Unlock()
  97. }
  98. return
  99. }
  100. func (s *Store) GetCheck(key any, mCheck CallCheck) (res any, check bool) {
  101. s.locker.Lock()
  102. res, check = s.get(key)
  103. if rKey, rVal, rCheck := mCheck(key, res, check); rCheck {
  104. s.set(rKey, rVal)
  105. key, res, check = rKey, rVal, true
  106. }
  107. s.locker.Unlock()
  108. return
  109. }
  110. // Each implements a map bypass for each key using the callback function. If the callback function returns false, then the cycle stops
  111. func (s *Store) Each(callback func(any, any) bool) {
  112. s.locker.RLock()
  113. for key, val := range s.items {
  114. if !callback(key, val) {
  115. s.locker.RUnlock()
  116. return
  117. }
  118. }
  119. s.locker.RUnlock()
  120. }
  121. func (s *Store) Len() (res int) {
  122. s.locker.RLock()
  123. res = len(s.items)
  124. s.locker.RUnlock()
  125. return
  126. }
  127. func (s *Store) Keys() (res []any) {
  128. s.locker.RLock()
  129. res = make([]any, 0, len(s.items))
  130. for key := range s.items {
  131. res = append(res, key)
  132. }
  133. s.locker.RUnlock()
  134. return
  135. }
  136. func (s *Store) Clear() {
  137. s.locker.Lock()
  138. s.items = make(map[any]any)
  139. s.locker.Unlock()
  140. }
  141. func (s *Store) Map() (res map[any]any) {
  142. res = make(map[any]any)
  143. s.locker.RLock()
  144. for key, val := range s.items {
  145. res[key] = val
  146. }
  147. s.locker.RUnlock()
  148. return
  149. }