forked from KurokuLabs/margo
/
db.go
143 lines (118 loc) · 2.62 KB
/
db.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
134
135
136
137
138
139
140
141
142
143
package mg
import (
"sync"
)
var (
_ KVStore = (KVStores)(nil)
_ KVStore = (*Store)(nil)
_ KVStore = (*KVMap)(nil)
)
// KVStore represents a generic key value store.
//
// All operations are safe for concurrent access.
//
// The main implementation in this and related packages is Store.
type KVStore interface {
// Put stores the value in the store with identifier key
// NOTE: use Del instead of storing nil
Put(key, value interface{})
// Get returns the value stored using identifier key
// NOTE: if the value doesn't exist, nil is returned
Get(key interface{}) interface{}
// Del removes the value identified by key from the store
Del(key interface{})
}
// KVStores implements a KVStore that duplicates its operations on a list of k/v stores
//
// NOTE: All operations are no-ops for nil KVStores
type KVStores []KVStore
// Put calls .Put on each of k/v stores in the list
func (kvl KVStores) Put(k, v interface{}) {
for _, kvs := range kvl {
if kvs == nil {
continue
}
kvs.Put(k, v)
}
}
// Get returns the first value identified by k found in the list of k/v stores
func (kvl KVStores) Get(k interface{}) interface{} {
for _, kvs := range kvl {
if kvs == nil {
continue
}
if v := kvs.Get(k); v != nil {
return v
}
}
return nil
}
// Del removed the value identified by k from all k/v stores in the list
func (kvl KVStores) Del(k interface{}) {
for _, kvs := range kvl {
if kvs == nil {
continue
}
kvs.Del(k)
}
}
// KVMap implements a KVStore using a map.
// The zero-value is safe for use with all operations.
//
// NOTE: All operations are no-ops on a nil KVMap
type KVMap struct {
vals map[interface{}]interface{}
mu sync.Mutex
}
// Put implements KVStore.Put
func (m *KVMap) Put(k interface{}, v interface{}) {
if m == nil {
return
}
m.mu.Lock()
defer m.mu.Unlock()
if m.vals == nil {
m.vals = map[interface{}]interface{}{}
}
m.vals[k] = v
}
// Get implements KVStore.Get
func (m *KVMap) Get(k interface{}) interface{} {
if m == nil {
return nil
}
m.mu.Lock()
defer m.mu.Unlock()
return m.vals[k]
}
// Del implements KVStore.Del
func (m *KVMap) Del(k interface{}) {
if m == nil {
return
}
m.mu.Lock()
defer m.mu.Unlock()
delete(m.vals, k)
}
// Clear removes all values from the store
func (m *KVMap) Clear() {
if m == nil {
return
}
m.mu.Lock()
defer m.mu.Unlock()
m.vals = nil
}
// Values returns a copy of all values stored
func (m *KVMap) Values() map[interface{}]interface{} {
if m == nil {
return nil
}
m.mu.Lock()
defer m.mu.Unlock()
vals := make(map[interface{}]interface{}, len(m.vals))
for k, v := range m.vals {
vals[k] = v
}
return vals
}