1 // Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
2 // All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
7 // Package memdb provides in-memory key/value database implementation.
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"
22 ErrNotFound = errors.ErrNotFound
23 ErrIterReleased = errors.New("leveldb/memdb: iterator released")
38 func (i *dbIter) fill(checkStart, checkLimit bool) bool {
40 n := i.p.nodeData[i.node]
41 m := n + i.p.nodeData[i.node+nKey]
42 i.key = i.p.kvData[n:m]
45 case checkLimit && i.slice.Limit != nil && i.p.cmp.Compare(i.key, i.slice.Limit) >= 0:
47 case checkStart && i.slice.Start != nil && i.p.cmp.Compare(i.key, i.slice.Start) < 0:
52 i.value = i.p.kvData[m : m+i.p.nodeData[i.node+nVal]]
61 func (i *dbIter) Valid() bool {
65 func (i *dbIter) First() bool {
67 i.err = ErrIterReleased
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)
77 i.node = i.p.nodeData[nNext]
79 return i.fill(false, true)
82 func (i *dbIter) Last() bool {
84 i.err = ErrIterReleased
90 defer i.p.mu.RUnlock()
91 if i.slice != nil && i.slice.Limit != nil {
92 i.node = i.p.findLT(i.slice.Limit)
94 i.node = i.p.findLast()
96 return i.fill(true, false)
99 func (i *dbIter) Seek(key []byte) bool {
101 i.err = ErrIterReleased
107 defer i.p.mu.RUnlock()
108 if i.slice != nil && i.slice.Start != nil && i.p.cmp.Compare(key, i.slice.Start) < 0 {
111 i.node, _ = i.p.findGE(key, false)
112 return i.fill(false, true)
115 func (i *dbIter) Next() bool {
117 i.err = ErrIterReleased
129 defer i.p.mu.RUnlock()
130 i.node = i.p.nodeData[i.node+nNext]
131 return i.fill(false, true)
134 func (i *dbIter) Prev() bool {
136 i.err = ErrIterReleased
148 defer i.p.mu.RUnlock()
149 i.node = i.p.findLT(i.key)
150 return i.fill(true, false)
153 func (i *dbIter) Key() []byte {
157 func (i *dbIter) Value() []byte {
161 func (i *dbIter) Error() error { return i.err }
163 func (i *dbIter) Release() {
169 i.BasicReleaser.Release()
181 // DB is an in-memory key/value database.
183 cmp comparer.BasicComparer
191 // [2] : Value length
193 // [3..height] : Next nodes
195 prevNode [tMaxHeight]int
201 func (p *DB) randHeight() (h int) {
204 for h < tMaxHeight && p.rnd.Int()%branching == 0 {
210 // Must hold RW-lock if prev == true, as it use shared prevNode slice.
211 func (p *DB) findGE(key []byte, prev bool) (int, bool) {
215 next := p.nodeData[node+nNext+h]
218 o := p.nodeData[next]
219 cmp = p.cmp.Compare(p.kvData[o:o+p.nodeData[next+nKey]], key)
222 // Keep searching in this list
231 return next, cmp == 0
238 func (p *DB) findLT(key []byte) int {
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 {
256 func (p *DB) findLast() int {
260 next := p.nodeData[node+nNext+h]
273 // Put sets the value for the given key. It overwrites any previous value
274 // for that key; a DB is not a multi-map.
276 // It is safe to modify the contents of the arguments after Put returns.
277 func (p *DB) Put(key []byte, value []byte) error {
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
294 for i := p.maxHeight; i < h; i++ {
300 kvOffset := len(p.kvData)
301 p.kvData = append(p.kvData, key...)
302 p.kvData = append(p.kvData, value...)
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] {
308 p.nodeData = append(p.nodeData, p.nodeData[m])
312 p.kvSize += len(key) + len(value)
317 // Delete deletes the value for the given key. It returns ErrNotFound if
318 // the DB does not contain the key.
320 // It is safe to modify the contents of the arguments after Delete returns.
321 func (p *DB) Delete(key []byte) error {
325 node, exact := p.findGE(key, true)
330 h := p.nodeData[node+nHeight]
331 for i, n := range p.prevNode[:h] {
333 p.nodeData[m] = p.nodeData[p.nodeData[m]+nNext+i]
336 p.kvSize -= p.nodeData[node+nKey] + p.nodeData[node+nVal]
341 // Contains returns true if the given key are in the DB.
343 // It is safe to modify the contents of the arguments after Contains returns.
344 func (p *DB) Contains(key []byte) bool {
346 _, exact := p.findGE(key, false)
351 // Get gets the value for the given key. It returns error.ErrNotFound if the
352 // DB does not contain the key.
354 // The caller should not modify the contents of the returned slice, but
355 // it is safe to modify the contents of the argument after Get returns.
356 func (p *DB) Get(key []byte) (value []byte, err error) {
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]]
368 // Find finds key/value pair whose key is greater than or equal to the
369 // given key. It returns ErrNotFound if the table doesn't contain
372 // The caller should not modify the contents of the returned slice, but
373 // it is safe to modify the contents of the argument after Find returns.
374 func (p *DB) Find(key []byte) (rkey, value []byte, err error) {
376 if node, _ := p.findGE(key, false); node != 0 {
377 n := p.nodeData[node]
378 m := n + p.nodeData[node+nKey]
380 value = p.kvData[m : m+p.nodeData[node+nVal]]
388 // NewIterator returns an iterator of the DB.
389 // The returned iterator is not safe for concurrent use, but it is safe to use
390 // multiple iterators concurrently, with each in a dedicated goroutine.
391 // It is also safe to use an iterator concurrently with modifying its
392 // underlying DB. However, the resultant key/value pairs are not guaranteed
393 // to be a consistent snapshot of the DB at a particular point in time.
395 // Slice allows slicing the iterator to only contains keys in the given
396 // range. A nil Range.Start is treated as a key before all keys in the
397 // DB. And a nil Range.Limit is treated as a key after all keys in
400 // The iterator must be released after use, by calling Release method.
402 // Also read Iterator documentation of the leveldb/iterator package.
403 func (p *DB) NewIterator(slice *util.Range) iterator.Iterator {
404 return &dbIter{p: p, slice: slice}
407 // Capacity returns keys/values buffer capacity.
408 func (p *DB) Capacity() int {
414 // Size returns sum of keys and values length. Note that deleted
415 // key/value will not be accounted for, but it will still consume
416 // the buffer, since the buffer is append only.
417 func (p *DB) Size() int {
423 // Free returns keys/values free buffer before need to grow.
424 func (p *DB) Free() int {
427 return cap(p.kvData) - len(p.kvData)
430 // Len returns the number of entries in the DB.
431 func (p *DB) Len() int {
437 // Reset resets the DB to initial empty state. Allows reuse the buffer.
438 func (p *DB) Reset() {
440 p.rnd = rand.New(rand.NewSource(0xdeadbeef))
444 p.kvData = p.kvData[:0]
445 p.nodeData = p.nodeData[:nNext+tMaxHeight]
449 p.nodeData[nHeight] = tMaxHeight
450 for n := 0; n < tMaxHeight; n++ {
451 p.nodeData[nNext+n] = 0
457 // New creates a new initialized in-memory key/value DB. The capacity
458 // is the initial key/value buffer capacity. The capacity is advisory,
461 // This DB is append-only, deleting an entry would remove entry node but not
462 // reclaim KV buffer.
464 // The returned DB instance is safe for concurrent use.
465 func New(cmp comparer.BasicComparer, capacity int) *DB {
468 rnd: rand.New(rand.NewSource(0xdeadbeef)),
470 kvData: make([]byte, 0, capacity),
471 nodeData: make([]int, 4+tMaxHeight),
473 p.nodeData[nHeight] = tMaxHeight