iterator.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  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. package trie
  17. import (
  18. "bytes"
  19. "fmt"
  20. "github.com/ethereum/go-ethereum/logger"
  21. "github.com/ethereum/go-ethereum/logger/glog"
  22. )
  23. // Iterator is a key-value trie iterator to traverse the data contents.
  24. type Iterator struct {
  25. trie *Trie
  26. Key []byte // Current data key on which the iterator is positioned on
  27. Value []byte // Current data value on which the iterator is positioned on
  28. }
  29. // NewIterator creates a new key-value iterator.
  30. func NewIterator(trie *Trie) *Iterator {
  31. return &Iterator{trie: trie, Key: nil}
  32. }
  33. // Next moves the iterator forward with one key-value entry.
  34. func (self *Iterator) Next() bool {
  35. isIterStart := false
  36. if self.Key == nil {
  37. isIterStart = true
  38. self.Key = make([]byte, 32)
  39. }
  40. key := remTerm(compactHexDecode(self.Key))
  41. k := self.next(self.trie.root, key, isIterStart)
  42. self.Key = []byte(decodeCompact(k))
  43. return len(k) > 0
  44. }
  45. func (self *Iterator) next(node interface{}, key []byte, isIterStart bool) []byte {
  46. if node == nil {
  47. return nil
  48. }
  49. switch node := node.(type) {
  50. case fullNode:
  51. if len(key) > 0 {
  52. k := self.next(node[key[0]], key[1:], isIterStart)
  53. if k != nil {
  54. return append([]byte{key[0]}, k...)
  55. }
  56. }
  57. var r byte
  58. if len(key) > 0 {
  59. r = key[0] + 1
  60. }
  61. for i := r; i < 16; i++ {
  62. k := self.key(node[i])
  63. if k != nil {
  64. return append([]byte{i}, k...)
  65. }
  66. }
  67. case shortNode:
  68. k := remTerm(node.Key)
  69. if vnode, ok := node.Val.(valueNode); ok {
  70. switch bytes.Compare([]byte(k), key) {
  71. case 0:
  72. if isIterStart {
  73. self.Value = vnode
  74. return k
  75. }
  76. case 1:
  77. self.Value = vnode
  78. return k
  79. }
  80. } else {
  81. cnode := node.Val
  82. var ret []byte
  83. skey := key[len(k):]
  84. if bytes.HasPrefix(key, k) {
  85. ret = self.next(cnode, skey, isIterStart)
  86. } else if bytes.Compare(k, key[:len(k)]) > 0 {
  87. return self.key(node)
  88. }
  89. if ret != nil {
  90. return append(k, ret...)
  91. }
  92. }
  93. case hashNode:
  94. rn, err := self.trie.resolveHash(node, nil, nil)
  95. if err != nil && glog.V(logger.Error) {
  96. glog.Errorf("Unhandled trie error: %v", err)
  97. }
  98. return self.next(rn, key, isIterStart)
  99. }
  100. return nil
  101. }
  102. func (self *Iterator) key(node interface{}) []byte {
  103. switch node := node.(type) {
  104. case shortNode:
  105. // Leaf node
  106. k := remTerm(node.Key)
  107. if vnode, ok := node.Val.(valueNode); ok {
  108. self.Value = vnode
  109. return k
  110. }
  111. return append(k, self.key(node.Val)...)
  112. case fullNode:
  113. if node[16] != nil {
  114. self.Value = node[16].(valueNode)
  115. return []byte{16}
  116. }
  117. for i := 0; i < 16; i++ {
  118. k := self.key(node[i])
  119. if k != nil {
  120. return append([]byte{byte(i)}, k...)
  121. }
  122. }
  123. case hashNode:
  124. rn, err := self.trie.resolveHash(node, nil, nil)
  125. if err != nil && glog.V(logger.Error) {
  126. glog.Errorf("Unhandled trie error: %v", err)
  127. }
  128. return self.key(rn)
  129. }
  130. return nil
  131. }
  132. // nodeIteratorState represents the iteration state at one particular node of the
  133. // trie, which can be resumed at a later invocation.
  134. type nodeIteratorState struct {
  135. node node // Trie node being iterated
  136. child int // Child to be processed next
  137. }
  138. // NodeIterator is an iterator to traverse the trie post-order.
  139. type NodeIterator struct {
  140. trie *Trie // Trie being iterated
  141. stack []*nodeIteratorState // Hierarchy of trie nodes persisting the iteration state
  142. Node node // Current node being iterated (internal representation)
  143. Leaf bool // Flag whether the current node is a value (data) node
  144. LeafBlob []byte // Data blob contained within a leaf (otherwise nil)
  145. }
  146. // NewNodeIterator creates an post-order trie iterator.
  147. func NewNodeIterator(trie *Trie) *NodeIterator {
  148. if bytes.Compare(trie.Root(), emptyRoot.Bytes()) == 0 {
  149. return new(NodeIterator)
  150. }
  151. return &NodeIterator{trie: trie}
  152. }
  153. // Next moves the iterator to the next node, returning whether there are any
  154. // further nodes.
  155. func (it *NodeIterator) Next() bool {
  156. it.step()
  157. return it.retrieve()
  158. }
  159. // step moves the iterator to the next node of the trie.
  160. func (it *NodeIterator) step() {
  161. // Abort if we reached the end of the iteration
  162. if it.trie == nil {
  163. return
  164. }
  165. // Initialize the iterator if we've just started, or pop off the old node otherwise
  166. if len(it.stack) == 0 {
  167. it.stack = append(it.stack, &nodeIteratorState{node: it.trie.root, child: -1})
  168. if it.stack[0].node == nil {
  169. panic(fmt.Sprintf("root node missing: %x", it.trie.Root()))
  170. }
  171. } else {
  172. it.stack = it.stack[:len(it.stack)-1]
  173. if len(it.stack) == 0 {
  174. it.trie = nil
  175. return
  176. }
  177. }
  178. // Continue iteration to the next child
  179. for {
  180. parent := it.stack[len(it.stack)-1]
  181. if node, ok := parent.node.(fullNode); ok {
  182. // Full node, traverse all children, then the node itself
  183. if parent.child >= len(node) {
  184. break
  185. }
  186. for parent.child++; parent.child < len(node); parent.child++ {
  187. if current := node[parent.child]; current != nil {
  188. it.stack = append(it.stack, &nodeIteratorState{node: current, child: -1})
  189. break
  190. }
  191. }
  192. } else if node, ok := parent.node.(shortNode); ok {
  193. // Short node, traverse the pointer singleton child, then the node itself
  194. if parent.child >= 0 {
  195. break
  196. }
  197. parent.child++
  198. it.stack = append(it.stack, &nodeIteratorState{node: node.Val, child: -1})
  199. } else if node, ok := parent.node.(hashNode); ok {
  200. // Hash node, resolve the hash child from the database, then the node itself
  201. if parent.child >= 0 {
  202. break
  203. }
  204. parent.child++
  205. node, err := it.trie.resolveHash(node, nil, nil)
  206. if err != nil {
  207. panic(err)
  208. }
  209. it.stack = append(it.stack, &nodeIteratorState{node: node, child: -1})
  210. } else {
  211. break
  212. }
  213. }
  214. }
  215. // retrieve pulls and caches the current trie node the iterator is traversing.
  216. // In case of a value node, the additional leaf blob is also populated with the
  217. // data contents for external interpretation.
  218. //
  219. // The method returns whether there are any more data left for inspection.
  220. func (it *NodeIterator) retrieve() bool {
  221. // Clear out any previously set values
  222. it.Node, it.Leaf, it.LeafBlob = nil, false, nil
  223. // If the iteration's done, return no available data
  224. if it.trie == nil {
  225. return false
  226. }
  227. // Otherwise retrieve the current node and resolve leaf accessors
  228. it.Node = it.stack[len(it.stack)-1].node
  229. if value, ok := it.Node.(valueNode); ok {
  230. it.Leaf, it.LeafBlob = true, []byte(value)
  231. }
  232. return true
  233. }