removed triedbmut recursion
This commit is contained in:
parent
15c3233376
commit
9cb4c99e5b
@ -367,45 +367,66 @@ 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
|
||||||
{
|
{
|
||||||
|
enum Step<'s> {
|
||||||
|
Return(Option<DBValue>),
|
||||||
|
Lookup(usize, &'s NodeHandle),
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut handle = handle;
|
||||||
|
loop {
|
||||||
|
let step = {
|
||||||
match *handle {
|
match *handle {
|
||||||
NodeHandle::Hash(ref hash) => Lookup {
|
NodeHandle::Hash(ref hash) => {
|
||||||
|
let lookup = 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)?;
|
||||||
|
Step::Return(lookup)
|
||||||
|
},
|
||||||
NodeHandle::InMemory(ref handle) => match self.storage[handle] {
|
NodeHandle::InMemory(ref handle) => match self.storage[handle] {
|
||||||
Node::Empty => Ok(None),
|
Node::Empty => Step::Return(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)))
|
Step::Return(Some(DBValue::from_slice(value)))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Step::Return(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)
|
Step::Lookup(slice.len(), child)
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Step::Return(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)))
|
Step::Return(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) => Step::Lookup(1, child),
|
||||||
None => Ok(None),
|
None => Step::Return(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match step {
|
||||||
|
Step::Return(r) => return Ok(r),
|
||||||
|
Step::Lookup(mid, child) => {
|
||||||
|
partial = partial.mid(mid);
|
||||||
|
handle = child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// insert a key, value pair into the trie, creating new nodes if necessary.
|
/// insert a key, value pair into the trie, creating new nodes if necessary.
|
||||||
|
Loading…
Reference in New Issue
Block a user