triedb seek and descend is not recursive

This commit is contained in:
debris 2017-08-26 18:33:43 +02:00
parent b6024adf85
commit 5d6c53c9bd

View File

@ -217,10 +217,17 @@ impl<'a> TrieDBIterator<'a> {
Ok(r) Ok(r)
} }
fn seek_descend<'key>(&mut self, node_data: DBValue, key: &NibbleSlice<'key>) -> super::Result<()> { fn seek_descend<'key>(&mut self, mut node_data: DBValue, mut key: NibbleSlice<'key>) -> super::Result<()> {
enum Step {
Descend(DBValue, usize),
Return,
}
loop {
let step = {
let node = Node::decoded(&node_data); let node = Node::decoded(&node_data);
match node { match node {
Node::Leaf(ref slice, _) => { Node::Leaf(slice, _) => {
if slice == key { if slice == key {
self.trail.push(Crumb { self.trail.push(Crumb {
status: Status::At, status: Status::At,
@ -234,7 +241,7 @@ impl<'a> TrieDBIterator<'a> {
} }
self.key_nibbles.extend(slice.iter()); self.key_nibbles.extend(slice.iter());
Ok(()) Step::Return
}, },
Node::Extension(ref slice, ref item) => { Node::Extension(ref slice, ref item) => {
if key.starts_with(slice) { if key.starts_with(slice) {
@ -244,10 +251,10 @@ impl<'a> TrieDBIterator<'a> {
}); });
self.key_nibbles.extend(slice.iter()); self.key_nibbles.extend(slice.iter());
let data = self.db.get_raw_or_lookup(&*item)?; let data = self.db.get_raw_or_lookup(&*item)?;
self.seek_descend(data, &key.mid(slice.len())) Step::Descend(data, slice.len())
} else { } else {
self.descend(&node_data)?; self.descend(&node_data)?;
Ok(()) Step::Return
} }
}, },
Node::Branch(ref nodes, _) => match key.is_empty() { Node::Branch(ref nodes, _) => match key.is_empty() {
@ -256,7 +263,7 @@ impl<'a> TrieDBIterator<'a> {
status: Status::At, status: Status::At,
node: node.clone().into(), node: node.clone().into(),
}); });
Ok(()) Step::Return
}, },
false => { false => {
let i = key.at(0); let i = key.at(0);
@ -266,10 +273,20 @@ impl<'a> TrieDBIterator<'a> {
}); });
self.key_nibbles.push(i); self.key_nibbles.push(i);
let child = self.db.get_raw_or_lookup(&*nodes[i as usize])?; let child = self.db.get_raw_or_lookup(&*nodes[i as usize])?;
self.seek_descend(child, &key.mid(1)) Step::Descend(child, 1)
} }
}, },
_ => Ok(()) _ => Step::Return
}
};
match step {
Step::Return => return Ok(()),
Step::Descend(data, mid) => {
node_data = data;
key = key.mid(mid);
}
}
} }
} }
@ -314,7 +331,7 @@ impl<'a> TrieIterator for TrieDBIterator<'a> {
self.trail.clear(); self.trail.clear();
self.key_nibbles.clear(); self.key_nibbles.clear();
let root_rlp = self.db.root_data()?; let root_rlp = self.db.root_data()?;
self.seek_descend(root_rlp, &NibbleSlice::new(key)) self.seek_descend(root_rlp, NibbleSlice::new(key))
} }
} }