iterator.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. package trie
  2. import (
  3. "bytes"
  4. "github.com/ethereum/go-ethereum/ethutil"
  5. )
  6. type NodeType byte
  7. const (
  8. EmptyNode NodeType = iota
  9. BranchNode
  10. LeafNode
  11. ExtNode
  12. )
  13. func getType(node *ethutil.Value) NodeType {
  14. if node.Len() == 0 {
  15. return EmptyNode
  16. }
  17. if node.Len() == 2 {
  18. k := CompactDecode(node.Get(0).Str())
  19. if HasTerm(k) {
  20. return LeafNode
  21. }
  22. return ExtNode
  23. }
  24. return BranchNode
  25. }
  26. type Iterator struct {
  27. Path [][]byte
  28. trie *Trie
  29. Key []byte
  30. Value *ethutil.Value
  31. }
  32. func NewIterator(trie *Trie) *Iterator {
  33. return &Iterator{trie: trie}
  34. }
  35. func (self *Iterator) key(node *ethutil.Value, path [][]byte) []byte {
  36. switch getType(node) {
  37. case LeafNode:
  38. k := RemTerm(CompactDecode(node.Get(0).Str()))
  39. self.Path = append(path, k)
  40. self.Value = node.Get(1)
  41. return k
  42. case BranchNode:
  43. if node.Get(16).Len() > 0 {
  44. return []byte{16}
  45. }
  46. for i := byte(0); i < 16; i++ {
  47. o := self.key(self.trie.getNode(node.Get(int(i)).Raw()), append(path, []byte{i}))
  48. if o != nil {
  49. return append([]byte{i}, o...)
  50. }
  51. }
  52. case ExtNode:
  53. currKey := node.Get(0).Bytes()
  54. return self.key(self.trie.getNode(node.Get(1).Raw()), append(path, currKey))
  55. }
  56. return nil
  57. }
  58. func (self *Iterator) next(node *ethutil.Value, key []byte, path [][]byte) []byte {
  59. switch typ := getType(node); typ {
  60. case EmptyNode:
  61. return nil
  62. case BranchNode:
  63. if len(key) > 0 {
  64. subNode := self.trie.getNode(node.Get(int(key[0])).Raw())
  65. o := self.next(subNode, key[1:], append(path, key[:1]))
  66. if o != nil {
  67. return append([]byte{key[0]}, o...)
  68. }
  69. }
  70. var r byte = 0
  71. if len(key) > 0 {
  72. r = key[0] + 1
  73. }
  74. for i := r; i < 16; i++ {
  75. subNode := self.trie.getNode(node.Get(int(i)).Raw())
  76. o := self.key(subNode, append(path, []byte{i}))
  77. if o != nil {
  78. return append([]byte{i}, o...)
  79. }
  80. }
  81. case LeafNode, ExtNode:
  82. k := RemTerm(CompactDecode(node.Get(0).Str()))
  83. if typ == LeafNode {
  84. if bytes.Compare([]byte(k), []byte(key)) > 0 {
  85. self.Value = node.Get(1)
  86. self.Path = append(path, k)
  87. return k
  88. }
  89. } else {
  90. subNode := self.trie.getNode(node.Get(1).Raw())
  91. subKey := key[len(k):]
  92. var ret []byte
  93. if BeginsWith(key, k) {
  94. ret = self.next(subNode, subKey, append(path, k))
  95. } else if bytes.Compare(k, key[:len(k)]) > 0 {
  96. ret = self.key(node, append(path, k))
  97. } else {
  98. ret = nil
  99. }
  100. if ret != nil {
  101. return append(k, ret...)
  102. }
  103. }
  104. }
  105. return nil
  106. }
  107. // Get the next in keys
  108. func (self *Iterator) Next(key string) []byte {
  109. self.trie.mut.Lock()
  110. defer self.trie.mut.Unlock()
  111. k := RemTerm(CompactHexDecode(key))
  112. n := self.next(self.trie.getNode(self.trie.Root), k, nil)
  113. self.Key = []byte(DecodeCompact(n))
  114. return self.Key
  115. }