Making Trie.iter non-recursive (#2733)

This commit is contained in:
Tomasz Drwięga 2016-10-20 14:49:44 +02:00 committed by Gav Wood
parent 906dcd7bfe
commit 0017a43364
2 changed files with 73 additions and 41 deletions

View File

@ -21,7 +21,7 @@ extern crate ethcore_util;
#[macro_use] #[macro_use]
extern crate log; extern crate log;
use test::Bencher; use test::{Bencher, black_box};
use ethcore_util::hash::*; use ethcore_util::hash::*;
use ethcore_util::bytes::*; use ethcore_util::bytes::*;
use ethcore_util::trie::*; use ethcore_util::trie::*;
@ -78,6 +78,32 @@ fn trie_insertions_32_mir_1k(b: &mut Bencher) {
}); });
// println!("hash_count: {}", hash_count); // println!("hash_count: {}", hash_count);
} }
#[bench]
fn trie_iter(b: &mut Bencher) {
let st = StandardMap {
alphabet: Alphabet::All,
min_key: 32,
journal_key: 0,
value_mode: ValueMode::Mirror,
count: 1000,
};
let d = st.make();
let mut memdb = MemoryDB::new();
let mut root = H256::new();
{
let mut t = TrieDBMut::new(&mut memdb, &mut root);
for i in d.iter() {
t.insert(&i.0, &i.1).unwrap();
}
}
b.iter(&mut ||{
let t = TrieDB::new(&memdb, &root).unwrap();
for n in t.iter().unwrap() {
black_box(n).unwrap();
}
});
}
#[bench] #[bench]
fn triehash_insertions_32_mir_1k(b: &mut Bencher) { fn triehash_insertions_32_mir_1k(b: &mut Bencher) {

View File

@ -304,14 +304,6 @@ impl<'a> TrieDBIterator<'a> {
Ok(()) Ok(())
} }
/// Descend into a payload and get the next item.
fn descend_next(&mut self, d: &'a [u8]) -> Option<TrieItem<'a>> {
match self.descend(d) {
Ok(()) => self.next(),
Err(e) => Some(Err(e)),
}
}
/// The present key. /// The present key.
fn key(&self) -> Bytes { fn key(&self) -> Bytes {
// collapse the key_nibbles down to bytes. // collapse the key_nibbles down to bytes.
@ -323,6 +315,7 @@ impl<'a> Iterator for TrieDBIterator<'a> {
type Item = TrieItem<'a>; type Item = TrieItem<'a>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
loop {
let b = match self.trail.last_mut() { let b = match self.trail.last_mut() {
Some(mut b) => { b.increment(); b.clone() }, Some(mut b) => { b.increment(); b.clone() },
None => return None, None => return None,
@ -338,25 +331,38 @@ impl<'a> Iterator for TrieDBIterator<'a> {
_ => {} _ => {}
} }
self.trail.pop(); self.trail.pop();
self.next() // continue
}, },
(Status::At, Node::Leaf(_, v)) | (Status::At, Node::Branch(_, Some(v))) => Some(Ok((self.key(), v))), (Status::At, Node::Leaf(_, v)) | (Status::At, Node::Branch(_, Some(v))) => {
(Status::At, Node::Extension(_, d)) => self.descend_next(d), return Some(Ok((self.key(), v)));
(Status::At, Node::Branch(_, _)) => self.next(), },
(Status::At, Node::Extension(_, d)) => {
if let Err(e) = self.descend(d) {
return Some(Err(e));
}
// continue
},
(Status::At, Node::Branch(_, _)) => {},
(Status::AtChild(i), Node::Branch(children, _)) if children[i].len() > 0 => { (Status::AtChild(i), Node::Branch(children, _)) if children[i].len() > 0 => {
match i { match i {
0 => self.key_nibbles.push(0), 0 => self.key_nibbles.push(0),
i => *self.key_nibbles.last_mut().unwrap() = i as u8, i => *self.key_nibbles.last_mut().unwrap() = i as u8,
} }
self.descend_next(children[i]) if let Err(e) = self.descend(children[i]) {
return Some(Err(e));
}
// continue
}, },
(Status::AtChild(i), Node::Branch(_, _)) => { (Status::AtChild(i), Node::Branch(_, _)) => {
if i == 0 { self.key_nibbles.push(0); } if i == 0 {
self.next() self.key_nibbles.push(0);
}
// continue
}, },
_ => panic!() // Should never see Entering or AtChild without a Branch here. _ => panic!() // Should never see Entering or AtChild without a Branch here.
} }
} }
}
} }
impl<'db> Trie for TrieDB<'db> { impl<'db> Trie for TrieDB<'db> {