github.com/murrekatt/go-ethereum@v1.5.8-0.20170123175102-fc52f2c007fb/trie/iterator.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package trie 18 19 import "github.com/ethereum/go-ethereum/common" 20 21 // Iterator is a key-value trie iterator that traverses a Trie. 22 type Iterator struct { 23 trie *Trie 24 nodeIt *NodeIterator 25 keyBuf []byte 26 27 Key []byte // Current data key on which the iterator is positioned on 28 Value []byte // Current data value on which the iterator is positioned on 29 } 30 31 // NewIterator creates a new key-value iterator. 32 func NewIterator(trie *Trie) *Iterator { 33 return &Iterator{ 34 trie: trie, 35 nodeIt: NewNodeIterator(trie), 36 keyBuf: make([]byte, 0, 64), 37 Key: nil, 38 } 39 } 40 41 // Next moves the iterator forward one key-value entry. 42 func (it *Iterator) Next() bool { 43 for it.nodeIt.Next() { 44 if it.nodeIt.Leaf { 45 it.Key = it.makeKey() 46 it.Value = it.nodeIt.LeafBlob 47 return true 48 } 49 } 50 it.Key = nil 51 it.Value = nil 52 return false 53 } 54 55 func (it *Iterator) makeKey() []byte { 56 key := it.keyBuf[:0] 57 for _, se := range it.nodeIt.stack { 58 switch node := se.node.(type) { 59 case *fullNode: 60 if se.child <= 16 { 61 key = append(key, byte(se.child)) 62 } 63 case *shortNode: 64 if hasTerm(node.Key) { 65 key = append(key, node.Key[:len(node.Key)-1]...) 66 } else { 67 key = append(key, node.Key...) 68 } 69 } 70 } 71 return decodeCompact(key) 72 } 73 74 // nodeIteratorState represents the iteration state at one particular node of the 75 // trie, which can be resumed at a later invocation. 76 type nodeIteratorState struct { 77 hash common.Hash // Hash of the node being iterated (nil if not standalone) 78 node node // Trie node being iterated 79 parent common.Hash // Hash of the first full ancestor node (nil if current is the root) 80 child int // Child to be processed next 81 } 82 83 // NodeIterator is an iterator to traverse the trie post-order. 84 type NodeIterator struct { 85 trie *Trie // Trie being iterated 86 stack []*nodeIteratorState // Hierarchy of trie nodes persisting the iteration state 87 88 Hash common.Hash // Hash of the current node being iterated (nil if not standalone) 89 Node node // Current node being iterated (internal representation) 90 Parent common.Hash // Hash of the first full ancestor node (nil if current is the root) 91 Leaf bool // Flag whether the current node is a value (data) node 92 LeafBlob []byte // Data blob contained within a leaf (otherwise nil) 93 94 Error error // Failure set in case of an internal error in the iterator 95 } 96 97 // NewNodeIterator creates an post-order trie iterator. 98 func NewNodeIterator(trie *Trie) *NodeIterator { 99 if trie.Hash() == emptyState { 100 return new(NodeIterator) 101 } 102 return &NodeIterator{trie: trie} 103 } 104 105 // Next moves the iterator to the next node, returning whether there are any 106 // further nodes. In case of an internal error this method returns false and 107 // sets the Error field to the encountered failure. 108 func (it *NodeIterator) Next() bool { 109 // If the iterator failed previously, don't do anything 110 if it.Error != nil { 111 return false 112 } 113 // Otherwise step forward with the iterator and report any errors 114 if err := it.step(); err != nil { 115 it.Error = err 116 return false 117 } 118 return it.retrieve() 119 } 120 121 // step moves the iterator to the next node of the trie. 122 func (it *NodeIterator) step() error { 123 if it.trie == nil { 124 // Abort if we reached the end of the iteration 125 return nil 126 } 127 if len(it.stack) == 0 { 128 // Initialize the iterator if we've just started. 129 root := it.trie.Hash() 130 state := &nodeIteratorState{node: it.trie.root, child: -1} 131 if root != emptyRoot { 132 state.hash = root 133 } 134 it.stack = append(it.stack, state) 135 } else { 136 // Continue iterating at the previous node otherwise. 137 it.stack = it.stack[:len(it.stack)-1] 138 if len(it.stack) == 0 { 139 it.trie = nil 140 return nil 141 } 142 } 143 144 // Continue iteration to the next child 145 for { 146 parent := it.stack[len(it.stack)-1] 147 ancestor := parent.hash 148 if (ancestor == common.Hash{}) { 149 ancestor = parent.parent 150 } 151 if node, ok := parent.node.(*fullNode); ok { 152 // Full node, traverse all children, then the node itself 153 if parent.child >= len(node.Children) { 154 break 155 } 156 for parent.child++; parent.child < len(node.Children); parent.child++ { 157 if current := node.Children[parent.child]; current != nil { 158 it.stack = append(it.stack, &nodeIteratorState{ 159 hash: common.BytesToHash(node.flags.hash), 160 node: current, 161 parent: ancestor, 162 child: -1, 163 }) 164 break 165 } 166 } 167 } else if node, ok := parent.node.(*shortNode); ok { 168 // Short node, traverse the pointer singleton child, then the node itself 169 if parent.child >= 0 { 170 break 171 } 172 parent.child++ 173 it.stack = append(it.stack, &nodeIteratorState{ 174 hash: common.BytesToHash(node.flags.hash), 175 node: node.Val, 176 parent: ancestor, 177 child: -1, 178 }) 179 } else if hash, ok := parent.node.(hashNode); ok { 180 // Hash node, resolve the hash child from the database, then the node itself 181 if parent.child >= 0 { 182 break 183 } 184 parent.child++ 185 186 node, err := it.trie.resolveHash(hash, nil, nil) 187 if err != nil { 188 return err 189 } 190 it.stack = append(it.stack, &nodeIteratorState{ 191 hash: common.BytesToHash(hash), 192 node: node, 193 parent: ancestor, 194 child: -1, 195 }) 196 } else { 197 break 198 } 199 } 200 return nil 201 } 202 203 // retrieve pulls and caches the current trie node the iterator is traversing. 204 // In case of a value node, the additional leaf blob is also populated with the 205 // data contents for external interpretation. 206 // 207 // The method returns whether there are any more data left for inspection. 208 func (it *NodeIterator) retrieve() bool { 209 // Clear out any previously set values 210 it.Hash, it.Node, it.Parent, it.Leaf, it.LeafBlob = common.Hash{}, nil, common.Hash{}, false, nil 211 212 // If the iteration's done, return no available data 213 if it.trie == nil { 214 return false 215 } 216 // Otherwise retrieve the current node and resolve leaf accessors 217 state := it.stack[len(it.stack)-1] 218 219 it.Hash, it.Node, it.Parent = state.hash, state.node, state.parent 220 if value, ok := it.Node.(valueNode); ok { 221 it.Leaf, it.LeafBlob = true, []byte(value) 222 } 223 return true 224 }