more changes for test file and function namings

This commit is contained in:
samuel 2025-09-02 20:26:56 +01:00 committed by Gary Rong
parent 9a72c83e6f
commit 6a812bcab0
4 changed files with 133 additions and 141 deletions

View file

@ -148,8 +148,8 @@ type nodeIterator struct {
pool []*nodeIteratorState // local pool for iterator states
// Fields for subtree iteration
prefix []byte // Prefix for subtree iteration (nil for full trie)
stop []byte // Stop boundary for subtree iteration (nil for full trie)
startKey []byte // Start key for subtree iteration (nil for full trie)
stopKey []byte // Stop key for subtree iteration (nil for full trie)
}
// errIteratorEnd is stored in nodeIterator.err when iteration is done.
@ -303,23 +303,23 @@ func (it *nodeIterator) Next(descend bool) bool {
// Check if we're still within the subtree boundaries
// Note: path is already hex-encoded by the iterator
if it.prefix != nil && len(path) > 0 {
prefixHex := keybytesToHex(it.prefix)
// Remove terminator from prefix hex if present
if hasTerm(prefixHex) {
prefixHex = prefixHex[:len(prefixHex)-1]
if it.startKey != nil && len(path) > 0 {
startKeyHex := keybytesToHex(it.startKey)
// Remove terminator from startKey hex if present
if hasTerm(startKeyHex) {
startKeyHex = startKeyHex[:len(startKeyHex)-1]
}
if !bytes.HasPrefix(path, prefixHex) {
if !bytes.HasPrefix(path, startKeyHex) {
it.err = errIteratorEnd
return false
}
}
if it.stop != nil && len(path) > 0 {
stopHex := keybytesToHex(it.stop)
if hasTerm(stopHex) {
stopHex = stopHex[:len(stopHex)-1]
if it.stopKey != nil && len(path) > 0 {
stopKeyHex := keybytesToHex(it.stopKey)
if hasTerm(stopKeyHex) {
stopKeyHex = stopKeyHex[:len(stopKeyHex)-1]
}
if bytes.Compare(path, stopHex) >= 0 {
if bytes.Compare(path, stopKeyHex) >= 0 {
it.err = errIteratorEnd
return false
}
@ -867,25 +867,25 @@ func (it *unionIterator) Error() error {
}
// NewSubtreeIterator creates an iterator that only traverses nodes within a subtree
// defined by the given prefix and stopping point. The prefix defines where iteration
// starts, and stop defines where it ends (exclusive).
func NewSubtreeIterator(trie *Trie, prefix []byte, stop []byte) NodeIterator {
// defined by the given startKey and stopKey. The startKey defines where iteration
// starts, and stopKey defines where it ends (exclusive).
func NewSubtreeIterator(trie *Trie, startKey, stopKey []byte) NodeIterator {
if trie.Hash() == types.EmptyRootHash {
return &nodeIterator{
trie: trie,
err: errIteratorEnd,
prefix: prefix,
stop: stop,
startKey: startKey,
stopKey: stopKey,
}
}
it := &nodeIterator{
trie: trie,
prefix: prefix,
stop: stop,
startKey: startKey,
stopKey: stopKey,
}
// Seek to the starting position if prefix is provided
if prefix != nil && len(prefix) > 0 {
it.err = it.seek(prefix)
// Seek to the starting position if startKey is provided
if startKey != nil && len(startKey) > 0 {
it.err = it.seek(startKey)
} else {
state, err := it.init()
if err != nil {

View file

@ -676,6 +676,112 @@ func TestSubtreeIterator(t *testing.T) {
}
}
func TestPrefixIterator(t *testing.T) {
// Create a new trie
trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme))
// Insert test data
testData := map[string]string{
"key1": "value1",
"key2": "value2",
"key10": "value10",
"key11": "value11",
"different": "value_different",
}
for key, value := range testData {
trie.Update([]byte(key), []byte(value))
}
// Test prefix iteration for "key1" prefix
prefix := []byte("key1")
iter, err := trie.NodeIteratorWithPrefix(prefix)
if err != nil {
t.Fatalf("Failed to create prefix iterator: %v", err)
}
var foundKeys [][]byte
for iter.Next(true) {
if iter.Leaf() {
foundKeys = append(foundKeys, iter.LeafKey())
}
}
if err := iter.Error(); err != nil {
t.Fatalf("Iterator error: %v", err)
}
// Verify only keys starting with "key1" were found
expectedCount := 3 // "key1", "key10", "key11"
if len(foundKeys) != expectedCount {
t.Errorf("Expected %d keys, found %d", expectedCount, len(foundKeys))
}
for _, key := range foundKeys {
keyStr := string(key)
if !bytes.HasPrefix(key, prefix) {
t.Errorf("Found key %s doesn't have prefix %s", keyStr, string(prefix))
}
}
}
func TestPrefixIteratorVsFullIterator(t *testing.T) {
// Create a new trie with more structured data
trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme))
// Insert structured test data
testData := map[string]string{
"aaa": "value_aaa",
"aab": "value_aab",
"aba": "value_aba",
"bbb": "value_bbb",
}
for key, value := range testData {
trie.Update([]byte(key), []byte(value))
}
// Test that prefix iterator stops at boundary
prefix := []byte("aa")
prefixIter, err := trie.NodeIteratorWithPrefix(prefix)
if err != nil {
t.Fatalf("Failed to create prefix iterator: %v", err)
}
var prefixKeys [][]byte
for prefixIter.Next(true) {
if prefixIter.Leaf() {
prefixKeys = append(prefixKeys, prefixIter.LeafKey())
}
}
// Should only find "aaa" and "aab", not "aba" or "bbb"
if len(prefixKeys) != 2 {
t.Errorf("Expected 2 keys with prefix 'aa', found %d", len(prefixKeys))
}
// Verify no keys outside prefix were found
for _, key := range prefixKeys {
if !bytes.HasPrefix(key, prefix) {
t.Errorf("Prefix iterator returned key %s outside prefix %s", string(key), string(prefix))
}
}
}
func TestEmptyPrefixIterator(t *testing.T) {
// Test with empty trie
trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme))
iter, err := trie.NodeIteratorWithPrefix([]byte("nonexistent"))
if err != nil {
t.Fatalf("Failed to create iterator: %v", err)
}
if iter.Next(true) {
t.Error("Expected no results from empty trie")
}
}
func BenchmarkIterator(b *testing.B) {
diskDb, srcDb, tr, _ := makeTestTrie(rawdb.HashScheme)
root := tr.Hash()

View file

@ -1,114 +0,0 @@
package trie
import (
"bytes"
"testing"
"github.com/ethereum/go-ethereum/core/rawdb"
)
func TestPrefixIterator(t *testing.T) {
// Create a new trie
trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme))
// Insert test data
testData := map[string]string{
"key1": "value1",
"key2": "value2",
"key10": "value10",
"key11": "value11",
"different": "value_different",
}
for key, value := range testData {
trie.Update([]byte(key), []byte(value))
}
// Test prefix iteration for "key1" prefix
prefix := []byte("key1")
iter, err := trie.NodeIteratorWithPrefix(prefix)
if err != nil {
t.Fatalf("Failed to create prefix iterator: %v", err)
}
var foundKeys [][]byte
for iter.Next(true) {
if iter.Leaf() {
foundKeys = append(foundKeys, iter.LeafKey())
}
}
if err := iter.Error(); err != nil {
t.Fatalf("Iterator error: %v", err)
}
// Verify only keys starting with "key1" were found
expectedCount := 3 // "key1", "key10", "key11"
if len(foundKeys) != expectedCount {
t.Errorf("Expected %d keys, found %d", expectedCount, len(foundKeys))
}
for _, key := range foundKeys {
keyStr := string(key)
if !bytes.HasPrefix(key, prefix) {
t.Errorf("Found key %s doesn't have prefix %s", keyStr, string(prefix))
}
}
}
func TestPrefixIteratorVsFullIterator(t *testing.T) {
// Create a new trie with more structured data
trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme))
// Insert structured test data
testData := map[string]string{
"aaa": "value_aaa",
"aab": "value_aab",
"aba": "value_aba",
"bbb": "value_bbb",
}
for key, value := range testData {
trie.Update([]byte(key), []byte(value))
}
// Test that prefix iterator stops at boundary
prefix := []byte("aa")
prefixIter, err := trie.NodeIteratorWithPrefix(prefix)
if err != nil {
t.Fatalf("Failed to create prefix iterator: %v", err)
}
var prefixKeys [][]byte
for prefixIter.Next(true) {
if prefixIter.Leaf() {
prefixKeys = append(prefixKeys, prefixIter.LeafKey())
}
}
// Should only find "aaa" and "aab", not "aba" or "bbb"
if len(prefixKeys) != 2 {
t.Errorf("Expected 2 keys with prefix 'aa', found %d", len(prefixKeys))
}
// Verify no keys outside prefix were found
for _, key := range prefixKeys {
if !bytes.HasPrefix(key, prefix) {
t.Errorf("Prefix iterator returned key %s outside prefix %s", string(key), string(prefix))
}
}
}
func TestEmptyPrefixIterator(t *testing.T) {
// Test with empty trie
trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme))
iter, err := trie.NodeIteratorWithPrefix([]byte("nonexistent"))
if err != nil {
t.Fatalf("Failed to create iterator: %v", err)
}
if iter.Next(true) {
t.Error("Expected no results from empty trie")
}
}

View file

@ -141,7 +141,7 @@ func (t *Trie) NodeIteratorWithPrefix(prefix []byte) (NodeIterator, error) {
if t.committed {
return nil, ErrCommitted
}
// Use NewSubtreeIterator with just a prefix and no stop boundary
// Use NewSubtreeIterator with just a startKey and no stopKey boundary
return NewSubtreeIterator(t, prefix, nil), nil
}