Add tracker interface and tests #3
22
iterator.go
22
iterator.go
@ -23,16 +23,21 @@ import (
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
)
|
||||
|
||||
// PrefixBoundIterator is a NodeIterator constrained by a lower & upper bound (as hex path prefixes)
|
||||
type PrefixBoundIterator struct {
|
||||
trie.NodeIterator
|
||||
EndPath []byte
|
||||
}
|
||||
|
||||
// IteratorConstructor is a constructor returning a NodeIterator, which is used to decouple this
|
||||
// code from the trie implementation.
|
||||
type IteratorConstructor = func(startKey []byte) trie.NodeIterator
|
||||
|
||||
// PrefixBoundIterator is a NodeIterator constrained by a lower & upper bound (as hex path prefixes)
|
||||
type PrefixBoundIterator struct {
|
||||
trie.NodeIterator
|
||||
StartPath, EndPath []byte
|
||||
}
|
||||
|
||||
// NewPrefixBoundIterator returns an iterator with an upper bound value (hex path prefix)
|
||||
func NewPrefixBoundIterator(it trie.NodeIterator, to []byte) *PrefixBoundIterator {
|
||||
return &PrefixBoundIterator{NodeIterator: it, StartPath: it.Path(), EndPath: to}
|
||||
}
|
||||
|
||||
func (it *PrefixBoundIterator) Next(descend bool) bool {
|
||||
if it.EndPath == nil {
|
||||
return it.NodeIterator.Next(descend)
|
||||
@ -49,9 +54,8 @@ func (it *PrefixBoundIterator) Next(descend bool) bool {
|
||||
return bytes.Compare(it.Path(), it.EndPath) <= 0
|
||||
}
|
||||
|
||||
// NewPrefixBoundIterator returns an iterator with an upper bound value (hex path prefix)
|
||||
func NewPrefixBoundIterator(it trie.NodeIterator, to []byte) *PrefixBoundIterator {
|
||||
return &PrefixBoundIterator{NodeIterator: it, EndPath: to}
|
||||
func (it *PrefixBoundIterator) Bounds() ([]byte, []byte) {
|
||||
return it.StartPath, it.EndPath
|
||||
}
|
||||
|
||||
// generates nibble slice prefixes at uniform intervals
|
||||
|
@ -69,11 +69,7 @@ func (tr *Tracker) dump() error {
|
||||
log.Debug("Dumping recovery state", "to", tr.recoveryFile)
|
||||
var rows [][]string
|
||||
for it := range tr.started {
|
||||
var endPath []byte
|
||||
if impl, ok := it.NodeIterator.(*iter.PrefixBoundIterator); ok {
|
||||
endPath = impl.EndPath
|
||||
}
|
||||
|
||||
_, endPath := it.Bounds()
|
||||
rows = append(rows, []string{
|
||||
fmt.Sprintf("%x", it.Path()),
|
||||
fmt.Sprintf("%x", endPath),
|
||||
@ -184,6 +180,13 @@ func (it *Iterator) Next(descend bool) bool {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (it *Iterator) Bounds() ([]byte, []byte) {
|
||||
roysc marked this conversation as resolved
Outdated
|
||||
if impl, ok := it.NodeIterator.(*iter.PrefixBoundIterator); ok {
|
||||
return impl.Bounds()
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Rewinds to the path of the previous (pre-order) node:
|
||||
// If the last byte of the path is zero, pops it. Otherwise, decrements it
|
||||
// and pads with 0xF to 64 bytes (e.g. [1] => [0 f f f ...]).
|
||||
|
Loading…
Reference in New Issue
Block a user
Is it explicit anywhere that you must call CloseAndSave in order to close the channel, set running to false, etc?
What happens if you don't call that, but the iterator completes?
If we need to call it, I think the pattern:
Needs to be documented explicitly somewhere (unless I am just missing something).
If it's not called, it should just be sort of a leak. The channels won't be flushed or saved, but once all its iterators die, the tracker will still be gc'd. No critical consequences that I foresee, but I will document it.