removed triedbmut recursion

This commit is contained in:
debris 2017-08-27 17:33:03 +02:00
parent 15c3233376
commit 9cb4c99e5b

View File

@ -367,43 +367,64 @@ impl<'a> TrieDBMut<'a> {
} }
// walk the trie, attempting to find the key's node. // walk the trie, attempting to find the key's node.
fn lookup<'x, 'key>(&'x self, partial: NibbleSlice<'key>, handle: &NodeHandle) -> super::Result<Option<DBValue>> fn lookup<'x, 'key>(&'x self, mut partial: NibbleSlice<'key>, handle: &NodeHandle) -> super::Result<Option<DBValue>>
where 'x: 'key where 'x: 'key
{ {
match *handle { enum Step<'s> {
NodeHandle::Hash(ref hash) => Lookup { Return(Option<DBValue>),
db: &*self.db, Lookup(usize, &'s NodeHandle),
query: DBValue::from_slice, }
hash: hash.clone(),
}.look_up(partial), let mut handle = handle;
NodeHandle::InMemory(ref handle) => match self.storage[handle] { loop {
Node::Empty => Ok(None), let step = {
Node::Leaf(ref key, ref value) => { match *handle {
if NibbleSlice::from_encoded(key).0 == partial { NodeHandle::Hash(ref hash) => {
Ok(Some(DBValue::from_slice(value))) let lookup = Lookup {
} else { db: &*self.db,
Ok(None) query: DBValue::from_slice,
} hash: hash.clone(),
} }.look_up(partial)?;
Node::Extension(ref slice, ref child) => { Step::Return(lookup)
let slice = NibbleSlice::from_encoded(slice).0; },
if partial.starts_with(&slice) { NodeHandle::InMemory(ref handle) => match self.storage[handle] {
self.lookup(partial.mid(slice.len()), child) Node::Empty => Step::Return(None),
} else { Node::Leaf(ref key, ref value) => {
Ok(None) if NibbleSlice::from_encoded(key).0 == partial {
} Step::Return(Some(DBValue::from_slice(value)))
} } else {
Node::Branch(ref children, ref value) => { Step::Return(None)
if partial.is_empty() { }
Ok(value.as_ref().map(|v| DBValue::from_slice(v))) }
} else { Node::Extension(ref slice, ref child) => {
let idx = partial.at(0); let slice = NibbleSlice::from_encoded(slice).0;
match children[idx as usize].as_ref() { if partial.starts_with(&slice) {
Some(child) => self.lookup(partial.mid(1), child), Step::Lookup(slice.len(), child)
None => Ok(None), } else {
Step::Return(None)
}
}
Node::Branch(ref children, ref value) => {
if partial.is_empty() {
Step::Return(value.as_ref().map(|v| DBValue::from_slice(v)))
} else {
let idx = partial.at(0);
match children[idx as usize].as_ref() {
Some(child) => Step::Lookup(1, child),
None => Step::Return(None),
}
}
} }
} }
} }
};
match step {
Step::Return(r) => return Ok(r),
Step::Lookup(mid, child) => {
partial = partial.mid(mid);
handle = child;
}
} }
} }
} }