db: memdb iterator

This commit is contained in:
Ethan Buchman 2017-12-12 20:06:50 -05:00
parent bb115d4d61
commit 39e40ff5ce
2 changed files with 58 additions and 34 deletions

View File

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

View File

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