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  }