Merge pull request #6394 from paritytech/trie_recursion

removed recursion from triedbmut::lookup
This commit is contained in:
Marek Kotewicz 2017-08-30 10:07:44 +02:00 committed by GitHub
commit da91a07906

View File

@ -367,44 +367,50 @@ 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 { let mut handle = handle;
NodeHandle::Hash(ref hash) => Lookup { loop {
let (mid, child) = match *handle {
NodeHandle::Hash(ref hash) => return Lookup {
db: &*self.db, db: &*self.db,
query: DBValue::from_slice, query: DBValue::from_slice,
hash: hash.clone(), hash: hash.clone(),
}.look_up(partial), }.look_up(partial),
NodeHandle::InMemory(ref handle) => match self.storage[handle] { NodeHandle::InMemory(ref handle) => match self.storage[handle] {
Node::Empty => Ok(None), Node::Empty => return Ok(None),
Node::Leaf(ref key, ref value) => { Node::Leaf(ref key, ref value) => {
if NibbleSlice::from_encoded(key).0 == partial { if NibbleSlice::from_encoded(key).0 == partial {
Ok(Some(DBValue::from_slice(value))) return Ok(Some(DBValue::from_slice(value)));
} else { } else {
Ok(None) return Ok(None);
} }
} }
Node::Extension(ref slice, ref child) => { Node::Extension(ref slice, ref child) => {
let slice = NibbleSlice::from_encoded(slice).0; let slice = NibbleSlice::from_encoded(slice).0;
if partial.starts_with(&slice) { if partial.starts_with(&slice) {
self.lookup(partial.mid(slice.len()), child) (slice.len(), child)
} else { } else {
Ok(None) return Ok(None);
} }
} }
Node::Branch(ref children, ref value) => { Node::Branch(ref children, ref value) => {
if partial.is_empty() { if partial.is_empty() {
Ok(value.as_ref().map(|v| DBValue::from_slice(v))) return Ok(value.as_ref().map(|v| DBValue::from_slice(v)));
} else { } else {
let idx = partial.at(0); let idx = partial.at(0);
match children[idx as usize].as_ref() { match children[idx as usize].as_ref() {
Some(child) => self.lookup(partial.mid(1), child), Some(child) => (1, child),
None => Ok(None), None => return Ok(None),
} }
} }
} }
} }
};
partial = partial.mid(mid);
handle = child;
} }
} }