-
Notifications
You must be signed in to change notification settings - Fork 10
/
inmemorydb.go
139 lines (111 loc) · 4.08 KB
/
inmemorydb.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
package inmemorydb
import (
"fmt"
"github.com/alexandre-normand/slackscot/store"
)
// InMemoryDB implements the slackscot GlobalSiloStringStorer interface and keeps
// a copy of everything in memory while writing through puts and deletes
// to the wrapped (persistent) GlobalSiloStringStorer
type InMemoryDB struct {
persistentStorer store.GlobalSiloStringStorer
data map[string]map[string]string
}
// New returns a new instance of InMemoryDB wrapping the persistent GlobalSiloStringStorer.
// Note that instantiation might have some latency induced by the initial scan to load
// the current database content from the persistentStorer in memory
func New(storer store.GlobalSiloStringStorer) (imdb *InMemoryDB, err error) {
imdb = new(InMemoryDB)
imdb.persistentStorer = storer
imdb.data, err = imdb.persistentStorer.GlobalScan()
if err != nil {
return nil, err
}
return imdb, nil
}
// GetString returns the value associated to a given key. If the value is not
// found or an error occurred, the zero-value string is returned along with
// the error
func (imdb *InMemoryDB) GetString(key string) (value string, err error) {
return imdb.GetSiloString("", key)
}
// GetSiloString returns the value associated to a given key in the given silo.
// If the value is not found or an error occurred, the zero-value string is returned along with
// the error
func (imdb *InMemoryDB) GetSiloString(silo string, key string) (value string, err error) {
s, ok := imdb.data[silo]
if !ok {
return "", fmt.Errorf("%s not found", key)
}
v, ok := s[key]
if !ok {
return "", fmt.Errorf("%s not found", key)
}
return v, nil
}
// PutString stores the key/value to the database. The key/value is persisted to
// persistent storage and also kept in memory
func (imdb *InMemoryDB) PutString(key string, value string) (err error) {
return imdb.PutSiloString("", key, value)
}
// PutSiloString stores the key/value to a silo the database. The key/value is persisted to
// persistent storage and also kept in memory
func (imdb *InMemoryDB) PutSiloString(silo string, key string, value string) (err error) {
err = imdb.persistentStorer.PutSiloString(silo, key, value)
if err != nil {
return err
}
if _, ok := imdb.data[silo]; !ok {
imdb.data[silo] = make(map[string]string)
}
imdb.data[silo][key] = value
return nil
}
// DeleteString deletes the entry for the given key. This is propagated to the
// persistent storage first and then deleted from memory
func (imdb *InMemoryDB) DeleteString(key string) (err error) {
return imdb.DeleteSiloString("", key)
}
// DeleteSiloString deletes the silo entry for the given key. This is propagated to the
// persistent storage first and then deleted from memory
func (imdb *InMemoryDB) DeleteSiloString(silo string, key string) (err error) {
err = imdb.persistentStorer.DeleteSiloString(silo, key)
if err != nil {
return err
}
if s, ok := imdb.data[silo]; ok {
delete(s, key)
}
return nil
}
// Scan returns all key/values from the database. This one returns a copy of the in-memory
// copy without querying the persistent storer.
func (imdb *InMemoryDB) Scan() (entries map[string]string, err error) {
return imdb.ScanSilo("")
}
// ScanSilo returns all key/values for a silo from the database. This one returns a copy of the in-memory
// copy without querying the persistent storer.
func (imdb *InMemoryDB) ScanSilo(silo string) (entries map[string]string, err error) {
entries = make(map[string]string)
for k, v := range imdb.data[silo] {
entries[k] = v
}
return entries, nil
}
// GlobalScan returns all key/values from the database. This one returns a copy of the in-memory
// copy without querying the persistent storer.
func (imdb *InMemoryDB) GlobalScan() (entries map[string]map[string]string, err error) {
entries = make(map[string]map[string]string)
for s, sc := range imdb.data {
for k, v := range sc {
if _, ok := entries[s]; !ok {
entries[s] = make(map[string]string)
}
entries[s][k] = v
}
}
return entries, nil
}
// Close closes the underlying storer
func (imdb *InMemoryDB) Close() (err error) {
return imdb.persistentStorer.Close()
}