aboutsummaryrefslogblamecommitdiffstats
path: root/trie/iterator.go
blob: 1114715a667727a10c714c9d1035608f414471d2 (plain) (tree)
1
2
3
4
5
6
7
            
 
  


               
                                                 








































































































































                                                                                                         
  
package trie

/*
import (
    "bytes"

    "github.com/ethereum/go-ethereum/ethutil"
)

type NodeType byte

const (
    EmptyNode NodeType = iota
    BranchNode
    LeafNode
    ExtNode
)

func getType(node *ethutil.Value) NodeType {
    if node.Len() == 0 {
        return EmptyNode
    }

    if node.Len() == 2 {
        k := CompactDecode(node.Get(0).Str())
        if HasTerm(k) {
            return LeafNode
        }

        return ExtNode
    }

    return BranchNode
}

type Iterator struct {
    Path [][]byte
    trie *Trie

    Key   []byte
    Value *ethutil.Value
}

func NewIterator(trie *Trie) *Iterator {
    return &Iterator{trie: trie}
}

func (self *Iterator) key(node *ethutil.Value, path [][]byte) []byte {
    switch getType(node) {
    case LeafNode:
        k := RemTerm(CompactDecode(node.Get(0).Str()))

        self.Path = append(path, k)
        self.Value = node.Get(1)

        return k
    case BranchNode:
        if node.Get(16).Len() > 0 {
            return []byte{16}
        }

        for i := byte(0); i < 16; i++ {
            o := self.key(self.trie.getNode(node.Get(int(i)).Raw()), append(path, []byte{i}))
            if o != nil {
                return append([]byte{i}, o...)
            }
        }
    case ExtNode:
        currKey := node.Get(0).Bytes()

        return self.key(self.trie.getNode(node.Get(1).Raw()), append(path, currKey))
    }

    return nil
}

func (self *Iterator) next(node *ethutil.Value, key []byte, path [][]byte) []byte {
    switch typ := getType(node); typ {
    case EmptyNode:
        return nil
    case BranchNode:
        if len(key) > 0 {
            subNode := self.trie.getNode(node.Get(int(key[0])).Raw())

            o := self.next(subNode, key[1:], append(path, key[:1]))
            if o != nil {
                return append([]byte{key[0]}, o...)
            }
        }

        var r byte = 0
        if len(key) > 0 {
            r = key[0] + 1
        }

        for i := r; i < 16; i++ {
            subNode := self.trie.getNode(node.Get(int(i)).Raw())
            o := self.key(subNode, append(path, []byte{i}))
            if o != nil {
                return append([]byte{i}, o...)
            }
        }
    case LeafNode, ExtNode:
        k := RemTerm(CompactDecode(node.Get(0).Str()))
        if typ == LeafNode {
            if bytes.Compare([]byte(k), []byte(key)) > 0 {
                self.Value = node.Get(1)
                self.Path = append(path, k)

                return k
            }
        } else {
            subNode := self.trie.getNode(node.Get(1).Raw())
            subKey := key[len(k):]
            var ret []byte
            if BeginsWith(key, k) {
                ret = self.next(subNode, subKey, append(path, k))
            } else if bytes.Compare(k, key[:len(k)]) > 0 {
                ret = self.key(node, append(path, k))
            } else {
                ret = nil
            }

            if ret != nil {
                return append(k, ret...)
            }
        }
    }

    return nil
}

// Get the next in keys
func (self *Iterator) Next(key string) []byte {
    self.trie.mut.Lock()
    defer self.trie.mut.Unlock()

    k := RemTerm(CompactHexDecode(key))
    n := self.next(self.trie.getNode(self.trie.Root), k, nil)

    self.Key = []byte(DecodeCompact(n))

    return self.Key
}
*/