Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DB generic type instead of dyn Trait to allow use the DB outside of the trie #206

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions hash-db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,17 +157,17 @@ pub trait HashDBRef<H: Hasher, T> {
fn contains(&self, key: &H::Out, prefix: Prefix) -> bool;
}

impl<'a, H: Hasher, T> HashDBRef<H, T> for &'a dyn HashDB<H, T> {
fn get(&self, key: &H::Out, prefix: Prefix) -> Option<T> {
impl<'a, H: Hasher, V, T: HashDB<H, V>> HashDBRef<H, V> for &T {
fn get(&self, key: &H::Out, prefix: Prefix) -> Option<V> {
HashDB::get(*self, key, prefix)
}
fn contains(&self, key: &H::Out, prefix: Prefix) -> bool {
HashDB::contains(*self, key, prefix)
}
}

impl<'a, H: Hasher, T> HashDBRef<H, T> for &'a mut dyn HashDB<H, T> {
fn get(&self, key: &H::Out, prefix: Prefix) -> Option<T> {
impl<'a, H: Hasher, V, T: HashDB<H, V>> HashDBRef<H, V> for &mut T {
fn get(&self, key: &H::Out, prefix: Prefix) -> Option<V> {
HashDB::get(*self, key, prefix)
}
fn contains(&self, key: &H::Out, prefix: Prefix) -> bool {
Expand Down
53 changes: 27 additions & 26 deletions test-support/reference-trie/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,20 +174,21 @@ impl Bitmap {
}
}

pub type RefTrieDB<'a, 'cache> = trie_db::TrieDB<'a, 'cache, ExtensionLayout>;
pub type RefTrieDBBuilder<'a, 'cache> = trie_db::TrieDBBuilder<'a, 'cache, ExtensionLayout>;
pub type RefTrieDBMut<'a> = trie_db::TrieDBMut<'a, ExtensionLayout>;
pub type RefTrieDBMutBuilder<'a> = trie_db::TrieDBMutBuilder<'a, ExtensionLayout>;
pub type RefTrieDBMutNoExt<'a> = trie_db::TrieDBMut<'a, NoExtensionLayout>;
pub type RefTrieDBMutNoExtBuilder<'a> = trie_db::TrieDBMutBuilder<'a, NoExtensionLayout>;
pub type RefTrieDBMutAllowEmpty<'a> = trie_db::TrieDBMut<'a, AllowEmptyLayout>;
pub type RefTrieDBMutAllowEmptyBuilder<'a> = trie_db::TrieDBMutBuilder<'a, AllowEmptyLayout>;
pub type RefTrieDB<'a, 'cache, DB> = trie_db::TrieDB<'a, 'cache, ExtensionLayout, DB>;
pub type RefTrieDBBuilder<'a, 'cache, DB> = trie_db::TrieDBBuilder<'a, 'cache, ExtensionLayout, DB>;
pub type RefTrieDBMut<'a, DB> = trie_db::TrieDBMut<'a, ExtensionLayout, DB>;
pub type RefTrieDBMutBuilder<'a, DB> = trie_db::TrieDBMutBuilder<'a, ExtensionLayout, DB>;
pub type RefTrieDBMutNoExt<'a, DB> = trie_db::TrieDBMut<'a, NoExtensionLayout, DB>;
pub type RefTrieDBMutNoExtBuilder<'a, DB> = trie_db::TrieDBMutBuilder<'a, NoExtensionLayout, DB>;
pub type RefTrieDBMutAllowEmpty<'a, DB> = trie_db::TrieDBMut<'a, AllowEmptyLayout, DB>;
pub type RefTrieDBMutAllowEmptyBuilder<'a, DB> =
trie_db::TrieDBMutBuilder<'a, AllowEmptyLayout, DB>;
pub type RefTestTrieDBCache = TestTrieCache<ExtensionLayout>;
pub type RefTestTrieDBCacheNoExt = TestTrieCache<NoExtensionLayout>;
pub type RefFatDB<'a, 'cache> = trie_db::FatDB<'a, 'cache, ExtensionLayout>;
pub type RefFatDBMut<'a> = trie_db::FatDBMut<'a, ExtensionLayout>;
pub type RefSecTrieDB<'a, 'cache> = trie_db::SecTrieDB<'a, 'cache, ExtensionLayout>;
pub type RefSecTrieDBMut<'a> = trie_db::SecTrieDBMut<'a, ExtensionLayout>;
pub type RefFatDB<'a, 'cache, DB> = trie_db::FatDB<'a, 'cache, ExtensionLayout, DB>;
pub type RefFatDBMut<'a, DB> = trie_db::FatDBMut<'a, ExtensionLayout, DB>;
pub type RefSecTrieDB<'a, 'cache, DB> = trie_db::SecTrieDB<'a, 'cache, ExtensionLayout, DB>;
pub type RefSecTrieDBMut<'a, DB> = trie_db::SecTrieDBMut<'a, ExtensionLayout, DB>;
pub type RefLookup<'a, 'cache, Q> = trie_db::Lookup<'a, 'cache, ExtensionLayout, Q>;
pub type RefLookupNoExt<'a, 'cache, Q> = trie_db::Lookup<'a, 'cache, NoExtensionLayout, Q>;

Expand Down Expand Up @@ -914,7 +915,7 @@ where
let root_new = calc_root_build::<T, _, _, _, _>(data.clone(), &mut hashdb);
let root = {
let mut root = Default::default();
let mut t = TrieDBMutBuilder::<T>::new(&mut memdb, &mut root).build();
let mut t = TrieDBMutBuilder::<T, DB>::new(&mut memdb, &mut root).build();
for i in 0..data.len() {
t.insert(&data[i].0[..], &data[i].1[..]).unwrap();
}
Expand All @@ -923,16 +924,16 @@ where
};
if root_new != root {
{
let db: &dyn hash_db::HashDB<_, _> = &hashdb;
let t = TrieDBBuilder::<T>::new(&db, &root_new).build();
let db: &DB = &hashdb;
let t = TrieDBBuilder::<T, _>::new(&db, &root_new).build();
println!("{:?}", t);
for a in t.iter().unwrap() {
println!("a:{:x?}", a);
}
}
{
let db: &dyn hash_db::HashDB<_, _> = &memdb;
let t = TrieDBBuilder::<T>::new(&db, &root).build();
let db: &DB = &memdb;
let t = TrieDBBuilder::<T, _>::new(&db, &root).build();
println!("{:?}", t);
for a in t.iter().unwrap() {
println!("a:{:x?}", a);
Expand All @@ -953,7 +954,7 @@ pub fn compare_root<T: TrieLayout, DB: hash_db::HashDB<T::Hash, DBValue>>(
let root_new = reference_trie_root_iter_build::<T, _, _, _>(data.clone());
let root = {
let mut root = Default::default();
let mut t = TrieDBMutBuilder::<T>::new(&mut memdb, &mut root).build();
let mut t = TrieDBMutBuilder::<T, DB>::new(&mut memdb, &mut root).build();
for i in 0..data.len() {
t.insert(&data[i].0[..], &data[i].1[..]).unwrap();
}
Expand Down Expand Up @@ -1028,7 +1029,7 @@ pub fn compare_implementations_unordered<T, DB>(
let mut b_map = std::collections::btree_map::BTreeMap::new();
let root = {
let mut root = Default::default();
let mut t = TrieDBMutBuilder::<T>::new(&mut memdb, &mut root).build();
let mut t = TrieDBMutBuilder::<T, DB>::new(&mut memdb, &mut root).build();
for i in 0..data.len() {
t.insert(&data[i].0[..], &data[i].1[..]).unwrap();
b_map.insert(data[i].0.clone(), data[i].1.clone());
Expand All @@ -1043,16 +1044,16 @@ pub fn compare_implementations_unordered<T, DB>(

if root != root_new {
{
let db: &dyn hash_db::HashDB<_, _> = &memdb;
let t = TrieDBBuilder::<T>::new(&db, &root).build();
let db: &DB = &memdb;
let t: trie_db::TrieDB<'_, '_, T, &DB> = TrieDBBuilder::<T, _>::new(&db, &root).build();
println!("{:?}", t);
for a in t.iter().unwrap() {
println!("a:{:?}", a);
}
}
{
let db: &dyn hash_db::HashDB<_, _> = &hashdb;
let t = TrieDBBuilder::<T>::new(&db, &root_new).build();
let db: &DB = &hashdb;
let t = TrieDBBuilder::<T, _>::new(&db, &root_new).build();
println!("{:?}", t);
for a in t.iter().unwrap() {
println!("a:{:?}", a);
Expand All @@ -1076,13 +1077,13 @@ pub fn compare_insert_remove<T, DB: hash_db::HashDB<T::Hash, DBValue>>(
let mut root = Default::default();
let mut a = 0;
{
let mut t = TrieDBMutBuilder::<T>::new(&mut memdb, &mut root).build();
let mut t = TrieDBMutBuilder::<T, DB>::new(&mut memdb, &mut root).build();
t.commit();
}
while a < data.len() {
// new triemut every 3 element
root = {
let mut t = TrieDBMutBuilder::<T>::from_existing(&mut memdb, &mut root).build();
let mut t = TrieDBMutBuilder::<T, DB>::from_existing(&mut memdb, &mut root).build();
for _ in 0..3 {
if data[a].0 {
// remove
Expand All @@ -1103,7 +1104,7 @@ pub fn compare_insert_remove<T, DB: hash_db::HashDB<T::Hash, DBValue>>(
*t.root()
};
}
let mut t = TrieDBMutBuilder::<T>::from_existing(&mut memdb, &mut root).build();
let mut t = TrieDBMutBuilder::<T, DB>::from_existing(&mut memdb, &mut root).build();
// we are testing the RefTrie code here so we do not sort or check uniqueness
// before.
assert_eq!(*t.root(), calc_root::<T, _, _, _>(data2));
Expand Down
17 changes: 12 additions & 5 deletions test-support/trie-bench/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,12 @@ fn benchmark<L: TrieLayout, S: TrieStream>(
bench_list,
|b, d: &TrieInsertionList| {
b.iter(&mut || {
let mut memdb = MemoryDB::<_, HashKey<L::Hash>, _>::new(L::Codec::empty_node());
let mut memdb = MemoryDB::new(L::Codec::empty_node());
let mut root = <TrieHash<L>>::default();
let mut t = TrieDBMutBuilder::<L>::new(&mut memdb, &mut root).build();
let mut t = TrieDBMutBuilder::<L, MemoryDB<_, HashKey<L::Hash>, _>>::new(
&mut memdb, &mut root,
)
.build();
for i in d.0.iter() {
t.insert(&i.0, &i.1).unwrap();
}
Expand All @@ -72,16 +75,20 @@ fn benchmark<L: TrieLayout, S: TrieStream>(
BenchmarkId::new("Iter", bench_size),
bench_list,
|b, d: &TrieInsertionList| {
let mut memdb = MemoryDB::<_, HashKey<_>, _>::new(L::Codec::empty_node());
let mut memdb = MemoryDB::new(L::Codec::empty_node());
let mut root = <TrieHash<L>>::default();
{
let mut t = TrieDBMutBuilder::<L>::new(&mut memdb, &mut root).build();
let mut t = TrieDBMutBuilder::<L, MemoryDB<_, HashKey<L::Hash>, _>>::new(
&mut memdb, &mut root,
)
.build();
for i in d.0.iter() {
t.insert(&i.0, &i.1).unwrap();
}
}
b.iter(&mut || {
let t = TrieDBBuilder::<L>::new(&memdb, &root).build();
let t = TrieDBBuilder::<L, MemoryDB<_, HashKey<L::Hash>, _>>::new(&memdb, &root)
.build();
for n in t.iter().unwrap() {
black_box(n).unwrap();
}
Expand Down
5 changes: 3 additions & 2 deletions test-support/trie-standardmap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,9 @@ impl StandardMap {
let v = match self.value_mode {
ValueMode::Mirror => k.clone(),
ValueMode::Random => Self::random_value(seed),
ValueMode::Index =>
vec![index as u8, (index >> 8) as u8, (index >> 16) as u8, (index >> 24) as u8],
ValueMode::Index => {
vec![index as u8, (index >> 8) as u8, (index >> 16) as u8, (index >> 24) as u8]
},
};
d.push((k, v))
}
Expand Down
53 changes: 32 additions & 21 deletions trie-db/src/fatdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,23 @@ use crate::{rstd::boxed::Box, MerkleValue, TrieDBBuilder};
/// Additionaly it stores inserted hash-key mappings for later retrieval.
///
/// Use it as a `Trie` or `TrieMut` trait object.
pub struct FatDB<'db, 'cache, L>
pub struct FatDB<'db, 'cache, L, DB>
where
L: TrieLayout,
DB: HashDBRef<L::Hash, DBValue>
{
raw: TrieDB<'db, 'cache, L>,
raw: TrieDB<'db, 'cache, L, DB>,
}

impl<'db, 'cache, L> FatDB<'db, 'cache, L>
impl<'db, 'cache, L, DB> FatDB<'db, 'cache, L, DB>
where
L: TrieLayout,
DB: HashDBRef<L::Hash, DBValue>,
{
/// Create a new trie with the backing database `db` and empty `root`
/// Initialise to the state entailed by the genesis block.
/// This guarantees the trie is built correctly.
pub fn new(db: &'db dyn HashDBRef<L::Hash, DBValue>, root: &'db TrieHash<L>) -> Self {
pub fn new(db: &'db DB, root: &'db TrieHash<L>) -> Self {
FatDB { raw: TrieDBBuilder::new(db, root).build() }
}

Expand All @@ -48,9 +50,10 @@ where
}
}

impl<'db, 'cache, L> Trie<L> for FatDB<'db, 'cache, L>
impl<'db, 'cache, L, DB> Trie<L> for FatDB<'db, 'cache, L, DB>
where
L: TrieLayout,
DB: HashDBRef<L::Hash, DBValue>,
{
fn root(&self) -> &TrieHash<L> {
self.raw.root()
Expand Down Expand Up @@ -86,7 +89,7 @@ where
TrieHash<L>,
CError<L>,
> {
FatDBIterator::<L>::new(&self.raw).map(|iter| Box::new(iter) as Box<_>)
FatDBIterator::<L, DB>::new(&self.raw).map(|iter| Box::new(iter) as Box<_>)
}

fn key_iter<'a>(
Expand All @@ -96,42 +99,46 @@ where
TrieHash<L>,
CError<L>,
> {
FatDBKeyIterator::<L>::new(&self.raw).map(|iter| Box::new(iter) as Box<_>)
FatDBKeyIterator::<L, DB>::new(&self.raw).map(|iter| Box::new(iter) as Box<_>)
}
}

/// Iterator over inserted pairs of key values.
pub struct FatDBIterator<'db, 'cache, L>
pub struct FatDBIterator<'db, 'cache, L, DB>
where
L: TrieLayout,
DB: HashDBRef<L::Hash, DBValue>,
{
trie_iterator: TrieDBIterator<'db, 'cache, L>,
trie: &'db TrieDB<'db, 'cache, L>,
trie_iterator: TrieDBIterator<'db, 'cache, L, DB>,
trie: &'db TrieDB<'db, 'cache, L, DB>,
}

impl<'db, 'cache, L> FatDBIterator<'db, 'cache, L>
impl<'db, 'cache, L, DB> FatDBIterator<'db, 'cache, L, DB>
where
L: TrieLayout,
DB: HashDBRef<L::Hash, DBValue>,
{
/// Creates new iterator.
pub fn new(trie: &'db TrieDB<'db, 'cache, L>) -> Result<Self, TrieHash<L>, CError<L>> {
pub fn new(trie: &'db TrieDB<'db, 'cache, L, DB>) -> Result<Self, TrieHash<L>, CError<L>> {
Ok(FatDBIterator { trie_iterator: TrieDBIterator::new(trie)?, trie })
}
}

impl<'db, 'cache, L> TrieIterator<L> for FatDBIterator<'db, 'cache, L>
impl<'db, 'cache, L, DB> TrieIterator<L> for FatDBIterator<'db, 'cache, L, DB>
where
L: TrieLayout,
DB: HashDBRef<L::Hash, DBValue>,
{
fn seek(&mut self, key: &[u8]) -> Result<(), TrieHash<L>, CError<L>> {
let hashed_key = L::Hash::hash(key);
self.trie_iterator.seek(hashed_key.as_ref())
}
}

impl<'db, 'cache, L> Iterator for FatDBIterator<'db, 'cache, L>
impl<'db, 'cache, L, DB> Iterator for FatDBIterator<'db, 'cache, L, DB>
where
L: TrieLayout,
DB: HashDBRef<L::Hash, DBValue>,
{
type Item = TrieItem<TrieHash<L>, CError<L>>;

Expand All @@ -149,37 +156,41 @@ where
}

/// Iterator over inserted keys.
pub struct FatDBKeyIterator<'db, 'cache, L>
pub struct FatDBKeyIterator<'db, 'cache, L, DB>
where
L: TrieLayout,
DB: HashDBRef<L::Hash, DBValue>,
{
trie_iterator: TrieDBKeyIterator<'db, 'cache, L>,
trie: &'db TrieDB<'db, 'cache, L>,
trie_iterator: TrieDBKeyIterator<'db, 'cache, L, DB>,
trie: &'db TrieDB<'db, 'cache, L, DB>,
}

impl<'db, 'cache, L> FatDBKeyIterator<'db, 'cache, L>
impl<'db, 'cache, L, DB> FatDBKeyIterator<'db, 'cache, L, DB>
where
L: TrieLayout,
DB: HashDBRef<L::Hash, DBValue>,
{
/// Creates new iterator.
pub fn new(trie: &'db TrieDB<'db, 'cache, L>) -> Result<Self, TrieHash<L>, CError<L>> {
pub fn new(trie: &'db TrieDB<'db, 'cache, L, DB>) -> Result<Self, TrieHash<L>, CError<L>> {
Ok(FatDBKeyIterator { trie_iterator: TrieDBKeyIterator::new(trie)?, trie })
}
}

impl<'db, 'cache, L> TrieIterator<L> for FatDBKeyIterator<'db, 'cache, L>
impl<'db, 'cache, L, DB> TrieIterator<L> for FatDBKeyIterator<'db, 'cache, L, DB>
where
L: TrieLayout,
DB: HashDBRef<L::Hash, DBValue>,
{
fn seek(&mut self, key: &[u8]) -> Result<(), TrieHash<L>, CError<L>> {
let hashed_key = L::Hash::hash(key);
self.trie_iterator.seek(hashed_key.as_ref())
}
}

impl<'db, 'cache, L> Iterator for FatDBKeyIterator<'db, 'cache, L>
impl<'db, 'cache, L, DB> Iterator for FatDBKeyIterator<'db, 'cache, L, DB>
where
L: TrieLayout,
DB: HashDBRef<L::Hash, DBValue>,
{
type Item = TrieKeyItem<TrieHash<L>, CError<L>>;

Expand Down
Loading