triedb db is borrowed instead of being owned

This commit is contained in:
debris 2015-12-10 15:48:25 +01:00
parent 1a40416724
commit 4210b957ac

View File

@ -2,7 +2,6 @@
extern crate rand; extern crate rand;
use std::fmt; use std::fmt;
use memorydb::*;
use sha3::*; use sha3::*;
use hashdb::*; use hashdb::*;
use hash::*; use hash::*;
@ -279,10 +278,14 @@ impl <'a>Node<'a> {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// extern crate ethcore_util; /// extern crate ethcore_util as util;
/// use ethcore_util::trie::*; /// use util::trie::*;
/// use util::hashdb::*;
/// use util::memorydb::*;
///
/// fn main() { /// fn main() {
/// let mut t = TrieDB::new_memory(); /// let mut memdb = MemoryDB::new();
/// let mut t = TrieDB::new(&mut memdb);
/// assert!(t.is_empty()); /// assert!(t.is_empty());
/// assert_eq!(*t.root(), SHA3_NULL_RLP); /// assert_eq!(*t.root(), SHA3_NULL_RLP);
/// t.insert(b"foo", b"bar"); /// t.insert(b"foo", b"bar");
@ -294,8 +297,8 @@ impl <'a>Node<'a> {
/// assert!(t.db_items_remaining().is_empty()); /// assert!(t.db_items_remaining().is_empty());
/// } /// }
/// ``` /// ```
pub struct TrieDB { pub struct TrieDB<'db, T> where T: 'db + HashDB {
db: Box<HashDB>, db: &'db mut T,
root: H256, root: H256,
pub hash_count: usize, pub hash_count: usize,
} }
@ -306,18 +309,23 @@ enum MaybeChanged<'a> {
Changed(Bytes), Changed(Bytes),
} }
impl TrieDB { impl<'db, T> TrieDB<'db, T> where T: 'db + HashDB {
/// Create a new trie with the boxed backing database `box_db`. /// Create a new trie with the backing database `db`.
pub fn new_boxed(db_box: Box<HashDB>) -> Self { let mut r = TrieDB{ db: db_box, root: H256::new(), hash_count: 0 }; r.root = r.db.insert(&NULL_RLP); r } pub fn new(db: &'db mut T) -> Self {
let mut r = TrieDB{
db: db,
root: H256::new(),
hash_count: 0
};
/// Convenience function to create a new trie with the backing database `db`. r.root = r.db.insert(&NULL_RLP);
pub fn new<T>(db: T) -> Self where T: HashDB + 'static { Self::new_boxed(Box::new(db)) } r
}
/// Convenience function to create a new trie with a new `MemoryDB` based backing database.
pub fn new_memory() -> Self { Self::new(MemoryDB::new()) }
/// Get the backing database. /// Get the backing database.
pub fn db(&self) -> &HashDB { self.db.as_ref() } pub fn db(&'db self) -> &'db T {
self.db
}
/// Determine all the keys in the backing database that belong to the trie. /// Determine all the keys in the backing database that belong to the trie.
pub fn keys(&self) -> Vec<H256> { pub fn keys(&self) -> Vec<H256> {
@ -868,7 +876,7 @@ impl TrieDB {
} }
} }
impl Trie for TrieDB { impl<'db, T> Trie for TrieDB<'db, T> where T: 'db + HashDB {
fn root(&self) -> &H256 { &self.root } fn root(&self) -> &H256 { &self.root }
fn contains(&self, key: &[u8]) -> bool { fn contains(&self, key: &[u8]) -> bool {
@ -891,7 +899,7 @@ impl Trie for TrieDB {
} }
} }
impl fmt::Debug for TrieDB { impl<'db, T> fmt::Debug for TrieDB<'db, T> where T: 'db + HashDB {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(writeln!(f, "c={:?} [", self.hash_count)); try!(writeln!(f, "c={:?} [", self.hash_count));
let root_rlp = self.db.lookup(&self.root).expect("Trie root not found!"); let root_rlp = self.db.lookup(&self.root).expect("Trie root not found!");
@ -906,6 +914,8 @@ mod tests {
use self::json_tests::{trie, execute_tests_from_directory}; use self::json_tests::{trie, execute_tests_from_directory};
use triehash::*; use triehash::*;
use hash::*; use hash::*;
use hashdb::*;
use memorydb::*;
use super::*; use super::*;
use nibbleslice::*; use nibbleslice::*;
use rlp; use rlp;
@ -934,8 +944,8 @@ mod tests {
} }
} }
fn populate_trie(v: &Vec<(Vec<u8>, Vec<u8>)>) -> TrieDB { fn populate_trie<'db, T>(db: &'db mut T, v: &Vec<(Vec<u8>, Vec<u8>)>) -> TrieDB<'db, T> where T: 'db + HashDB {
let mut t = TrieDB::new_memory(); let mut t = TrieDB::new(db);
for i in 0..v.len() { for i in 0..v.len() {
let key: &[u8]= &v[i].0; let key: &[u8]= &v[i].0;
let val: &[u8] = &v[i].1; let val: &[u8] = &v[i].1;
@ -944,7 +954,7 @@ mod tests {
t t
} }
fn unpopulate_trie(t: &mut TrieDB, v: &Vec<(Vec<u8>, Vec<u8>)>) { fn unpopulate_trie<'a, 'db, T>(t: &mut TrieDB<'db, T>, v: &Vec<(Vec<u8>, Vec<u8>)>) where T: 'db + HashDB {
for i in v.iter() { for i in v.iter() {
let key: &[u8]= &i.0; let key: &[u8]= &i.0;
t.remove(&key); t.remove(&key);
@ -994,7 +1004,8 @@ mod tests {
} }
let real = trie_root(x.clone()); let real = trie_root(x.clone());
let mut memtrie = populate_trie(&x); let mut memdb = MemoryDB::new();
let mut memtrie = populate_trie(&mut memdb, &x);
if *memtrie.root() != real || !memtrie.db_items_remaining().is_empty() { if *memtrie.root() != real || !memtrie.db_items_remaining().is_empty() {
println!("TRIE MISMATCH"); println!("TRIE MISMATCH");
println!(""); println!("");
@ -1023,14 +1034,16 @@ mod tests {
#[test] #[test]
fn init() { fn init() {
let t = TrieDB::new_memory(); let mut memdb = MemoryDB::new();
let t = TrieDB::new(&mut memdb);
assert_eq!(*t.root(), SHA3_NULL_RLP); assert_eq!(*t.root(), SHA3_NULL_RLP);
assert!(t.is_empty()); assert!(t.is_empty());
} }
#[test] #[test]
fn insert_on_empty() { fn insert_on_empty() {
let mut t = TrieDB::new_memory(); let mut memdb = MemoryDB::new();
let mut t = TrieDB::new(&mut memdb);
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]); t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
assert_eq!(*t.root(), trie_root(vec![ (vec![0x01u8, 0x23], vec![0x01u8, 0x23]) ])); assert_eq!(*t.root(), trie_root(vec![ (vec![0x01u8, 0x23], vec![0x01u8, 0x23]) ]));
} }
@ -1039,12 +1052,14 @@ mod tests {
fn remove_to_empty() { fn remove_to_empty() {
let big_value = b"00000000000000000000000000000000"; let big_value = b"00000000000000000000000000000000";
let mut t1 = TrieDB::new_memory(); let mut memdb = MemoryDB::new();
let mut t1 = TrieDB::new(&mut memdb);
t1.insert(&[0x01, 0x23], &big_value.to_vec()); t1.insert(&[0x01, 0x23], &big_value.to_vec());
t1.insert(&[0x01, 0x34], &big_value.to_vec()); t1.insert(&[0x01, 0x34], &big_value.to_vec());
trace!("keys remaining {:?}", t1.db_items_remaining()); trace!("keys remaining {:?}", t1.db_items_remaining());
assert!(t1.db_items_remaining().is_empty()); assert!(t1.db_items_remaining().is_empty());
let mut t2 = TrieDB::new_memory(); let mut memdb2 = MemoryDB::new();
let mut t2 = TrieDB::new(&mut memdb2);
t2.insert(&[0x01], &big_value.to_vec()); t2.insert(&[0x01], &big_value.to_vec());
t2.insert(&[0x01, 0x23], &big_value.to_vec()); t2.insert(&[0x01, 0x23], &big_value.to_vec());
t2.insert(&[0x01, 0x34], &big_value.to_vec()); t2.insert(&[0x01, 0x34], &big_value.to_vec());
@ -1058,7 +1073,8 @@ mod tests {
#[test] #[test]
fn insert_replace_root() { fn insert_replace_root() {
let mut t = TrieDB::new_memory(); let mut memdb = MemoryDB::new();
let mut t = TrieDB::new(&mut memdb);
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]); t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
t.insert(&[0x01u8, 0x23], &[0x23u8, 0x45]); t.insert(&[0x01u8, 0x23], &[0x23u8, 0x45]);
assert_eq!(*t.root(), trie_root(vec![ (vec![0x01u8, 0x23], vec![0x23u8, 0x45]) ])); assert_eq!(*t.root(), trie_root(vec![ (vec![0x01u8, 0x23], vec![0x23u8, 0x45]) ]));
@ -1066,7 +1082,8 @@ mod tests {
#[test] #[test]
fn insert_make_branch_root() { fn insert_make_branch_root() {
let mut t = TrieDB::new_memory(); let mut memdb = MemoryDB::new();
let mut t = TrieDB::new(&mut memdb);
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]); t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
t.insert(&[0x11u8, 0x23], &[0x11u8, 0x23]); t.insert(&[0x11u8, 0x23], &[0x11u8, 0x23]);
assert_eq!(*t.root(), trie_root(vec![ assert_eq!(*t.root(), trie_root(vec![
@ -1077,7 +1094,8 @@ mod tests {
#[test] #[test]
fn insert_into_branch_root() { fn insert_into_branch_root() {
let mut t = TrieDB::new_memory(); let mut memdb = MemoryDB::new();
let mut t = TrieDB::new(&mut memdb);
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]); t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
t.insert(&[0xf1u8, 0x23], &[0xf1u8, 0x23]); t.insert(&[0xf1u8, 0x23], &[0xf1u8, 0x23]);
t.insert(&[0x81u8, 0x23], &[0x81u8, 0x23]); t.insert(&[0x81u8, 0x23], &[0x81u8, 0x23]);
@ -1090,7 +1108,8 @@ mod tests {
#[test] #[test]
fn insert_value_into_branch_root() { fn insert_value_into_branch_root() {
let mut t = TrieDB::new_memory(); let mut memdb = MemoryDB::new();
let mut t = TrieDB::new(&mut memdb);
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]); t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
t.insert(&[], &[0x0]); t.insert(&[], &[0x0]);
assert_eq!(*t.root(), trie_root(vec![ assert_eq!(*t.root(), trie_root(vec![
@ -1101,7 +1120,8 @@ mod tests {
#[test] #[test]
fn insert_split_leaf() { fn insert_split_leaf() {
let mut t = TrieDB::new_memory(); let mut memdb = MemoryDB::new();
let mut t = TrieDB::new(&mut memdb);
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]); t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
t.insert(&[0x01u8, 0x34], &[0x01u8, 0x34]); t.insert(&[0x01u8, 0x34], &[0x01u8, 0x34]);
assert_eq!(*t.root(), trie_root(vec![ assert_eq!(*t.root(), trie_root(vec![
@ -1112,7 +1132,8 @@ mod tests {
#[test] #[test]
fn insert_split_extenstion() { fn insert_split_extenstion() {
let mut t = TrieDB::new_memory(); let mut memdb = MemoryDB::new();
let mut t = TrieDB::new(&mut memdb);
t.insert(&[0x01, 0x23, 0x45], &[0x01]); t.insert(&[0x01, 0x23, 0x45], &[0x01]);
t.insert(&[0x01, 0xf3, 0x45], &[0x02]); t.insert(&[0x01, 0xf3, 0x45], &[0x02]);
t.insert(&[0x01, 0xf3, 0xf5], &[0x03]); t.insert(&[0x01, 0xf3, 0xf5], &[0x03]);
@ -1128,7 +1149,8 @@ mod tests {
let big_value0 = b"00000000000000000000000000000000"; let big_value0 = b"00000000000000000000000000000000";
let big_value1 = b"11111111111111111111111111111111"; let big_value1 = b"11111111111111111111111111111111";
let mut t = TrieDB::new_memory(); let mut memdb = MemoryDB::new();
let mut t = TrieDB::new(&mut memdb);
t.insert(&[0x01u8, 0x23], big_value0); t.insert(&[0x01u8, 0x23], big_value0);
t.insert(&[0x11u8, 0x23], big_value1); t.insert(&[0x11u8, 0x23], big_value1);
assert_eq!(*t.root(), trie_root(vec![ assert_eq!(*t.root(), trie_root(vec![
@ -1141,7 +1163,8 @@ mod tests {
fn insert_duplicate_value() { fn insert_duplicate_value() {
let big_value = b"00000000000000000000000000000000"; let big_value = b"00000000000000000000000000000000";
let mut t = TrieDB::new_memory(); let mut memdb = MemoryDB::new();
let mut t = TrieDB::new(&mut memdb);
t.insert(&[0x01u8, 0x23], big_value); t.insert(&[0x01u8, 0x23], big_value);
t.insert(&[0x11u8, 0x23], big_value); t.insert(&[0x11u8, 0x23], big_value);
assert_eq!(*t.root(), trie_root(vec![ assert_eq!(*t.root(), trie_root(vec![
@ -1199,20 +1222,23 @@ mod tests {
#[test] #[test]
fn test_at_empty() { fn test_at_empty() {
let t = TrieDB::new_memory(); let mut memdb = MemoryDB::new();
let t = TrieDB::new(&mut memdb);
assert_eq!(t.at(&[0x5]), None); assert_eq!(t.at(&[0x5]), None);
} }
#[test] #[test]
fn test_at_one() { fn test_at_one() {
let mut t = TrieDB::new_memory(); let mut memdb = MemoryDB::new();
let mut t = TrieDB::new(&mut memdb);
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]); t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
assert_eq!(t.at(&[0x1, 0x23]).unwrap(), &[0x1u8, 0x23]); assert_eq!(t.at(&[0x1, 0x23]).unwrap(), &[0x1u8, 0x23]);
} }
#[test] #[test]
fn test_at_three() { fn test_at_three() {
let mut t = TrieDB::new_memory(); let mut memdb = MemoryDB::new();
let mut t = TrieDB::new(&mut memdb);
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]); t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
t.insert(&[0xf1u8, 0x23], &[0xf1u8, 0x23]); t.insert(&[0xf1u8, 0x23], &[0xf1u8, 0x23]);
t.insert(&[0x81u8, 0x23], &[0x81u8, 0x23]); t.insert(&[0x81u8, 0x23], &[0x81u8, 0x23]);
@ -1224,7 +1250,8 @@ mod tests {
#[test] #[test]
fn test_print_trie() { fn test_print_trie() {
let mut t = TrieDB::new_memory(); let mut memdb = MemoryDB::new();
let mut t = TrieDB::new(&mut memdb);
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]); t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
t.insert(&[0x02u8, 0x23], &[0x01u8, 0x23]); t.insert(&[0x02u8, 0x23], &[0x01u8, 0x23]);
t.insert(&[0xf1u8, 0x23], &[0xf1u8, 0x23]); t.insert(&[0xf1u8, 0x23], &[0xf1u8, 0x23]);
@ -1244,10 +1271,12 @@ mod tests {
x.push((key, rlp::encode(&j))); x.push((key, rlp::encode(&j)));
} }
let real = trie_root(x.clone()); let real = trie_root(x.clone());
let memtrie = populate_trie(&x); let mut memdb = MemoryDB::new();
let memtrie = populate_trie(&mut memdb, &x);
let mut y = x.clone(); let mut y = x.clone();
y.sort_by(|ref a, ref b| a.0.cmp(&b.0)); y.sort_by(|ref a, ref b| a.0.cmp(&b.0));
let memtrie_sorted = populate_trie(&y); let mut memdb2 = MemoryDB::new();
let memtrie_sorted = populate_trie(&mut memdb2, &y);
if *memtrie.root() != real || *memtrie_sorted.root() != real { if *memtrie.root() != real || *memtrie_sorted.root() != real {
println!("TRIE MISMATCH"); println!("TRIE MISMATCH");
println!(""); println!("");
@ -1273,7 +1302,8 @@ mod tests {
execute_tests_from_directory::<trie::TrieTest, _>("json-tests/json/trie/*.json", &mut | file, input, output | { execute_tests_from_directory::<trie::TrieTest, _>("json-tests/json/trie/*.json", &mut | file, input, output | {
println!("file: {}", file); println!("file: {}", file);
let mut t = TrieDB::new_memory(); let mut memdb = MemoryDB::new();
let mut t = TrieDB::new(&mut memdb);
for operation in input.into_iter() { for operation in input.into_iter() {
match operation { match operation {
trie::Operation::Insert(key, value) => t.insert(&key, &value), trie::Operation::Insert(key, value) => t.insert(&key, &value),