forked from keks/go-orbitdb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
kvstore.go
123 lines (96 loc) · 2 KB
/
kvstore.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
package orbitdb
import (
"fmt"
"sync"
"github.com/keks/go-ipfs-colog"
"github.com/zacharyestep/go-orbitdb/handler"
)
var (
// ErrNotFound is returned when the given key could not be found in the db.
ErrNotFound = fmt.Errorf("key not found")
)
type kvPayload struct {
Key string `json:"key"`
Value string `json:"value"`
handler.Op `json:"op"`
}
func kvCast(e *colog.Entry) (pl kvPayload, err error) {
err = e.Get(&pl)
return pl, err
}
type kvIndex struct {
l sync.Mutex
kv map[string]string
}
func (idx *kvIndex) handlePut(e *colog.Entry) error {
pl, err := kvCast(e)
if err != nil {
return err
}
idx.l.Lock()
idx.kv[pl.Key] = pl.Value
idx.l.Unlock()
return nil
}
func (idx *kvIndex) handleDel(e *colog.Entry) error {
pl, err := kvCast(e)
if err != nil {
return err
}
idx.l.Lock()
delete(idx.kv, pl.Key)
idx.l.Unlock()
return nil
}
func (idx *kvIndex) Get(key string) (value string, err error) {
var ok bool
idx.l.Lock()
value, ok = idx.kv[key]
idx.l.Unlock()
if !ok {
err = ErrNotFound
}
return value, err
}
// KVStore provides a key-value store on an OrbitDB.
type KVStore struct {
db *OrbitDB
idx *kvIndex
}
// NewKVStore returns a new KVStore for the given OrbitDB.
func NewKVStore(db *OrbitDB) *KVStore {
kvs := &KVStore{
db: db,
idx: &kvIndex{
kv: make(map[string]string),
},
}
mux := handler.NewMux()
mux.AddHandler(OpPut, kvs.idx.handlePut)
mux.AddHandler(OpDel, kvs.idx.handleDel)
go db.Notify(mux)
return kvs
}
// Put adds a key-value pair to the KVStore.
func (kv *KVStore) Put(key, value string) error {
payload := kvPayload{
Key: key,
Value: value,
Op: OpPut,
}
_, err := kv.db.Add(&payload)
return err
}
// Get retrieves the value stored at a given key.
func (kv *KVStore) Get(key string) (string, error) {
return kv.idx.Get(key)
}
// Delete deletes the value at the given key,
func (kv *KVStore) Delete(key string) error {
payload := kvPayload{
Key: key,
Op: OpDel,
}
_, err := kv.db.Add(&payload)
return err
}