1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16
17 package sorted
18
19 import (
20 "errors"
21 "log"
22 "sync"
23
24 "github.com/syndtr/goleveldb/leveldb/comparer"
25 "github.com/syndtr/goleveldb/leveldb/iterator"
26 "github.com/syndtr/goleveldb/leveldb/memdb"
27 "github.com/syndtr/goleveldb/leveldb/util"
28 "go4.org/jsonconfig"
29 )
30
31
32
33 func NewMemoryKeyValue() KeyValue {
34 kv := new(memKeys)
35 kv.Wipe()
36 return kv
37 }
38
39 var _ Wiper = (*memKeys)(nil)
40
41
42
43 type memKeys struct {
44 mu sync.Mutex
45 db *memdb.DB
46 }
47
48 func (s *memKeys) Wipe() error {
49 s.mu.Lock()
50 defer s.mu.Unlock()
51 s.db = memdb.New(comparer.DefaultComparer, 128)
52 return nil
53 }
54
55
56
57
58 type memIter struct {
59 lit iterator.Iterator
60 k, v *string
61 }
62
63 func (s *memIter) Next() bool {
64 s.k, s.v = nil, nil
65 return s.lit.Next()
66 }
67
68 func (s *memIter) Close() error {
69 s.lit.Release()
70 return s.lit.Error()
71 }
72
73 func (s *memIter) KeyBytes() []byte {
74 return s.lit.Key()
75 }
76
77 func (s *memIter) ValueBytes() []byte {
78 return s.lit.Value()
79 }
80
81 func (s *memIter) Key() string {
82 if s.k != nil {
83 return *s.k
84 }
85 str := string(s.KeyBytes())
86 s.k = &str
87 return str
88 }
89
90 func (s *memIter) Value() string {
91 if s.v != nil {
92 return *s.v
93 }
94 str := string(s.ValueBytes())
95 s.v = &str
96 return str
97 }
98
99 func (mk *memKeys) Get(key string) (string, error) {
100 mk.mu.Lock()
101 defer mk.mu.Unlock()
102 k, err := mk.db.Get([]byte(key))
103 if err == memdb.ErrNotFound {
104 return "", ErrNotFound
105 }
106 return string(k), err
107 }
108
109 func (mk *memKeys) Find(start, end string) Iterator {
110 mk.mu.Lock()
111 defer mk.mu.Unlock()
112 var startB, endB []byte
113 if start != "" {
114 startB = []byte(start)
115 }
116 if end != "" {
117 endB = []byte(end)
118 }
119 lit := mk.db.NewIterator(&util.Range{Start: startB, Limit: endB})
120 return &memIter{lit: lit}
121 }
122
123 func (mk *memKeys) Set(key, value string) error {
124 if err := CheckSizes(key, value); err != nil {
125 log.Printf("Skipping storing (%q:%q): %v", key, value, err)
126 return nil
127 }
128 mk.mu.Lock()
129 defer mk.mu.Unlock()
130 return mk.db.Put([]byte(key), []byte(value))
131 }
132
133 func (mk *memKeys) Delete(key string) error {
134 mk.mu.Lock()
135 defer mk.mu.Unlock()
136 err := mk.db.Delete([]byte(key))
137 if err == memdb.ErrNotFound {
138 return nil
139 }
140 return err
141 }
142
143 func (mk *memKeys) BeginBatch() BatchMutation {
144 return &batch{}
145 }
146
147 func (mk *memKeys) CommitBatch(bm BatchMutation) error {
148 b, ok := bm.(*batch)
149 if !ok {
150 return errors.New("invalid batch type; not an instance returned by BeginBatch")
151 }
152 mk.mu.Lock()
153 defer mk.mu.Unlock()
154 for _, m := range b.Mutations() {
155 if m.IsDelete() {
156 if err := mk.db.Delete([]byte(m.Key())); err != nil && err != memdb.ErrNotFound {
157 return err
158 }
159 } else {
160
161
162 if err := CheckSizes(m.Key(), m.Value()); err != nil {
163 log.Printf("Skipping storing (%q:%q): %v", m.Key(), m.Value(), err)
164 continue
165 }
166 if err := mk.db.Put([]byte(m.Key()), []byte(m.Value())); err != nil {
167 return err
168 }
169 }
170 }
171 return nil
172 }
173
174 func (mk *memKeys) Close() error { return nil }
175
176 func init() {
177 RegisterKeyValue("memory", func(cfg jsonconfig.Obj) (KeyValue, error) {
178 if err := cfg.Validate(); err != nil {
179 return nil, err
180 }
181 return NewMemoryKeyValue(), nil
182 })
183 }