github.com/jonasnick/go-ethereum@v0.7.12-0.20150216215225-22176f05d387/trie/iterator.go (about) 1 package trie 2 3 import "bytes" 4 5 type Iterator struct { 6 trie *Trie 7 8 Key []byte 9 Value []byte 10 } 11 12 func NewIterator(trie *Trie) *Iterator { 13 return &Iterator{trie: trie, Key: make([]byte, 32)} 14 } 15 16 func (self *Iterator) Next() bool { 17 self.trie.mu.Lock() 18 defer self.trie.mu.Unlock() 19 20 key := RemTerm(CompactHexDecode(string(self.Key))) 21 k := self.next(self.trie.root, key) 22 23 self.Key = []byte(DecodeCompact(k)) 24 25 return len(k) > 0 26 } 27 28 func (self *Iterator) next(node Node, key []byte) []byte { 29 if node == nil { 30 return nil 31 } 32 33 switch node := node.(type) { 34 case *FullNode: 35 if len(key) > 0 { 36 k := self.next(node.branch(key[0]), key[1:]) 37 if k != nil { 38 return append([]byte{key[0]}, k...) 39 } 40 } 41 42 var r byte 43 if len(key) > 0 { 44 r = key[0] + 1 45 } 46 47 for i := r; i < 16; i++ { 48 k := self.key(node.branch(byte(i))) 49 if k != nil { 50 return append([]byte{i}, k...) 51 } 52 } 53 54 case *ShortNode: 55 k := RemTerm(node.Key()) 56 if vnode, ok := node.Value().(*ValueNode); ok { 57 if bytes.Compare([]byte(k), key) > 0 { 58 self.Value = vnode.Val() 59 return k 60 } 61 } else { 62 cnode := node.Value() 63 64 var ret []byte 65 skey := key[len(k):] 66 if BeginsWith(key, k) { 67 ret = self.next(cnode, skey) 68 } else if bytes.Compare(k, key[:len(k)]) > 0 { 69 return self.key(node) 70 } 71 72 if ret != nil { 73 return append(k, ret...) 74 } 75 } 76 } 77 78 return nil 79 } 80 81 func (self *Iterator) key(node Node) []byte { 82 switch node := node.(type) { 83 case *ShortNode: 84 // Leaf node 85 if vnode, ok := node.Value().(*ValueNode); ok { 86 k := RemTerm(node.Key()) 87 self.Value = vnode.Val() 88 89 return k 90 } else { 91 k := RemTerm(node.Key()) 92 return append(k, self.key(node.Value())...) 93 } 94 case *FullNode: 95 if node.Value() != nil { 96 self.Value = node.Value().(*ValueNode).Val() 97 98 return []byte{16} 99 } 100 101 for i := 0; i < 16; i++ { 102 k := self.key(node.branch(byte(i))) 103 if k != nil { 104 return append([]byte{byte(i)}, k...) 105 } 106 } 107 } 108 109 return nil 110 }