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,59 +217,76 @@ 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<()> {
let node = Node::decoded(&node_data); enum Step {
match node { Descend(DBValue, usize),
Node::Leaf(ref slice, _) => { Return,
if slice == key { }
self.trail.push(Crumb {
status: Status::At,
node: node.clone().into(),
});
} else {
self.trail.push(Crumb {
status: Status::Exiting,
node: node.clone().into(),
});
}
self.key_nibbles.extend(slice.iter()); loop {
Ok(()) let step = {
}, let node = Node::decoded(&node_data);
Node::Extension(ref slice, ref item) => { match node {
if key.starts_with(slice) { Node::Leaf(slice, _) => {
self.trail.push(Crumb { if slice == key {
status: Status::At, self.trail.push(Crumb {
node: node.clone().into(), status: Status::At,
}); node: node.clone().into(),
self.key_nibbles.extend(slice.iter()); });
let data = self.db.get_raw_or_lookup(&*item)?; } else {
self.seek_descend(data, &key.mid(slice.len())) self.trail.push(Crumb {
} else { status: Status::Exiting,
self.descend(&node_data)?; node: node.clone().into(),
Ok(()) });
}
self.key_nibbles.extend(slice.iter());
Step::Return
},
Node::Extension(ref slice, ref item) => {
if key.starts_with(slice) {
self.trail.push(Crumb {
status: Status::At,
node: node.clone().into(),
});
self.key_nibbles.extend(slice.iter());
let data = self.db.get_raw_or_lookup(&*item)?;
Step::Descend(data, slice.len())
} else {
self.descend(&node_data)?;
Step::Return
}
},
Node::Branch(ref nodes, _) => match key.is_empty() {
true => {
self.trail.push(Crumb {
status: Status::At,
node: node.clone().into(),
});
Step::Return
},
false => {
let i = key.at(0);
self.trail.push(Crumb {
status: Status::AtChild(i as usize),
node: node.clone().into(),
});
self.key_nibbles.push(i);
let child = self.db.get_raw_or_lookup(&*nodes[i as usize])?;
Step::Descend(child, 1)
}
},
_ => Step::Return
} }
}, };
Node::Branch(ref nodes, _) => match key.is_empty() {
true => { match step {
self.trail.push(Crumb { Step::Return => return Ok(()),
status: Status::At, Step::Descend(data, mid) => {
node: node.clone().into(), node_data = data;
}); key = key.mid(mid);
Ok(())
},
false => {
let i = key.at(0);
self.trail.push(Crumb {
status: Status::AtChild(i as usize),
node: node.clone().into(),
});
self.key_nibbles.push(i);
let child = self.db.get_raw_or_lookup(&*nodes[i as usize])?;
self.seek_descend(child, &key.mid(1))
} }
}, }
_ => Ok(())
} }
} }
@ -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))
} }
} }