all: simplify and fix database iteration with prefix/start (#20808)
* core/state/snapshot: start fixing disk iterator seek * ethdb, rawdb, leveldb, memorydb: implement iterators with prefix and start * les, core/state/snapshot: iterator fixes * all: remove two iterator methods * all: rename Iteratee.NewIteratorWith -> NewIterator * ethdb: fix review concerns
This commit is contained in:
parent
00064ddcfb
commit
6402c42b67
@ -301,7 +301,7 @@ func ExportPreimages(db ethdb.Database, fn string) error {
|
|||||||
defer writer.(*gzip.Writer).Close()
|
defer writer.(*gzip.Writer).Close()
|
||||||
}
|
}
|
||||||
// Iterate over the preimages and export them
|
// Iterate over the preimages and export them
|
||||||
it := db.NewIteratorWithPrefix([]byte("secure-key-"))
|
it := db.NewIterator([]byte("secure-key-"), nil)
|
||||||
defer it.Release()
|
defer it.Release()
|
||||||
|
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
|
@ -145,3 +145,14 @@ func TrimLeftZeroes(s []byte) []byte {
|
|||||||
}
|
}
|
||||||
return s[idx:]
|
return s[idx:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TrimRightZeroes returns a subslice of s without trailing zeroes
|
||||||
|
func TrimRightZeroes(s []byte) []byte {
|
||||||
|
idx := len(s)
|
||||||
|
for ; idx > 0; idx-- {
|
||||||
|
if s[idx-1] != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s[:idx]
|
||||||
|
}
|
||||||
|
@ -105,3 +105,22 @@ func TestNoPrefixShortHexOddLength(t *testing.T) {
|
|||||||
t.Errorf("Expected %x got %x", expected, result)
|
t.Errorf("Expected %x got %x", expected, result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTrimRightZeroes(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
arr []byte
|
||||||
|
exp []byte
|
||||||
|
}{
|
||||||
|
{FromHex("0x00ffff00ff0000"), FromHex("0x00ffff00ff")},
|
||||||
|
{FromHex("0x00000000000000"), []byte{}},
|
||||||
|
{FromHex("0xff"), FromHex("0xff")},
|
||||||
|
{[]byte{}, []byte{}},
|
||||||
|
{FromHex("0x00ffffffffffff"), FromHex("0x00ffffffffffff")},
|
||||||
|
}
|
||||||
|
for i, test := range tests {
|
||||||
|
got := TrimRightZeroes(test.arr)
|
||||||
|
if !bytes.Equal(got, test.exp) {
|
||||||
|
t.Errorf("test %d, got %x exp %x", i, got, test.exp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -69,7 +69,7 @@ func ReadAllHashes(db ethdb.Iteratee, number uint64) []common.Hash {
|
|||||||
prefix := headerKeyPrefix(number)
|
prefix := headerKeyPrefix(number)
|
||||||
|
|
||||||
hashes := make([]common.Hash, 0, 1)
|
hashes := make([]common.Hash, 0, 1)
|
||||||
it := db.NewIteratorWithPrefix(prefix)
|
it := db.NewIterator(prefix, nil)
|
||||||
defer it.Release()
|
defer it.Release()
|
||||||
|
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
|
@ -93,7 +93,7 @@ func DeleteStorageSnapshot(db ethdb.KeyValueWriter, accountHash, storageHash com
|
|||||||
// IterateStorageSnapshots returns an iterator for walking the entire storage
|
// IterateStorageSnapshots returns an iterator for walking the entire storage
|
||||||
// space of a specific account.
|
// space of a specific account.
|
||||||
func IterateStorageSnapshots(db ethdb.Iteratee, accountHash common.Hash) ethdb.Iterator {
|
func IterateStorageSnapshots(db ethdb.Iteratee, accountHash common.Hash) ethdb.Iterator {
|
||||||
return db.NewIteratorWithPrefix(storageSnapshotsKey(accountHash))
|
return db.NewIterator(storageSnapshotsKey(accountHash), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadSnapshotJournal retrieves the serialized in-memory diff layers saved at
|
// ReadSnapshotJournal retrieves the serialized in-memory diff layers saved at
|
||||||
|
@ -221,7 +221,7 @@ func NewLevelDBDatabaseWithFreezer(file string, cache int, handles int, freezer
|
|||||||
// InspectDatabase traverses the entire database and checks the size
|
// InspectDatabase traverses the entire database and checks the size
|
||||||
// of all different categories of data.
|
// of all different categories of data.
|
||||||
func InspectDatabase(db ethdb.Database) error {
|
func InspectDatabase(db ethdb.Database) error {
|
||||||
it := db.NewIterator()
|
it := db.NewIterator(nil, nil)
|
||||||
defer it.Release()
|
defer it.Release()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -103,27 +103,12 @@ func (t *table) Delete(key []byte) error {
|
|||||||
return t.db.Delete(append([]byte(t.prefix), key...))
|
return t.db.Delete(append([]byte(t.prefix), key...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewIterator creates a binary-alphabetical iterator over the entire keyspace
|
// NewIterator creates a binary-alphabetical iterator over a subset
|
||||||
// contained within the database.
|
// of database content with a particular key prefix, starting at a particular
|
||||||
func (t *table) NewIterator() ethdb.Iterator {
|
// initial key (or after, if it does not exist).
|
||||||
return t.NewIteratorWithPrefix(nil)
|
func (t *table) NewIterator(prefix []byte, start []byte) ethdb.Iterator {
|
||||||
}
|
innerPrefix := append([]byte(t.prefix), prefix...)
|
||||||
|
iter := t.db.NewIterator(innerPrefix, start)
|
||||||
// NewIteratorWithStart creates a binary-alphabetical iterator over a subset of
|
|
||||||
// database content starting at a particular initial key (or after, if it does
|
|
||||||
// not exist).
|
|
||||||
func (t *table) NewIteratorWithStart(start []byte) ethdb.Iterator {
|
|
||||||
iter := t.db.NewIteratorWithStart(append([]byte(t.prefix), start...))
|
|
||||||
return &tableIterator{
|
|
||||||
iter: iter,
|
|
||||||
prefix: t.prefix,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewIteratorWithPrefix creates a binary-alphabetical iterator over a subset
|
|
||||||
// of database content with a particular key prefix.
|
|
||||||
func (t *table) NewIteratorWithPrefix(prefix []byte) ethdb.Iterator {
|
|
||||||
iter := t.db.NewIteratorWithPrefix(append([]byte(t.prefix), prefix...))
|
|
||||||
return &tableIterator{
|
return &tableIterator{
|
||||||
iter: iter,
|
iter: iter,
|
||||||
prefix: t.prefix,
|
prefix: t.prefix,
|
||||||
|
@ -19,6 +19,8 @@ package rawdb
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTableDatabase(t *testing.T) { testTableDatabase(t, "prefix") }
|
func TestTableDatabase(t *testing.T) { testTableDatabase(t, "prefix") }
|
||||||
@ -96,48 +98,31 @@ func testTableDatabase(t *testing.T, prefix string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check := func(iter ethdb.Iterator, expCount, index int) {
|
||||||
|
count := 0
|
||||||
|
for iter.Next() {
|
||||||
|
key, value := iter.Key(), iter.Value()
|
||||||
|
if !bytes.Equal(key, entries[index].key) {
|
||||||
|
t.Fatalf("Key mismatch: want=%v, got=%v", entries[index].key, key)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(value, entries[index].value) {
|
||||||
|
t.Fatalf("Value mismatch: want=%v, got=%v", entries[index].value, value)
|
||||||
|
}
|
||||||
|
index += 1
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
if count != expCount {
|
||||||
|
t.Fatalf("Wrong number of elems, exp %d got %d", expCount, count)
|
||||||
|
}
|
||||||
|
iter.Release()
|
||||||
|
}
|
||||||
// Test iterators
|
// Test iterators
|
||||||
iter := db.NewIterator()
|
check(db.NewIterator(nil, nil), 6, 0)
|
||||||
var index int
|
|
||||||
for iter.Next() {
|
|
||||||
key, value := iter.Key(), iter.Value()
|
|
||||||
if !bytes.Equal(key, entries[index].key) {
|
|
||||||
t.Fatalf("Key mismatch: want=%v, got=%v", entries[index].key, key)
|
|
||||||
}
|
|
||||||
if !bytes.Equal(value, entries[index].value) {
|
|
||||||
t.Fatalf("Value mismatch: want=%v, got=%v", entries[index].value, value)
|
|
||||||
}
|
|
||||||
index += 1
|
|
||||||
}
|
|
||||||
iter.Release()
|
|
||||||
|
|
||||||
// Test iterators with prefix
|
// Test iterators with prefix
|
||||||
iter = db.NewIteratorWithPrefix([]byte{0xff, 0xff})
|
check(db.NewIterator([]byte{0xff, 0xff}, nil), 3, 3)
|
||||||
index = 3
|
|
||||||
for iter.Next() {
|
|
||||||
key, value := iter.Key(), iter.Value()
|
|
||||||
if !bytes.Equal(key, entries[index].key) {
|
|
||||||
t.Fatalf("Key mismatch: want=%v, got=%v", entries[index].key, key)
|
|
||||||
}
|
|
||||||
if !bytes.Equal(value, entries[index].value) {
|
|
||||||
t.Fatalf("Value mismatch: want=%v, got=%v", entries[index].value, value)
|
|
||||||
}
|
|
||||||
index += 1
|
|
||||||
}
|
|
||||||
iter.Release()
|
|
||||||
|
|
||||||
// Test iterators with start point
|
// Test iterators with start point
|
||||||
iter = db.NewIteratorWithStart([]byte{0xff, 0xff, 0x02})
|
check(db.NewIterator(nil, []byte{0xff, 0xff, 0x02}), 2, 4)
|
||||||
index = 4
|
// Test iterators with prefix and start point
|
||||||
for iter.Next() {
|
check(db.NewIterator([]byte{0xee}, nil), 0, 0)
|
||||||
key, value := iter.Key(), iter.Value()
|
check(db.NewIterator(nil, []byte{0x00}), 6, 0)
|
||||||
if !bytes.Equal(key, entries[index].key) {
|
|
||||||
t.Fatalf("Key mismatch: want=%v, got=%v", entries[index].key, key)
|
|
||||||
}
|
|
||||||
if !bytes.Equal(value, entries[index].value) {
|
|
||||||
t.Fatalf("Value mismatch: want=%v, got=%v", entries[index].value, value)
|
|
||||||
}
|
|
||||||
index += 1
|
|
||||||
}
|
|
||||||
iter.Release()
|
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ func TestNodeIteratorCoverage(t *testing.T) {
|
|||||||
t.Errorf("state entry not reported %x", hash)
|
t.Errorf("state entry not reported %x", hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
it := db.TrieDB().DiskDB().(ethdb.Database).NewIterator()
|
it := db.TrieDB().DiskDB().(ethdb.Database).NewIterator(nil, nil)
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
key := it.Key()
|
key := it.Key()
|
||||||
if bytes.HasPrefix(key, []byte("secure-key-")) {
|
if bytes.HasPrefix(key, []byte("secure-key-")) {
|
||||||
|
@ -18,11 +18,15 @@ package snapshot
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/fastcache"
|
"github.com/VictoriaMetrics/fastcache"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
"github.com/ethereum/go-ethereum/ethdb/leveldb"
|
||||||
"github.com/ethereum/go-ethereum/ethdb/memorydb"
|
"github.com/ethereum/go-ethereum/ethdb/memorydb"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -432,4 +436,76 @@ func TestDiskPartialMerge(t *testing.T) {
|
|||||||
// This test case is a tiny specialized case of TestDiskPartialMerge, which tests
|
// This test case is a tiny specialized case of TestDiskPartialMerge, which tests
|
||||||
// some very specific cornercases that random tests won't ever trigger.
|
// some very specific cornercases that random tests won't ever trigger.
|
||||||
func TestDiskMidAccountPartialMerge(t *testing.T) {
|
func TestDiskMidAccountPartialMerge(t *testing.T) {
|
||||||
|
// TODO(@karalabe) ?
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestDiskSeek tests that seek-operations work on the disk layer
|
||||||
|
func TestDiskSeek(t *testing.T) {
|
||||||
|
// Create some accounts in the disk layer
|
||||||
|
var db ethdb.Database
|
||||||
|
|
||||||
|
if dir, err := ioutil.TempDir("", "disklayer-test"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else {
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
diskdb, err := leveldb.New(dir, 256, 0, "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
db = rawdb.NewDatabase(diskdb)
|
||||||
|
}
|
||||||
|
// Fill even keys [0,2,4...]
|
||||||
|
for i := 0; i < 0xff; i += 2 {
|
||||||
|
acc := common.Hash{byte(i)}
|
||||||
|
rawdb.WriteAccountSnapshot(db, acc, acc[:])
|
||||||
|
}
|
||||||
|
// Add an 'higher' key, with incorrect (higher) prefix
|
||||||
|
highKey := []byte{rawdb.SnapshotAccountPrefix[0] + 1}
|
||||||
|
db.Put(highKey, []byte{0xff, 0xff})
|
||||||
|
|
||||||
|
baseRoot := randomHash()
|
||||||
|
rawdb.WriteSnapshotRoot(db, baseRoot)
|
||||||
|
|
||||||
|
snaps := &Tree{
|
||||||
|
layers: map[common.Hash]snapshot{
|
||||||
|
baseRoot: &diskLayer{
|
||||||
|
diskdb: db,
|
||||||
|
cache: fastcache.New(500 * 1024),
|
||||||
|
root: baseRoot,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
// Test some different seek positions
|
||||||
|
type testcase struct {
|
||||||
|
pos byte
|
||||||
|
expkey byte
|
||||||
|
}
|
||||||
|
var cases = []testcase{
|
||||||
|
{0xff, 0x55}, // this should exit immediately without checking key
|
||||||
|
{0x01, 0x02},
|
||||||
|
{0xfe, 0xfe},
|
||||||
|
{0xfd, 0xfe},
|
||||||
|
{0x00, 0x00},
|
||||||
|
}
|
||||||
|
for i, tc := range cases {
|
||||||
|
it, err := snaps.AccountIterator(baseRoot, common.Hash{tc.pos})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("case %d, error: %v", i, err)
|
||||||
|
}
|
||||||
|
count := 0
|
||||||
|
for it.Next() {
|
||||||
|
k, v, err := it.Hash()[0], it.Account()[0], it.Error()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("test %d, item %d, error: %v", i, count, err)
|
||||||
|
}
|
||||||
|
// First item in iterator should have the expected key
|
||||||
|
if count == 0 && k != tc.expkey {
|
||||||
|
t.Fatalf("test %d, item %d, got %v exp %v", i, count, k, tc.expkey)
|
||||||
|
}
|
||||||
|
count++
|
||||||
|
if v != k {
|
||||||
|
t.Fatalf("test %d, item %d, value wrong, got %v exp %v", i, count, v, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,10 +148,10 @@ type diskAccountIterator struct {
|
|||||||
|
|
||||||
// AccountIterator creates an account iterator over a disk layer.
|
// AccountIterator creates an account iterator over a disk layer.
|
||||||
func (dl *diskLayer) AccountIterator(seek common.Hash) AccountIterator {
|
func (dl *diskLayer) AccountIterator(seek common.Hash) AccountIterator {
|
||||||
// TODO: Fix seek position, or remove seek parameter
|
pos := common.TrimRightZeroes(seek[:])
|
||||||
return &diskAccountIterator{
|
return &diskAccountIterator{
|
||||||
layer: dl,
|
layer: dl,
|
||||||
it: dl.diskdb.NewIteratorWithPrefix(rawdb.SnapshotAccountPrefix),
|
it: dl.diskdb.NewIterator(rawdb.SnapshotAccountPrefix, pos),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ func wipeKeyRange(db ethdb.KeyValueStore, kind string, prefix []byte, keylen int
|
|||||||
// Iterate over the key-range and delete all of them
|
// Iterate over the key-range and delete all of them
|
||||||
start, logged := time.Now(), time.Now()
|
start, logged := time.Now(), time.Now()
|
||||||
|
|
||||||
it := db.NewIteratorWithStart(prefix)
|
it := db.NewIterator(prefix, nil)
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
// Skip any keys with the correct prefix but wrong lenth (trie nodes)
|
// Skip any keys with the correct prefix but wrong lenth (trie nodes)
|
||||||
key := it.Key()
|
key := it.Key()
|
||||||
@ -113,7 +113,8 @@ func wipeKeyRange(db ethdb.KeyValueStore, kind string, prefix []byte, keylen int
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
batch.Reset()
|
batch.Reset()
|
||||||
it = db.NewIteratorWithStart(key)
|
seekPos := key[len(prefix):]
|
||||||
|
it = db.NewIterator(prefix, seekPos)
|
||||||
|
|
||||||
if time.Since(logged) > 8*time.Second {
|
if time.Since(logged) > 8*time.Second {
|
||||||
log.Info("Deleting state snapshot leftovers", "kind", kind, "wiped", items, "elapsed", common.PrettyDuration(time.Since(start)))
|
log.Info("Deleting state snapshot leftovers", "kind", kind, "wiped", items, "elapsed", common.PrettyDuration(time.Since(start)))
|
||||||
|
@ -60,7 +60,7 @@ func TestWipe(t *testing.T) {
|
|||||||
// Sanity check that all the keys are present
|
// Sanity check that all the keys are present
|
||||||
var items int
|
var items int
|
||||||
|
|
||||||
it := db.NewIteratorWithPrefix(rawdb.SnapshotAccountPrefix)
|
it := db.NewIterator(rawdb.SnapshotAccountPrefix, nil)
|
||||||
defer it.Release()
|
defer it.Release()
|
||||||
|
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
@ -69,7 +69,7 @@ func TestWipe(t *testing.T) {
|
|||||||
items++
|
items++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
it = db.NewIteratorWithPrefix(rawdb.SnapshotStoragePrefix)
|
it = db.NewIterator(rawdb.SnapshotStoragePrefix, nil)
|
||||||
defer it.Release()
|
defer it.Release()
|
||||||
|
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
@ -88,7 +88,7 @@ func TestWipe(t *testing.T) {
|
|||||||
<-wipeSnapshot(db, true)
|
<-wipeSnapshot(db, true)
|
||||||
|
|
||||||
// Iterate over the database end ensure no snapshot information remains
|
// Iterate over the database end ensure no snapshot information remains
|
||||||
it = db.NewIteratorWithPrefix(rawdb.SnapshotAccountPrefix)
|
it = db.NewIterator(rawdb.SnapshotAccountPrefix, nil)
|
||||||
defer it.Release()
|
defer it.Release()
|
||||||
|
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
@ -97,7 +97,7 @@ func TestWipe(t *testing.T) {
|
|||||||
t.Errorf("snapshot entry remained after wipe: %x", key)
|
t.Errorf("snapshot entry remained after wipe: %x", key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
it = db.NewIteratorWithPrefix(rawdb.SnapshotStoragePrefix)
|
it = db.NewIterator(rawdb.SnapshotStoragePrefix, nil)
|
||||||
defer it.Release()
|
defer it.Release()
|
||||||
|
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
@ -112,7 +112,7 @@ func TestWipe(t *testing.T) {
|
|||||||
// Iterate over the database and ensure miscellaneous items are present
|
// Iterate over the database and ensure miscellaneous items are present
|
||||||
items = 0
|
items = 0
|
||||||
|
|
||||||
it = db.NewIterator()
|
it = db.NewIterator(nil, nil)
|
||||||
defer it.Release()
|
defer it.Release()
|
||||||
|
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
|
@ -60,7 +60,7 @@ func TestUpdateLeaks(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that no data was leaked into the database
|
// Ensure that no data was leaked into the database
|
||||||
it := db.NewIterator()
|
it := db.NewIterator(nil, nil)
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
t.Errorf("State leaked into database: %x -> %x", it.Key(), it.Value())
|
t.Errorf("State leaked into database: %x -> %x", it.Key(), it.Value())
|
||||||
}
|
}
|
||||||
@ -118,7 +118,7 @@ func TestIntermediateLeaks(t *testing.T) {
|
|||||||
t.Errorf("can not commit trie %v to persistent database", finalRoot.Hex())
|
t.Errorf("can not commit trie %v to persistent database", finalRoot.Hex())
|
||||||
}
|
}
|
||||||
|
|
||||||
it := finalDb.NewIterator()
|
it := finalDb.NewIterator(nil, nil)
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
key, fvalue := it.Key(), it.Value()
|
key, fvalue := it.Key(), it.Value()
|
||||||
tvalue, err := transDb.Get(key)
|
tvalue, err := transDb.Get(key)
|
||||||
@ -131,7 +131,7 @@ func TestIntermediateLeaks(t *testing.T) {
|
|||||||
}
|
}
|
||||||
it.Release()
|
it.Release()
|
||||||
|
|
||||||
it = transDb.NewIterator()
|
it = transDb.NewIterator(nil, nil)
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
key, tvalue := it.Key(), it.Value()
|
key, tvalue := it.Key(), it.Value()
|
||||||
fvalue, err := finalDb.Get(key)
|
fvalue, err := finalDb.Get(key)
|
||||||
|
@ -147,7 +147,7 @@ var bloomBitsPrefix = []byte("bloomBits-")
|
|||||||
|
|
||||||
func clearBloomBits(db ethdb.Database) {
|
func clearBloomBits(db ethdb.Database) {
|
||||||
fmt.Println("Clearing bloombits data...")
|
fmt.Println("Clearing bloombits data...")
|
||||||
it := db.NewIteratorWithPrefix(bloomBitsPrefix)
|
it := db.NewIterator(bloomBitsPrefix, nil)
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
db.Delete(it.Key())
|
db.Delete(it.Key())
|
||||||
}
|
}
|
||||||
|
@ -317,7 +317,7 @@ func testGetNodeData(t *testing.T, protocol int) {
|
|||||||
// Fetch for now the entire chain db
|
// Fetch for now the entire chain db
|
||||||
hashes := []common.Hash{}
|
hashes := []common.Hash{}
|
||||||
|
|
||||||
it := db.NewIterator()
|
it := db.NewIterator(nil, nil)
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
if key := it.Key(); len(key) == common.HashLength {
|
if key := it.Key(); len(key) == common.HashLength {
|
||||||
hashes = append(hashes, common.BytesToHash(key))
|
hashes = append(hashes, common.BytesToHash(key))
|
||||||
|
@ -32,31 +32,32 @@ func TestDatabaseSuite(t *testing.T, New func() ethdb.KeyValueStore) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
content map[string]string
|
content map[string]string
|
||||||
prefix string
|
prefix string
|
||||||
|
start string
|
||||||
order []string
|
order []string
|
||||||
}{
|
}{
|
||||||
// Empty databases should be iterable
|
// Empty databases should be iterable
|
||||||
{map[string]string{}, "", nil},
|
{map[string]string{}, "", "", nil},
|
||||||
{map[string]string{}, "non-existent-prefix", nil},
|
{map[string]string{}, "non-existent-prefix", "", nil},
|
||||||
|
|
||||||
// Single-item databases should be iterable
|
// Single-item databases should be iterable
|
||||||
{map[string]string{"key": "val"}, "", []string{"key"}},
|
{map[string]string{"key": "val"}, "", "", []string{"key"}},
|
||||||
{map[string]string{"key": "val"}, "k", []string{"key"}},
|
{map[string]string{"key": "val"}, "k", "", []string{"key"}},
|
||||||
{map[string]string{"key": "val"}, "l", nil},
|
{map[string]string{"key": "val"}, "l", "", nil},
|
||||||
|
|
||||||
// Multi-item databases should be fully iterable
|
// Multi-item databases should be fully iterable
|
||||||
{
|
{
|
||||||
map[string]string{"k1": "v1", "k5": "v5", "k2": "v2", "k4": "v4", "k3": "v3"},
|
map[string]string{"k1": "v1", "k5": "v5", "k2": "v2", "k4": "v4", "k3": "v3"},
|
||||||
"",
|
"", "",
|
||||||
[]string{"k1", "k2", "k3", "k4", "k5"},
|
[]string{"k1", "k2", "k3", "k4", "k5"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
map[string]string{"k1": "v1", "k5": "v5", "k2": "v2", "k4": "v4", "k3": "v3"},
|
map[string]string{"k1": "v1", "k5": "v5", "k2": "v2", "k4": "v4", "k3": "v3"},
|
||||||
"k",
|
"k", "",
|
||||||
[]string{"k1", "k2", "k3", "k4", "k5"},
|
[]string{"k1", "k2", "k3", "k4", "k5"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
map[string]string{"k1": "v1", "k5": "v5", "k2": "v2", "k4": "v4", "k3": "v3"},
|
map[string]string{"k1": "v1", "k5": "v5", "k2": "v2", "k4": "v4", "k3": "v3"},
|
||||||
"l",
|
"l", "",
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
// Multi-item databases should be prefix-iterable
|
// Multi-item databases should be prefix-iterable
|
||||||
@ -65,7 +66,7 @@ func TestDatabaseSuite(t *testing.T, New func() ethdb.KeyValueStore) {
|
|||||||
"ka1": "va1", "ka5": "va5", "ka2": "va2", "ka4": "va4", "ka3": "va3",
|
"ka1": "va1", "ka5": "va5", "ka2": "va2", "ka4": "va4", "ka3": "va3",
|
||||||
"kb1": "vb1", "kb5": "vb5", "kb2": "vb2", "kb4": "vb4", "kb3": "vb3",
|
"kb1": "vb1", "kb5": "vb5", "kb2": "vb2", "kb4": "vb4", "kb3": "vb3",
|
||||||
},
|
},
|
||||||
"ka",
|
"ka", "",
|
||||||
[]string{"ka1", "ka2", "ka3", "ka4", "ka5"},
|
[]string{"ka1", "ka2", "ka3", "ka4", "ka5"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -73,7 +74,24 @@ func TestDatabaseSuite(t *testing.T, New func() ethdb.KeyValueStore) {
|
|||||||
"ka1": "va1", "ka5": "va5", "ka2": "va2", "ka4": "va4", "ka3": "va3",
|
"ka1": "va1", "ka5": "va5", "ka2": "va2", "ka4": "va4", "ka3": "va3",
|
||||||
"kb1": "vb1", "kb5": "vb5", "kb2": "vb2", "kb4": "vb4", "kb3": "vb3",
|
"kb1": "vb1", "kb5": "vb5", "kb2": "vb2", "kb4": "vb4", "kb3": "vb3",
|
||||||
},
|
},
|
||||||
"kc",
|
"kc", "",
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
// Multi-item databases should be prefix-iterable with start position
|
||||||
|
{
|
||||||
|
map[string]string{
|
||||||
|
"ka1": "va1", "ka5": "va5", "ka2": "va2", "ka4": "va4", "ka3": "va3",
|
||||||
|
"kb1": "vb1", "kb5": "vb5", "kb2": "vb2", "kb4": "vb4", "kb3": "vb3",
|
||||||
|
},
|
||||||
|
"ka", "3",
|
||||||
|
[]string{"ka3", "ka4", "ka5"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
map[string]string{
|
||||||
|
"ka1": "va1", "ka5": "va5", "ka2": "va2", "ka4": "va4", "ka3": "va3",
|
||||||
|
"kb1": "vb1", "kb5": "vb5", "kb2": "vb2", "kb4": "vb4", "kb3": "vb3",
|
||||||
|
},
|
||||||
|
"ka", "8",
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -86,7 +104,7 @@ func TestDatabaseSuite(t *testing.T, New func() ethdb.KeyValueStore) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Iterate over the database with the given configs and verify the results
|
// Iterate over the database with the given configs and verify the results
|
||||||
it, idx := db.NewIteratorWithPrefix([]byte(tt.prefix)), 0
|
it, idx := db.NewIterator([]byte(tt.prefix), []byte(tt.start)), 0
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
if len(tt.order) <= idx {
|
if len(tt.order) <= idx {
|
||||||
t.Errorf("test %d: prefix=%q more items than expected: checking idx=%d (key %q), expecting len=%d", i, tt.prefix, idx, it.Key(), len(tt.order))
|
t.Errorf("test %d: prefix=%q more items than expected: checking idx=%d (key %q), expecting len=%d", i, tt.prefix, idx, it.Key(), len(tt.order))
|
||||||
@ -124,62 +142,57 @@ func TestDatabaseSuite(t *testing.T, New func() ethdb.KeyValueStore) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
it := db.NewIterator()
|
it := db.NewIterator(nil, nil)
|
||||||
got, want := iterateKeys(it), keys
|
got, want := iterateKeys(it), keys
|
||||||
if err := it.Error(); err != nil {
|
if err := it.Error(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
it.Release()
|
|
||||||
if !reflect.DeepEqual(got, want) {
|
if !reflect.DeepEqual(got, want) {
|
||||||
t.Errorf("Iterator: got: %s; want: %s", got, want)
|
t.Errorf("Iterator: got: %s; want: %s", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
it := db.NewIteratorWithPrefix([]byte("1"))
|
it := db.NewIterator([]byte("1"), nil)
|
||||||
got, want := iterateKeys(it), []string{"1", "10", "11", "12"}
|
got, want := iterateKeys(it), []string{"1", "10", "11", "12"}
|
||||||
if err := it.Error(); err != nil {
|
if err := it.Error(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
it.Release()
|
|
||||||
if !reflect.DeepEqual(got, want) {
|
if !reflect.DeepEqual(got, want) {
|
||||||
t.Errorf("IteratorWithPrefix(1): got: %s; want: %s", got, want)
|
t.Errorf("IteratorWith(1,nil): got: %s; want: %s", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
it := db.NewIteratorWithPrefix([]byte("5"))
|
it := db.NewIterator([]byte("5"), nil)
|
||||||
got, want := iterateKeys(it), []string{}
|
got, want := iterateKeys(it), []string{}
|
||||||
if err := it.Error(); err != nil {
|
if err := it.Error(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
it.Release()
|
|
||||||
if !reflect.DeepEqual(got, want) {
|
if !reflect.DeepEqual(got, want) {
|
||||||
t.Errorf("IteratorWithPrefix(1): got: %s; want: %s", got, want)
|
t.Errorf("IteratorWith(5,nil): got: %s; want: %s", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
it := db.NewIteratorWithStart([]byte("2"))
|
it := db.NewIterator(nil, []byte("2"))
|
||||||
got, want := iterateKeys(it), []string{"2", "20", "21", "22", "3", "4", "6"}
|
got, want := iterateKeys(it), []string{"2", "20", "21", "22", "3", "4", "6"}
|
||||||
if err := it.Error(); err != nil {
|
if err := it.Error(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
it.Release()
|
|
||||||
if !reflect.DeepEqual(got, want) {
|
if !reflect.DeepEqual(got, want) {
|
||||||
t.Errorf("IteratorWithStart(2): got: %s; want: %s", got, want)
|
t.Errorf("IteratorWith(nil,2): got: %s; want: %s", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
it := db.NewIteratorWithStart([]byte("5"))
|
it := db.NewIterator(nil, []byte("5"))
|
||||||
got, want := iterateKeys(it), []string{"6"}
|
got, want := iterateKeys(it), []string{"6"}
|
||||||
if err := it.Error(); err != nil {
|
if err := it.Error(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
it.Release()
|
|
||||||
if !reflect.DeepEqual(got, want) {
|
if !reflect.DeepEqual(got, want) {
|
||||||
t.Errorf("IteratorWithStart(2): got: %s; want: %s", got, want)
|
t.Errorf("IteratorWith(nil,5): got: %s; want: %s", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -246,11 +259,10 @@ func TestDatabaseSuite(t *testing.T, New func() ethdb.KeyValueStore) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
it := db.NewIterator()
|
it := db.NewIterator(nil, nil)
|
||||||
if got, want := iterateKeys(it), []string{"1", "2", "3", "4"}; !reflect.DeepEqual(got, want) {
|
if got, want := iterateKeys(it), []string{"1", "2", "3", "4"}; !reflect.DeepEqual(got, want) {
|
||||||
t.Errorf("got: %s; want: %s", got, want)
|
t.Errorf("got: %s; want: %s", got, want)
|
||||||
}
|
}
|
||||||
it.Release()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
b.Reset()
|
b.Reset()
|
||||||
@ -267,11 +279,10 @@ func TestDatabaseSuite(t *testing.T, New func() ethdb.KeyValueStore) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
it := db.NewIterator()
|
it := db.NewIterator(nil, nil)
|
||||||
if got, want := iterateKeys(it), []string{"2", "3", "4", "5", "6"}; !reflect.DeepEqual(got, want) {
|
if got, want := iterateKeys(it), []string{"2", "3", "4", "5", "6"}; !reflect.DeepEqual(got, want) {
|
||||||
t.Errorf("got: %s; want: %s", got, want)
|
t.Errorf("got: %s; want: %s", got, want)
|
||||||
}
|
}
|
||||||
it.Release()
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -296,11 +307,10 @@ func TestDatabaseSuite(t *testing.T, New func() ethdb.KeyValueStore) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
it := db.NewIterator()
|
it := db.NewIterator(nil, nil)
|
||||||
if got := iterateKeys(it); !reflect.DeepEqual(got, want) {
|
if got := iterateKeys(it); !reflect.DeepEqual(got, want) {
|
||||||
t.Errorf("got: %s; want: %s", got, want)
|
t.Errorf("got: %s; want: %s", got, want)
|
||||||
}
|
}
|
||||||
it.Release()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -311,5 +321,6 @@ func iterateKeys(it ethdb.Iterator) []string {
|
|||||||
keys = append(keys, string(it.Key()))
|
keys = append(keys, string(it.Key()))
|
||||||
}
|
}
|
||||||
sort.Strings(keys)
|
sort.Strings(keys)
|
||||||
|
it.Release()
|
||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
|
@ -51,16 +51,11 @@ type Iterator interface {
|
|||||||
|
|
||||||
// Iteratee wraps the NewIterator methods of a backing data store.
|
// Iteratee wraps the NewIterator methods of a backing data store.
|
||||||
type Iteratee interface {
|
type Iteratee interface {
|
||||||
// NewIterator creates a binary-alphabetical iterator over the entire keyspace
|
// NewIterator creates a binary-alphabetical iterator over a subset
|
||||||
// contained within the key-value database.
|
// of database content with a particular key prefix, starting at a particular
|
||||||
NewIterator() Iterator
|
// initial key (or after, if it does not exist).
|
||||||
|
//
|
||||||
// NewIteratorWithStart creates a binary-alphabetical iterator over a subset of
|
// Note: This method assumes that the prefix is NOT part of the start, so there's
|
||||||
// database content starting at a particular initial key (or after, if it does
|
// no need for the caller to prepend the prefix to the start
|
||||||
// not exist).
|
NewIterator(prefix []byte, start []byte) Iterator
|
||||||
NewIteratorWithStart(start []byte) Iterator
|
|
||||||
|
|
||||||
// NewIteratorWithPrefix creates a binary-alphabetical iterator over a subset
|
|
||||||
// of database content with a particular key prefix.
|
|
||||||
NewIteratorWithPrefix(prefix []byte) Iterator
|
|
||||||
}
|
}
|
||||||
|
@ -183,23 +183,11 @@ func (db *Database) NewBatch() ethdb.Batch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewIterator creates a binary-alphabetical iterator over the entire keyspace
|
// NewIterator creates a binary-alphabetical iterator over a subset
|
||||||
// contained within the leveldb database.
|
// of database content with a particular key prefix, starting at a particular
|
||||||
func (db *Database) NewIterator() ethdb.Iterator {
|
// initial key (or after, if it does not exist).
|
||||||
return db.db.NewIterator(new(util.Range), nil)
|
func (db *Database) NewIterator(prefix []byte, start []byte) ethdb.Iterator {
|
||||||
}
|
return db.db.NewIterator(bytesPrefixRange(prefix, start), nil)
|
||||||
|
|
||||||
// NewIteratorWithStart creates a binary-alphabetical iterator over a subset of
|
|
||||||
// database content starting at a particular initial key (or after, if it does
|
|
||||||
// not exist).
|
|
||||||
func (db *Database) NewIteratorWithStart(start []byte) ethdb.Iterator {
|
|
||||||
return db.db.NewIterator(&util.Range{Start: start}, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewIteratorWithPrefix creates a binary-alphabetical iterator over a subset
|
|
||||||
// of database content with a particular key prefix.
|
|
||||||
func (db *Database) NewIteratorWithPrefix(prefix []byte) ethdb.Iterator {
|
|
||||||
return db.db.NewIterator(util.BytesPrefix(prefix), nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stat returns a particular internal stat of the database.
|
// Stat returns a particular internal stat of the database.
|
||||||
@ -488,3 +476,12 @@ func (r *replayer) Delete(key []byte) {
|
|||||||
}
|
}
|
||||||
r.failure = r.writer.Delete(key)
|
r.failure = r.writer.Delete(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bytesPrefixRange returns key range that satisfy
|
||||||
|
// - the given prefix, and
|
||||||
|
// - the given seek position
|
||||||
|
func bytesPrefixRange(prefix, start []byte) *util.Range {
|
||||||
|
r := util.BytesPrefix(prefix)
|
||||||
|
r.Start = append(r.Start, start...)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
@ -129,55 +129,26 @@ func (db *Database) NewBatch() ethdb.Batch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewIterator creates a binary-alphabetical iterator over the entire keyspace
|
// NewIterator creates a binary-alphabetical iterator over a subset
|
||||||
// contained within the memory database.
|
// of database content with a particular key prefix, starting at a particular
|
||||||
func (db *Database) NewIterator() ethdb.Iterator {
|
// initial key (or after, if it does not exist).
|
||||||
return db.NewIteratorWithStart(nil)
|
func (db *Database) NewIterator(prefix []byte, start []byte) ethdb.Iterator {
|
||||||
}
|
|
||||||
|
|
||||||
// NewIteratorWithStart creates a binary-alphabetical iterator over a subset of
|
|
||||||
// database content starting at a particular initial key (or after, if it does
|
|
||||||
// not exist).
|
|
||||||
func (db *Database) NewIteratorWithStart(start []byte) ethdb.Iterator {
|
|
||||||
db.lock.RLock()
|
|
||||||
defer db.lock.RUnlock()
|
|
||||||
|
|
||||||
var (
|
|
||||||
st = string(start)
|
|
||||||
keys = make([]string, 0, len(db.db))
|
|
||||||
values = make([][]byte, 0, len(db.db))
|
|
||||||
)
|
|
||||||
// Collect the keys from the memory database corresponding to the given start
|
|
||||||
for key := range db.db {
|
|
||||||
if key >= st {
|
|
||||||
keys = append(keys, key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Sort the items and retrieve the associated values
|
|
||||||
sort.Strings(keys)
|
|
||||||
for _, key := range keys {
|
|
||||||
values = append(values, db.db[key])
|
|
||||||
}
|
|
||||||
return &iterator{
|
|
||||||
keys: keys,
|
|
||||||
values: values,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewIteratorWithPrefix creates a binary-alphabetical iterator over a subset
|
|
||||||
// of database content with a particular key prefix.
|
|
||||||
func (db *Database) NewIteratorWithPrefix(prefix []byte) ethdb.Iterator {
|
|
||||||
db.lock.RLock()
|
db.lock.RLock()
|
||||||
defer db.lock.RUnlock()
|
defer db.lock.RUnlock()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
pr = string(prefix)
|
pr = string(prefix)
|
||||||
|
st = string(append(prefix, start...))
|
||||||
keys = make([]string, 0, len(db.db))
|
keys = make([]string, 0, len(db.db))
|
||||||
values = make([][]byte, 0, len(db.db))
|
values = make([][]byte, 0, len(db.db))
|
||||||
)
|
)
|
||||||
// Collect the keys from the memory database corresponding to the given prefix
|
// Collect the keys from the memory database corresponding to the given prefix
|
||||||
|
// and start
|
||||||
for key := range db.db {
|
for key := range db.db {
|
||||||
if strings.HasPrefix(key, pr) {
|
if !strings.HasPrefix(key, pr) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if key >= st {
|
||||||
keys = append(keys, key)
|
keys = append(keys, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -691,6 +691,14 @@ func (db *nodeDB) close() {
|
|||||||
close(db.closeCh)
|
close(db.closeCh)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *nodeDB) getPrefix(neg bool) []byte {
|
||||||
|
prefix := positiveBalancePrefix
|
||||||
|
if neg {
|
||||||
|
prefix = negativeBalancePrefix
|
||||||
|
}
|
||||||
|
return append(db.verbuf[:], prefix...)
|
||||||
|
}
|
||||||
|
|
||||||
func (db *nodeDB) key(id []byte, neg bool) []byte {
|
func (db *nodeDB) key(id []byte, neg bool) []byte {
|
||||||
prefix := positiveBalancePrefix
|
prefix := positiveBalancePrefix
|
||||||
if neg {
|
if neg {
|
||||||
@ -761,7 +769,8 @@ func (db *nodeDB) getPosBalanceIDs(start, stop enode.ID, maxCount int) (result [
|
|||||||
if maxCount <= 0 {
|
if maxCount <= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
it := db.db.NewIteratorWithStart(db.key(start.Bytes(), false))
|
prefix := db.getPrefix(false)
|
||||||
|
it := db.db.NewIterator(prefix, start.Bytes())
|
||||||
defer it.Release()
|
defer it.Release()
|
||||||
for i := len(stop[:]) - 1; i >= 0; i-- {
|
for i := len(stop[:]) - 1; i >= 0; i-- {
|
||||||
stop[i]--
|
stop[i]--
|
||||||
@ -840,8 +849,9 @@ func (db *nodeDB) expireNodes() {
|
|||||||
visited int
|
visited int
|
||||||
deleted int
|
deleted int
|
||||||
start = time.Now()
|
start = time.Now()
|
||||||
|
prefix = db.getPrefix(true)
|
||||||
)
|
)
|
||||||
iter := db.db.NewIteratorWithPrefix(append(db.verbuf[:], negativeBalancePrefix...))
|
iter := db.db.NewIterator(prefix, nil)
|
||||||
for iter.Next() {
|
for iter.Next() {
|
||||||
visited += 1
|
visited += 1
|
||||||
var balance negBalance
|
var balance negBalance
|
||||||
|
@ -120,7 +120,7 @@ func TestNodeIteratorCoverage(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
it := db.diskdb.NewIterator()
|
it := db.diskdb.NewIterator(nil, nil)
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
key := it.Key()
|
key := it.Key()
|
||||||
if _, ok := hashes[common.BytesToHash(key)]; !ok {
|
if _, ok := hashes[common.BytesToHash(key)]; !ok {
|
||||||
@ -312,7 +312,7 @@ func testIteratorContinueAfterError(t *testing.T, memonly bool) {
|
|||||||
if memonly {
|
if memonly {
|
||||||
memKeys = triedb.Nodes()
|
memKeys = triedb.Nodes()
|
||||||
} else {
|
} else {
|
||||||
it := diskdb.NewIterator()
|
it := diskdb.NewIterator(nil, nil)
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
diskKeys = append(diskKeys, it.Key())
|
diskKeys = append(diskKeys, it.Key())
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ func TestBadProof(t *testing.T) {
|
|||||||
if proof == nil {
|
if proof == nil {
|
||||||
t.Fatalf("prover %d: nil proof", i)
|
t.Fatalf("prover %d: nil proof", i)
|
||||||
}
|
}
|
||||||
it := proof.NewIterator()
|
it := proof.NewIterator(nil, nil)
|
||||||
for i, d := 0, mrand.Intn(proof.Len()); i <= d; i++ {
|
for i, d := 0, mrand.Intn(proof.Len()); i <= d; i++ {
|
||||||
it.Next()
|
it.Next()
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ func (b *SyncBloom) init(database ethdb.Iteratee) {
|
|||||||
// Note, this is fine, because everything inserted into leveldb by fast sync is
|
// Note, this is fine, because everything inserted into leveldb by fast sync is
|
||||||
// also pushed into the bloom directly, so we're not missing anything when the
|
// also pushed into the bloom directly, so we're not missing anything when the
|
||||||
// iterator is swapped out for a new one.
|
// iterator is swapped out for a new one.
|
||||||
it := database.NewIterator()
|
it := database.NewIterator(nil, nil)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
start = time.Now()
|
start = time.Now()
|
||||||
@ -116,7 +116,7 @@ func (b *SyncBloom) init(database ethdb.Iteratee) {
|
|||||||
key := common.CopyBytes(it.Key())
|
key := common.CopyBytes(it.Key())
|
||||||
|
|
||||||
it.Release()
|
it.Release()
|
||||||
it = database.NewIteratorWithStart(key)
|
it = database.NewIterator(nil, key)
|
||||||
|
|
||||||
log.Info("Initializing fast sync bloom", "items", b.bloom.N(), "errorrate", b.errorRate(), "elapsed", common.PrettyDuration(time.Since(start)))
|
log.Info("Initializing fast sync bloom", "items", b.bloom.N(), "errorrate", b.errorRate(), "elapsed", common.PrettyDuration(time.Since(start)))
|
||||||
swap = time.Now()
|
swap = time.Now()
|
||||||
|
Loading…
Reference in New Issue
Block a user