forked from pocketbase/pocketbase
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstore.go
133 lines (100 loc) · 2.68 KB
/
store.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package store
import "sync"
// Store defines a concurrent safe in memory key-value data store.
type Store[T any] struct {
mux sync.RWMutex
data map[string]T
}
// New creates a new Store[T] instance with a shallow copy of the provided data (if any).
func New[T any](data map[string]T) *Store[T] {
s := &Store[T]{}
s.Reset(data)
return s
}
// Reset clears the store and replaces the store data with a
// shallow copy of the provided newData.
func (s *Store[T]) Reset(newData map[string]T) {
s.mux.Lock()
defer s.mux.Unlock()
var clone = make(map[string]T, len(newData))
for k, v := range newData {
clone[k] = v
}
s.data = clone
}
// Length returns the current number of elements in the store.
func (s *Store[T]) Length() int {
s.mux.RLock()
defer s.mux.RUnlock()
return len(s.data)
}
// RemoveAll removes all the existing store entries.
func (s *Store[T]) RemoveAll() {
s.mux.Lock()
defer s.mux.Unlock()
s.data = make(map[string]T)
}
// Remove removes a single entry from the store.
//
// Remove does nothing if key doesn't exist in the store.
func (s *Store[T]) Remove(key string) {
s.mux.Lock()
defer s.mux.Unlock()
delete(s.data, key)
}
// Has checks if element with the specified key exist or not.
func (s *Store[T]) Has(key string) bool {
s.mux.RLock()
defer s.mux.RUnlock()
_, ok := s.data[key]
return ok
}
// Get returns a single element value from the store.
//
// If key is not set, the zero T value is returned.
func (s *Store[T]) Get(key string) T {
s.mux.RLock()
defer s.mux.RUnlock()
return s.data[key]
}
// GetAll returns a shallow copy of the current store data.
func (s *Store[T]) GetAll() map[string]T {
s.mux.RLock()
defer s.mux.RUnlock()
var clone = make(map[string]T, len(s.data))
for k, v := range s.data {
clone[k] = v
}
return clone
}
// Set sets (or overwrite if already exist) a new value for key.
func (s *Store[T]) Set(key string, value T) {
s.mux.Lock()
defer s.mux.Unlock()
if s.data == nil {
s.data = make(map[string]T)
}
s.data[key] = value
}
// SetIfLessThanLimit sets (or overwrite if already exist) a new value for key.
//
// This method is similar to Set() but **it will skip adding new elements**
// to the store if the store length has reached the specified limit.
// false is returned if maxAllowedElements limit is reached.
func (s *Store[T]) SetIfLessThanLimit(key string, value T, maxAllowedElements int) bool {
s.mux.Lock()
defer s.mux.Unlock()
// init map if not already
if s.data == nil {
s.data = make(map[string]T)
}
// check for existing item
_, ok := s.data[key]
if !ok && len(s.data) >= maxAllowedElements {
// cannot add more items
return false
}
// add/overwrite item
s.data[key] = value
return true
}