Browse Source

db: memdb iterator

pull/1842/head
Ethan Buchman 7 years ago
parent
commit
39e40ff5ce
2 changed files with 57 additions and 33 deletions
  1. +56
    -32
      db/mem_db.go
  2. +1
    -1
      db/mem_db_test.go

+ 56
- 32
db/mem_db.go View File

@ -3,6 +3,8 @@ package db
import (
"bytes"
"fmt"
"sort"
"strings"
"sync"
)
@ -12,6 +14,8 @@ func init() {
}, false)
}
var _ DB = (*MemDB)(nil)
type MemDB struct {
mtx sync.Mutex
db map[string][]byte
@ -123,49 +127,67 @@ func (db *MemDB) Mutex() *sync.Mutex {
//----------------------------------------
func (db *MemDB) Iterator(start, end []byte) Iterator {
/*
XXX
it := newMemDBIterator()
it.db = db
it.cur = 0
db.mtx.Lock()
defer db.mtx.Unlock()
// We need a copy of all of the keys.
// Not the best, but probably not a bottleneck depending.
for key, _ := range db.db {
it.keys = append(it.keys, key)
}
sort.Strings(it.keys)
return it
*/
return nil
it := newMemDBIterator(db, start, end)
db.mtx.Lock()
defer db.mtx.Unlock()
// We need a copy of all of the keys.
// Not the best, but probably not a bottleneck depending.
it.keys = db.getSortedKeys(start, end)
return it
}
func (db *MemDB) ReverseIterator(start, end []byte) Iterator {
// XXX
it := newMemDBIterator(db, start, end)
db.mtx.Lock()
defer db.mtx.Unlock()
// We need a copy of all of the keys.
// Not the best, but probably not a bottleneck depending.
it.keys = db.getSortedKeys(end, start)
// reverse the order
l := len(it.keys) - 1
for i, v := range it.keys {
it.keys[i] = it.keys[l-i]
it.keys[l-i] = v
}
return nil
}
type memDBIterator struct {
cur int
keys []string
db DB
func (db *MemDB) getSortedKeys(start, end []byte) []string {
keys := []string{}
for key, _ := range db.db {
leftCondition := bytes.Equal(start, BeginningKey()) || strings.Compare(key, string(start)) >= 0
rightCondition := bytes.Equal(end, EndingKey()) || strings.Compare(key, string(end)) < 0
if leftCondition && rightCondition {
keys = append(keys, key)
}
}
sort.Strings(keys)
return keys
}
func newMemDBIterator() *memDBIterator {
return &memDBIterator{}
var _ Iterator = (*memDBIterator)(nil)
type memDBIterator struct {
cur int
keys []string
db DB
start, end []byte
}
func (it *memDBIterator) Seek(key []byte) {
for i, ik := range it.keys {
it.cur = i
if bytes.Compare(key, []byte(ik)) <= 0 {
return
}
func newMemDBIterator(db DB, start, end []byte) *memDBIterator {
return &memDBIterator{
db: db,
start: start,
end: end,
}
it.cur += 1 // If not found, becomes invalid.
}
func (it *memDBIterator) Domain() ([]byte, []byte) {
return it.start, it.end
}
func (it *memDBIterator) Valid() bool {
@ -208,3 +230,5 @@ func (it *memDBIterator) Close() {
func (it *memDBIterator) GetError() error {
return nil
}
func (it *memDBIterator) Release() {}

+ 1
- 1
db/mem_db_test.go View File

@ -7,7 +7,7 @@ import (
"github.com/stretchr/testify/require"
)
func TestMemDbIterator(t *testing.T) {
func TestMemDBIterator(t *testing.T) {
db := NewMemDB()
keys := make([][]byte, 100)
for i := 0; i < 100; i++ {


Loading…
Cancel
Save