forked from TrueCloudLab/neoneo-go
core: add ability to traverse backwards for Billet
This commit is contained in:
parent
3ae1647940
commit
0cf525d62e
2 changed files with 23 additions and 9 deletions
|
@ -205,7 +205,7 @@ func (b *Billet) incrementRefAndStore(h util.Uint256, bs []byte) {
|
||||||
// returned from `process` function. It also replaces all HashNodes to their
|
// returned from `process` function. It also replaces all HashNodes to their
|
||||||
// "unhashed" counterparts until the stop condition is satisfied.
|
// "unhashed" counterparts until the stop condition is satisfied.
|
||||||
func (b *Billet) Traverse(process func(pathToNode []byte, node Node, nodeBytes []byte) bool, ignoreStorageErr bool) error {
|
func (b *Billet) Traverse(process func(pathToNode []byte, node Node, nodeBytes []byte) bool, ignoreStorageErr bool) error {
|
||||||
r, err := b.traverse(b.root, []byte{}, []byte{}, process, ignoreStorageErr)
|
r, err := b.traverse(b.root, []byte{}, []byte{}, process, ignoreStorageErr, false)
|
||||||
if err != nil && !errors.Is(err, errStop) {
|
if err != nil && !errors.Is(err, errStop) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,7 @@ func (b *Billet) Traverse(process func(pathToNode []byte, node Node, nodeBytes [
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Billet) traverse(curr Node, path, from []byte, process func(pathToNode []byte, node Node, nodeBytes []byte) bool, ignoreStorageErr bool) (Node, error) {
|
func (b *Billet) traverse(curr Node, path, from []byte, process func(pathToNode []byte, node Node, nodeBytes []byte) bool, ignoreStorageErr bool, backwards bool) (Node, error) {
|
||||||
if _, ok := curr.(EmptyNode); ok {
|
if _, ok := curr.(EmptyNode); ok {
|
||||||
// We're not interested in EmptyNodes, and they do not affect the
|
// We're not interested in EmptyNodes, and they do not affect the
|
||||||
// traversal process, thus remain them untouched.
|
// traversal process, thus remain them untouched.
|
||||||
|
@ -227,7 +227,7 @@ func (b *Billet) traverse(curr Node, path, from []byte, process func(pathToNode
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return b.traverse(r, path, from, process, ignoreStorageErr)
|
return b.traverse(r, path, from, process, ignoreStorageErr, backwards)
|
||||||
}
|
}
|
||||||
if len(from) == 0 {
|
if len(from) == 0 {
|
||||||
bytes := slice.Copy(curr.Bytes())
|
bytes := slice.Copy(curr.Bytes())
|
||||||
|
@ -242,22 +242,36 @@ func (b *Billet) traverse(curr Node, path, from []byte, process func(pathToNode
|
||||||
var (
|
var (
|
||||||
startIndex byte
|
startIndex byte
|
||||||
endIndex byte = childrenCount
|
endIndex byte = childrenCount
|
||||||
|
cmp = func(i int) bool {
|
||||||
|
return i < int(endIndex)
|
||||||
|
}
|
||||||
|
step = 1
|
||||||
)
|
)
|
||||||
|
if backwards {
|
||||||
|
startIndex, endIndex = lastChild, startIndex
|
||||||
|
cmp = func(i int) bool {
|
||||||
|
return i >= int(endIndex)
|
||||||
|
}
|
||||||
|
step = -1
|
||||||
|
}
|
||||||
if len(from) != 0 {
|
if len(from) != 0 {
|
||||||
endIndex = lastChild
|
endIndex = lastChild
|
||||||
|
if backwards {
|
||||||
|
endIndex = 0
|
||||||
|
}
|
||||||
startIndex, from = splitPath(from)
|
startIndex, from = splitPath(from)
|
||||||
}
|
}
|
||||||
for i := startIndex; i < endIndex; i++ {
|
for i := int(startIndex); cmp(i); i += step {
|
||||||
var newPath []byte
|
var newPath []byte
|
||||||
if i == lastChild {
|
if i == lastChild {
|
||||||
newPath = path
|
newPath = path
|
||||||
} else {
|
} else {
|
||||||
newPath = append(path, i)
|
newPath = append(path, byte(i))
|
||||||
}
|
}
|
||||||
if i != startIndex {
|
if byte(i) != startIndex {
|
||||||
from = []byte{}
|
from = []byte{}
|
||||||
}
|
}
|
||||||
r, err := b.traverse(n.Children[i], newPath, from, process, ignoreStorageErr)
|
r, err := b.traverse(n.Children[i], newPath, from, process, ignoreStorageErr, backwards)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(err, errStop) {
|
if !errors.Is(err, errStop) {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -276,7 +290,7 @@ func (b *Billet) traverse(curr Node, path, from []byte, process func(pathToNode
|
||||||
} else {
|
} else {
|
||||||
return b.tryCollapseExtension(n), nil
|
return b.tryCollapseExtension(n), nil
|
||||||
}
|
}
|
||||||
r, err := b.traverse(n.next, append(path, n.key...), from, process, ignoreStorageErr)
|
r, err := b.traverse(n.next, append(path, n.key...), from, process, ignoreStorageErr, backwards)
|
||||||
if err != nil && !errors.Is(err, errStop) {
|
if err != nil && !errors.Is(err, errStop) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -625,7 +625,7 @@ func (t *Trie) Find(prefix, from []byte, max int) ([]storage.KeyValue, error) {
|
||||||
}
|
}
|
||||||
return count >= max
|
return count >= max
|
||||||
}
|
}
|
||||||
_, err = b.traverse(start, path, fromP, process, false)
|
_, err = b.traverse(start, path, fromP, process, false, false)
|
||||||
if err != nil && !errors.Is(err, errStop) {
|
if err != nil && !errors.Is(err, errStop) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue