1
2
3
4
5
6
7
8 package memdb
9
10 import (
11 "math/rand"
12 "sync"
13
14 "github.com/syndtr/goleveldb/leveldb/comparer"
15 "github.com/syndtr/goleveldb/leveldb/errors"
16 "github.com/syndtr/goleveldb/leveldb/iterator"
17 "github.com/syndtr/goleveldb/leveldb/util"
18 )
19
20
21 var (
22 ErrNotFound = errors.ErrNotFound
23 ErrIterReleased = errors.New("leveldb/memdb: iterator released")
24 )
25
26 const tMaxHeight = 12
27
28 type dbIter struct {
29 util.BasicReleaser
30 p *DB
31 slice *util.Range
32 node int
33 forward bool
34 key, value []byte
35 err error
36 }
37
38 func (i *dbIter) fill(checkStart, checkLimit bool) bool {
39 if i.node != 0 {
40 n := i.p.nodeData[i.node]
41 m := n + i.p.nodeData[i.node+nKey]
42 i.key = i.p.kvData[n:m]
43 if i.slice != nil {
44 switch {
45 case checkLimit && i.slice.Limit != nil && i.p.cmp.Compare(i.key, i.slice.Limit) >= 0:
46 fallthrough
47 case checkStart && i.slice.Start != nil && i.p.cmp.Compare(i.key, i.slice.Start) < 0:
48 i.node = 0
49 goto bail
50 }
51 }
52 i.value = i.p.kvData[m : m+i.p.nodeData[i.node+nVal]]
53 return true
54 }
55 bail:
56 i.key = nil
57 i.value = nil
58 return false
59 }
60
61 func (i *dbIter) Valid() bool {
62 return i.node != 0
63 }
64
65 func (i *dbIter) First() bool {
66 if i.Released() {
67 i.err = ErrIterReleased
68 return false
69 }
70
71 i.forward = true
72 i.p.mu.RLock()
73 defer i.p.mu.RUnlock()
74 if i.slice != nil && i.slice.Start != nil {
75 i.node, _ = i.p.findGE(i.slice.Start, false)
76 } else {
77 i.node = i.p.nodeData[nNext]
78 }
79 return i.fill(false, true)
80 }
81
82 func (i *dbIter) Last() bool {
83 if i.Released() {
84 i.err = ErrIterReleased
85 return false
86 }
87
88 i.forward = false
89 i.p.mu.RLock()
90 defer i.p.mu.RUnlock()
91 if i.slice != nil && i.slice.Limit != nil {
92 i.node = i.p.findLT(i.slice.Limit)
93 } else {
94 i.node = i.p.findLast()
95 }
96 return i.fill(true, false)
97 }
98
99 func (i *dbIter) Seek(key []byte) bool {
100 if i.Released() {
101 i.err = ErrIterReleased
102 return false
103 }
104
105 i.forward = true
106 i.p.mu.RLock()
107 defer i.p.mu.RUnlock()
108 if i.slice != nil && i.slice.Start != nil && i.p.cmp.Compare(key, i.slice.Start) < 0 {
109 key = i.slice.Start
110 }
111 i.node, _ = i.p.findGE(key, false)
112 return i.fill(false, true)
113 }
114
115 func (i *dbIter) Next() bool {
116 if i.Released() {
117 i.err = ErrIterReleased
118 return false
119 }
120
121 if i.node == 0 {
122 if !i.forward {
123 return i.First()
124 }
125 return false
126 }
127 i.forward = true
128 i.p.mu.RLock()
129 defer i.p.mu.RUnlock()
130 i.node = i.p.nodeData[i.node+nNext]
131 return i.fill(false, true)
132 }
133
134 func (i *dbIter) Prev() bool {
135 if i.Released() {
136 i.err = ErrIterReleased
137 return false
138 }
139
140 if i.node == 0 {
141 if i.forward {
142 return i.Last()
143 }
144 return false
145 }
146 i.forward = false
147 i.p.mu.RLock()
148 defer i.p.mu.RUnlock()
149 i.node = i.p.findLT(i.key)
150 return i.fill(true, false)
151 }
152
153 func (i *dbIter) Key() []byte {
154 return i.key
155 }
156
157 func (i *dbIter) Value() []byte {
158 return i.value
159 }
160
161 func (i *dbIter) Error() error { return i.err }
162
163 func (i *dbIter) Release() {
164 if !i.Released() {
165 i.p = nil
166 i.node = 0
167 i.key = nil
168 i.value = nil
169 i.BasicReleaser.Release()
170 }
171 }
172
173 const (
174 nKV = iota
175 nKey
176 nVal
177 nHeight
178 nNext
179 )
180
181
182 type DB struct {
183 cmp comparer.BasicComparer
184 rnd *rand.Rand
185
186 mu sync.RWMutex
187 kvData []byte
188
189
190
191
192
193
194 nodeData []int
195 prevNode [tMaxHeight]int
196 maxHeight int
197 n int
198 kvSize int
199 }
200
201 func (p *DB) randHeight() (h int) {
202 const branching = 4
203 h = 1
204 for h < tMaxHeight && p.rnd.Int()%branching == 0 {
205 h++
206 }
207 return
208 }
209
210
211 func (p *DB) findGE(key []byte, prev bool) (int, bool) {
212 node := 0
213 h := p.maxHeight - 1
214 for {
215 next := p.nodeData[node+nNext+h]
216 cmp := 1
217 if next != 0 {
218 o := p.nodeData[next]
219 cmp = p.cmp.Compare(p.kvData[o:o+p.nodeData[next+nKey]], key)
220 }
221 if cmp < 0 {
222
223 node = next
224 } else {
225 if prev {
226 p.prevNode[h] = node
227 } else if cmp == 0 {
228 return next, true
229 }
230 if h == 0 {
231 return next, cmp == 0
232 }
233 h--
234 }
235 }
236 }
237
238 func (p *DB) findLT(key []byte) int {
239 node := 0
240 h := p.maxHeight - 1
241 for {
242 next := p.nodeData[node+nNext+h]
243 o := p.nodeData[next]
244 if next == 0 || p.cmp.Compare(p.kvData[o:o+p.nodeData[next+nKey]], key) >= 0 {
245 if h == 0 {
246 break
247 }
248 h--
249 } else {
250 node = next
251 }
252 }
253 return node
254 }
255
256 func (p *DB) findLast() int {
257 node := 0
258 h := p.maxHeight - 1
259 for {
260 next := p.nodeData[node+nNext+h]
261 if next == 0 {
262 if h == 0 {
263 break
264 }
265 h--
266 } else {
267 node = next
268 }
269 }
270 return node
271 }
272
273
274
275
276
277 func (p *DB) Put(key []byte, value []byte) error {
278 p.mu.Lock()
279 defer p.mu.Unlock()
280
281 if node, exact := p.findGE(key, true); exact {
282 kvOffset := len(p.kvData)
283 p.kvData = append(p.kvData, key...)
284 p.kvData = append(p.kvData, value...)
285 p.nodeData[node] = kvOffset
286 m := p.nodeData[node+nVal]
287 p.nodeData[node+nVal] = len(value)
288 p.kvSize += len(value) - m
289 return nil
290 }
291
292 h := p.randHeight()
293 if h > p.maxHeight {
294 for i := p.maxHeight; i < h; i++ {
295 p.prevNode[i] = 0
296 }
297 p.maxHeight = h
298 }
299
300 kvOffset := len(p.kvData)
301 p.kvData = append(p.kvData, key...)
302 p.kvData = append(p.kvData, value...)
303
304 node := len(p.nodeData)
305 p.nodeData = append(p.nodeData, kvOffset, len(key), len(value), h)
306 for i, n := range p.prevNode[:h] {
307 m := n + nNext + i
308 p.nodeData = append(p.nodeData, p.nodeData[m])
309 p.nodeData[m] = node
310 }
311
312 p.kvSize += len(key) + len(value)
313 p.n++
314 return nil
315 }
316
317
318
319
320
321 func (p *DB) Delete(key []byte) error {
322 p.mu.Lock()
323 defer p.mu.Unlock()
324
325 node, exact := p.findGE(key, true)
326 if !exact {
327 return ErrNotFound
328 }
329
330 h := p.nodeData[node+nHeight]
331 for i, n := range p.prevNode[:h] {
332 m := n + nNext + i
333 p.nodeData[m] = p.nodeData[p.nodeData[m]+nNext+i]
334 }
335
336 p.kvSize -= p.nodeData[node+nKey] + p.nodeData[node+nVal]
337 p.n--
338 return nil
339 }
340
341
342
343
344 func (p *DB) Contains(key []byte) bool {
345 p.mu.RLock()
346 _, exact := p.findGE(key, false)
347 p.mu.RUnlock()
348 return exact
349 }
350
351
352
353
354
355
356 func (p *DB) Get(key []byte) (value []byte, err error) {
357 p.mu.RLock()
358 if node, exact := p.findGE(key, false); exact {
359 o := p.nodeData[node] + p.nodeData[node+nKey]
360 value = p.kvData[o : o+p.nodeData[node+nVal]]
361 } else {
362 err = ErrNotFound
363 }
364 p.mu.RUnlock()
365 return
366 }
367
368
369
370
371
372
373
374 func (p *DB) Find(key []byte) (rkey, value []byte, err error) {
375 p.mu.RLock()
376 if node, _ := p.findGE(key, false); node != 0 {
377 n := p.nodeData[node]
378 m := n + p.nodeData[node+nKey]
379 rkey = p.kvData[n:m]
380 value = p.kvData[m : m+p.nodeData[node+nVal]]
381 } else {
382 err = ErrNotFound
383 }
384 p.mu.RUnlock()
385 return
386 }
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407 func (p *DB) NewIterator(slice *util.Range) iterator.Iterator {
408 return &dbIter{p: p, slice: slice}
409 }
410
411
412 func (p *DB) Capacity() int {
413 p.mu.RLock()
414 defer p.mu.RUnlock()
415 return cap(p.kvData)
416 }
417
418
419
420
421 func (p *DB) Size() int {
422 p.mu.RLock()
423 defer p.mu.RUnlock()
424 return p.kvSize
425 }
426
427
428 func (p *DB) Free() int {
429 p.mu.RLock()
430 defer p.mu.RUnlock()
431 return cap(p.kvData) - len(p.kvData)
432 }
433
434
435 func (p *DB) Len() int {
436 p.mu.RLock()
437 defer p.mu.RUnlock()
438 return p.n
439 }
440
441
442 func (p *DB) Reset() {
443 p.mu.Lock()
444 p.rnd = rand.New(rand.NewSource(0xdeadbeef))
445 p.maxHeight = 1
446 p.n = 0
447 p.kvSize = 0
448 p.kvData = p.kvData[:0]
449 p.nodeData = p.nodeData[:nNext+tMaxHeight]
450 p.nodeData[nKV] = 0
451 p.nodeData[nKey] = 0
452 p.nodeData[nVal] = 0
453 p.nodeData[nHeight] = tMaxHeight
454 for n := 0; n < tMaxHeight; n++ {
455 p.nodeData[nNext+n] = 0
456 p.prevNode[n] = 0
457 }
458 p.mu.Unlock()
459 }
460
461
462
463
464
465
466
467
468
469 func New(cmp comparer.BasicComparer, capacity int) *DB {
470 p := &DB{
471 cmp: cmp,
472 rnd: rand.New(rand.NewSource(0xdeadbeef)),
473 maxHeight: 1,
474 kvData: make([]byte, 0, capacity),
475 nodeData: make([]int, 4+tMaxHeight),
476 }
477 p.nodeData[nHeight] = tMaxHeight
478 return p
479 }
480
View as plain text