-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprefix_wrapper.go
101 lines (82 loc) · 2.07 KB
/
prefix_wrapper.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
package raccoon
import (
"bytes"
)
// WrapperKV implements raccoon's KVStore to a KVStore by wrapping its methods with a global prefix
type WrapperKV struct {
store KVStore
prefix Key
}
func NewWrapperKV(store KVStore, prefix []byte) KVStore {
prefixKey := Key{}.Append(prefix)
return &WrapperKV{
store: store,
prefix: prefixKey,
}
}
func (kv *WrapperKV) Get(key []byte) ([]byte, error) {
key = kv.prefix.Append(key).ToBytes()
return kv.store.Get(key)
}
func (kv *WrapperKV) Has(key []byte) (bool, error) {
key = kv.prefix.Append(key).ToBytes()
return kv.store.Has(key)
}
func (kv *WrapperKV) Set(key, value []byte) error {
key = kv.prefix.Append(key).ToBytes()
return kv.store.Set(key, value)
}
func (kv *WrapperKV) Delete(key []byte) error {
key = kv.prefix.Append(key).ToBytes()
return kv.store.Delete(key)
}
func (kv *WrapperKV) Iterator(start, end []byte) Iterator {
return newPrefixIterator(kv.prefix, start, end, kv.store)
}
func newPrefixIterator(prefix Key, start, end []byte, store KVStore) *prefixIterator {
prefixBytes := prefix.Append(nil).ToBytes()
start = prefix.Append(start).ToBytes()
// if end is nil, the iterator must be unbounded
if end != nil {
end = prefix.Append(end).ToBytes()
}
iter := store.Iterator(start, end)
return &prefixIterator{
prefix: prefixBytes,
iter: iter,
done: false,
}
}
type prefixIterator struct {
prefix []byte
iter Iterator
done bool
}
func (i *prefixIterator) Valid() bool {
if i.done {
return false
}
return i.iter.Valid()
}
// Next steps the iterator to the next value
// if the next value does not contain prefix, the scan is done
func (i *prefixIterator) Next() {
i.iter.Next()
if !i.iter.Valid() || !bytes.HasPrefix(i.iter.Key(), i.prefix) {
i.done = true
}
}
// Key strips prefix from Key
func (i *prefixIterator) Key() (key []byte) {
key = i.iter.Key()
return key[len(i.prefix):]
}
func (i *prefixIterator) Value() (value []byte) {
return i.iter.Value()
}
func (i *prefixIterator) Error() error {
return i.iter.Error()
}
func (i *prefixIterator) Close() error {
return i.iter.Close()
}