Browse Source

db: fsdb iterator

pull/1842/head
Ethan Buchman 7 years ago
parent
commit
edf07760d6
3 changed files with 36 additions and 29 deletions
  1. +24
    -24
      db/fsdb.go
  2. +1
    -5
      db/mem_db.go
  3. +11
    -0
      db/util.go

+ 24
- 24
db/fsdb.go View File

@ -7,6 +7,7 @@ import (
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"sort"
"sync" "sync"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -24,6 +25,8 @@ func init() {
}, false) }, false)
} }
var _ DB = (*FSDB)(nil)
// It's slow. // It's slow.
type FSDB struct { type FSDB struct {
mtx sync.Mutex mtx sync.Mutex
@ -160,26 +163,20 @@ func (db *FSDB) Mutex() *sync.Mutex {
} }
func (db *FSDB) Iterator(start, end []byte) Iterator { func (db *FSDB) 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.
keys, err := list(db.dir)
if err != nil {
panic(errors.Wrap(err, fmt.Sprintf("Listing keys in %s", db.dir)))
}
sort.Strings(keys)
it.keys = 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.
keys, err := list(db.dir, start, end)
if err != nil {
panic(errors.Wrap(err, fmt.Sprintf("Listing keys in %s", db.dir)))
}
sort.Strings(keys)
it.keys = keys
return it
} }
func (db *FSDB) ReverseIterator(start, end []byte) Iterator { func (db *FSDB) ReverseIterator(start, end []byte) Iterator {
@ -233,7 +230,7 @@ func remove(path string) error {
// List files of a path. // List files of a path.
// Paths will NOT include dir as the prefix. // Paths will NOT include dir as the prefix.
// CONTRACT: returns os errors directly without wrapping. // CONTRACT: returns os errors directly without wrapping.
func list(dirPath string) (paths []string, err error) {
func list(dirPath string, start, end []byte) ([]string, error) {
dir, err := os.Open(dirPath) dir, err := os.Open(dirPath)
if err != nil { if err != nil {
return nil, err return nil, err
@ -244,12 +241,15 @@ func list(dirPath string) (paths []string, err error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
for i, name := range names {
var paths []string
for _, name := range names {
n, err := url.PathUnescape(name) n, err := url.PathUnescape(name)
if err != nil { if err != nil {
return nil, fmt.Errorf("Failed to unescape %s while listing", name) return nil, fmt.Errorf("Failed to unescape %s while listing", name)
} }
names[i] = n
if checkKeyCondition(n, start, end) {
paths = append(paths, n)
}
} }
return names, nil
return paths, nil
} }

+ 1
- 5
db/mem_db.go View File

@ -1,10 +1,8 @@
package db package db
import ( import (
"bytes"
"fmt" "fmt"
"sort" "sort"
"strings"
"sync" "sync"
) )
@ -159,9 +157,7 @@ func (db *MemDB) ReverseIterator(start, end []byte) Iterator {
func (db *MemDB) getSortedKeys(start, end []byte) []string { func (db *MemDB) getSortedKeys(start, end []byte) []string {
keys := []string{} keys := []string{}
for key, _ := range db.db { 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 {
if checkKeyCondition(key, start, end) {
keys = append(keys, key) keys = append(keys, key)
} }
} }


+ 11
- 0
db/util.go View File

@ -1,5 +1,10 @@
package db package db
import (
"bytes"
"strings"
)
func IteratePrefix(db DB, prefix []byte) Iterator { func IteratePrefix(db DB, prefix []byte) Iterator {
var start, end []byte var start, end []byte
if len(prefix) == 0 { if len(prefix) == 0 {
@ -33,3 +38,9 @@ func cpIncr(bz []byte) (ret []byte) {
} }
return EndingKey() return EndingKey()
} }
func checkKeyCondition(key string, start, end []byte) bool {
leftCondition := bytes.Equal(start, BeginningKey()) || strings.Compare(key, string(start)) >= 0
rightCondition := bytes.Equal(end, EndingKey()) || strings.Compare(key, string(end)) < 0
return leftCondition && rightCondition
}

Loading…
Cancel
Save