From 95892aa98baf86a9163479ac11ed8d4a3b1549a8 Mon Sep 17 00:00:00 2001 From: Emeric Chevalier Date: Fri, 31 Jan 2020 15:07:07 +0100 Subject: [PATCH 1/2] ConstMemoryDB. --- hash-db/src/lib.rs | 15 + memory-db/src/lib.rs | 482 ++++++++++++++++++-------- test-support/keccak-hasher/src/lib.rs | 16 + 3 files changed, 378 insertions(+), 135 deletions(-) diff --git a/hash-db/src/lib.rs b/hash-db/src/lib.rs index 249ae4eb..2869a142 100644 --- a/hash-db/src/lib.rs +++ b/hash-db/src/lib.rs @@ -64,6 +64,21 @@ pub trait Hasher: Sync + Send { fn hash(x: &[u8]) -> Self::Out; } +/// Technical trait to avoid calculating empty root. +/// This trait assumes, an empty node is `[0u8]`. +pub trait HasherNullEmptyRoot: Hasher { + /// Associated constant value. + const EMPTY_ROOT: &'static [u8]; + + +} + +/// Test to call for all new `HasherNullEmptyRoot` implementation. +pub fn test_associated_empty_root() -> bool { + let empty = ::hash(&[0u8]); + H::EMPTY_ROOT == empty.as_ref() +} + /// Trait modelling a plain datastore whose key is a fixed type. /// The caller should ensure that a key only corresponds to /// one value. diff --git a/memory-db/src/lib.rs b/memory-db/src/lib.rs index 67e67246..0b92b7dc 100644 --- a/memory-db/src/lib.rs +++ b/memory-db/src/lib.rs @@ -20,7 +20,7 @@ extern crate alloc; use hash_db::{HashDB, HashDBRef, PlainDB, PlainDBRef, Hasher as KeyHasher, - AsHashDB, AsPlainDB, Prefix}; + AsHashDB, AsPlainDB, Prefix, HasherNullEmptyRoot as ConstKeyHasher}; use parity_util_mem::{MallocSizeOf, MallocSizeOfOps}; #[cfg(feature = "deprecated")] #[cfg(feature = "std")] @@ -118,6 +118,18 @@ pub struct MemoryDB _kf: PhantomData, } +/// Same as memory db byt with a `HasherNullEmptyRoot` +/// constraint that assumes empty root is `[0]` and +/// do not store and calculate this empty root value. +pub struct ConstNullMemoryDB + where + H: ConstKeyHasher, + KF: KeyFunction, +{ + data: HashMap, + _kf: PhantomData, +} + impl, T: Clone> Clone for MemoryDB { fn clone(&self) -> Self { Self { @@ -129,33 +141,15 @@ impl, T: Clone> Clone for MemoryDB { } } -impl PartialEq> for MemoryDB - where - H: KeyHasher, - KF: KeyFunction, - >::Key: Eq + MaybeDebug, - T: Eq + MaybeDebug, -{ - fn eq(&self, other: &MemoryDB) -> bool { - for a in self.data.iter() { - match other.data.get(&a.0) { - Some(v) if v != a.1 => return false, - None => return false, - _ => (), - } +impl, T: Clone> Clone for ConstNullMemoryDB { + fn clone(&self) -> Self { + Self { + data: self.data.clone(), + _kf: Default::default(), } - true } } -impl Eq for MemoryDB - where - H: KeyHasher, - KF: KeyFunction, - >::Key: Eq + MaybeDebug, - T: Eq + MaybeDebug, -{} - pub trait KeyFunction { type Key: Send + Sync + Clone + hash::Hash + Eq; @@ -269,32 +263,16 @@ where } } -/// Create a new `MemoryDB` from a given null key/data -impl MemoryDB +impl<'a, H, KF, T> Default for ConstNullMemoryDB where - H: KeyHasher, - T: Default, + H: ConstKeyHasher, + T: From<&'a [u8]>, KF: KeyFunction, { - /// Remove an element and delete it from storage if reference count reaches zero. - /// If the value was purged, return the old value. - pub fn remove_and_purge(&mut self, key: &::Out, prefix: Prefix) -> Option { - if key == &self.hashed_null_node { - return None; - } - let key = KF::key(key, prefix); - match self.data.entry(key) { - Entry::Occupied(mut entry) => - if entry.get().1 == 1 { - Some(entry.remove().0) - } else { - entry.get_mut().1 -= 1; - None - }, - Entry::Vacant(entry) => { - entry.insert((T::default(), -1)); // FIXME: shouldn't it be purged? - None - } + fn default() -> Self { + ConstNullMemoryDB { + data: Default::default(), + _kf: PhantomData, } } } @@ -328,6 +306,92 @@ where (db, root) } + /// Grab the raw information associated with a key. Returns None if the key + /// doesn't exist. + /// + /// Even when Some is returned, the data is only guaranteed to be useful + /// when the refs > 0. + pub fn raw(&self, key: &::Out, prefix: Prefix) -> Option<(&T, i32)> { + if key == &self.hashed_null_node { + return Some((&self.null_node_data, 1)); + } + self.data.get(&KF::key(key, prefix)).map(|(value, count)| (value, *count)) + } +} + +macro_rules! impl_mem_db {( + $db_type: tt, + $hash_constraint: tt, + $cmp_def: expr, + $null_node: expr, + $cmp_node: expr, + $cmp_node2: expr, + $ret_hash: expr +) => { + +impl PartialEq<$db_type> for $db_type + where + H: $hash_constraint, + KF: KeyFunction, + >::Key: Eq + MaybeDebug, + T: Eq + MaybeDebug, +{ + fn eq(&self, other: &$db_type) -> bool { + for a in self.data.iter() { + match other.data.get(&a.0) { + Some(v) if v != a.1 => return false, + None => return false, + _ => (), + } + } + true + } +} + +impl Eq for $db_type + where + H: $hash_constraint, + KF: KeyFunction, + >::Key: Eq + MaybeDebug, + T: Eq + MaybeDebug, +{} + +/// Create a new `MemoryDB` from a given null key/data +impl $db_type +where + H: $hash_constraint, + T: Default, + KF: KeyFunction, +{ + /// Remove an element and delete it from storage if reference count reaches zero. + /// If the value was purged, return the old value. + pub fn remove_and_purge(&mut self, key: &::Out, prefix: Prefix) -> Option { + if $cmp_def(self, key) { + return None; + } + let key = KF::key(key, prefix); + match self.data.entry(key) { + Entry::Occupied(mut entry) => + if entry.get().1 == 1 { + Some(entry.remove().0) + } else { + entry.get_mut().1 -= 1; + None + }, + Entry::Vacant(entry) => { + entry.insert((T::default(), -1)); // FIXME: shouldn't it be purged? + None + } + } + } +} + +impl<'a, H: $hash_constraint, KF, T> $db_type +where + H: $hash_constraint, + T: From<&'a [u8]>, + KF: KeyFunction, +{ /// Clear all data from the database. /// /// # Examples @@ -363,18 +427,6 @@ where mem::replace(&mut self.data, Default::default()) } - /// Grab the raw information associated with a key. Returns None if the key - /// doesn't exist. - /// - /// Even when Some is returned, the data is only guaranteed to be useful - /// when the refs > 0. - pub fn raw(&self, key: &::Out, prefix: Prefix) -> Option<(&T, i32)> { - if key == &self.hashed_null_node { - return Some((&self.null_node_data, 1)); - } - self.data.get(&KF::key(key, prefix)).map(|(value, count)| (value, *count)) - } - /// Consolidate all the entries of `other` into `self`. pub fn consolidate(&mut self, mut other: Self) { for (key, (value, rc)) in other.drain() { @@ -405,66 +457,9 @@ where } } -#[cfg(feature = "deprecated")] -#[cfg(feature = "std")] -impl MemoryDB -where - H: KeyHasher, - T: HeapSizeOf, - KF: KeyFunction, -{ - #[deprecated(since="0.12.0", note="please use `size_of` instead")] - /// Returns the size of allocated heap memory - pub fn mem_used(&self) -> usize { - 0//self.data.heap_size_of_children() - // TODO Reenable above when HeapSizeOf supports arrays. - } -} - -// `no_std` implementation requires that hasmap -// is implementated in parity-util-mem, that -// is currently not the case. -#[cfg(feature = "std")] -impl MallocSizeOf for MemoryDB -where - H: KeyHasher, - H::Out: MallocSizeOf, - T: MallocSizeOf, - KF: KeyFunction, - KF::Key: MallocSizeOf, -{ - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.data.size_of(ops) - + self.null_node_data.size_of(ops) - + self.hashed_null_node.size_of(ops) - } -} - -// This is temporary code, we should use -// `parity-util-mem`, see -// https://github.com/paritytech/trie/issues/21 -#[cfg(not(feature = "std"))] -impl MallocSizeOf for MemoryDB -where - H: KeyHasher, - H::Out: MallocSizeOf, - T: MallocSizeOf, - KF: KeyFunction, - KF::Key: MallocSizeOf, -{ - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - use core::mem::size_of; - let mut n = self.data.capacity() * (size_of::() + size_of::() + size_of::()); - for (k, v) in self.data.iter() { - n += k.size_of(ops) + v.size_of(ops); - } - n + self.null_node_data.size_of(ops) + self.hashed_null_node.size_of(ops) - } -} - -impl PlainDB for MemoryDB +impl PlainDB for $db_type where - H: KeyHasher, + H: $hash_constraint, T: Default + PartialEq + for<'a> From<&'a [u8]> + Clone + Send + Sync, KF: Send + Sync + KeyFunction, KF::Key: Borrow<[u8]> + for <'a> From<&'a [u8]>, @@ -511,9 +506,9 @@ where } } -impl PlainDBRef for MemoryDB +impl PlainDBRef for $db_type where - H: KeyHasher, + H: $hash_constraint, T: Default + PartialEq + for<'a> From<&'a [u8]> + Clone + Send + Sync, KF: Send + Sync + KeyFunction, KF::Key: Borrow<[u8]> + for <'a> From<&'a [u8]>, @@ -522,15 +517,15 @@ where fn contains(&self, key: &H::Out) -> bool { PlainDB::contains(self, key) } } -impl HashDB for MemoryDB +impl HashDB for $db_type where - H: KeyHasher, + H: $hash_constraint, T: Default + PartialEq + for<'a> From<&'a [u8]> + Clone + Send + Sync, KF: Send + Sync + KeyFunction, { fn get(&self, key: &H::Out, prefix: Prefix) -> Option { - if key == &self.hashed_null_node { - return Some(self.null_node_data.clone()); + if $cmp_def(self, key) { + return Some($null_node(self)); } let key = KF::key(key, prefix); @@ -541,7 +536,7 @@ where } fn contains(&self, key: &H::Out, prefix: Prefix) -> bool { - if key == &self.hashed_null_node { + if $cmp_def(self, key) { return true; } @@ -553,7 +548,7 @@ where } fn emplace(&mut self, key: H::Out, prefix: Prefix, value: T) { - if value == self.null_node_data { + if $cmp_node2(self, &value) { return; } @@ -573,8 +568,8 @@ where } fn insert(&mut self, prefix: Prefix, value: &[u8]) -> H::Out { - if T::from(value) == self.null_node_data { - return self.hashed_null_node.clone(); + if $cmp_node(self, value) { + return $ret_hash(self); } let key = H::hash(value); @@ -583,7 +578,7 @@ where } fn remove(&mut self, key: &H::Out, prefix: Prefix) { - if key == &self.hashed_null_node { + if $cmp_def(self, key) { return; } @@ -600,9 +595,9 @@ where } } -impl HashDBRef for MemoryDB +impl HashDBRef for $db_type where - H: KeyHasher, + H: $hash_constraint, T: Default + PartialEq + for<'a> From<&'a [u8]> + Clone + Send + Sync, KF: Send + Sync + KeyFunction, { @@ -610,9 +605,9 @@ where fn contains(&self, key: &H::Out, prefix: Prefix) -> bool { HashDB::contains(self, key, prefix) } } -impl AsPlainDB for MemoryDB +impl AsPlainDB for $db_type where - H: KeyHasher, + H: $hash_constraint, T: Default + PartialEq + for<'a> From<&'a[u8]> + Clone + Send + Sync, KF: Send + Sync + KeyFunction, KF::Key: Borrow<[u8]> + for <'a> From<&'a [u8]>, @@ -621,9 +616,9 @@ where fn as_plain_db_mut(&mut self) -> &mut dyn PlainDB { self } } -impl AsHashDB for MemoryDB +impl AsHashDB for $db_type where - H: KeyHasher, + H: $hash_constraint, T: Default + PartialEq + for<'a> From<&'a[u8]> + Clone + Send + Sync, KF: Send + Sync + KeyFunction, { @@ -631,9 +626,218 @@ where fn as_hash_db_mut(&mut self) -> &mut dyn HashDB { self } } + + }; +} + +fn cmp_hashed_null_node<'a, H, KF, T>(db: &MemoryDB, key: &H::Out) -> bool +where + H: KeyHasher, + KF: KeyFunction, +{ + key == &db.hashed_null_node +} + +fn const_cmp_hashed_null_node<'a, H, KF, T>(_: &ConstNullMemoryDB, key: &H::Out) -> bool +where + H: ConstKeyHasher, + KF: KeyFunction, +{ + key.as_ref() == H::EMPTY_ROOT +} + +fn cmp_null_node_ref<'a, H, KF, T>(db: &MemoryDB, value: &'a [u8]) -> bool +where + H: KeyHasher, + T: From<&'a [u8]> + PartialEq, + KF: KeyFunction, +{ + T::from(value) == db.null_node_data +} + +fn const_cmp_null_node_ref<'a, H, KF, T>(_: &ConstNullMemoryDB, value: &'a [u8]) -> bool +where + H: ConstKeyHasher, + T: From<&'a [u8]> + PartialEq, + KF: KeyFunction, +{ + T::from(value) == T::from(&[0u8]) +} + +fn cmp_null_node<'a, H, KF, T>(db: &MemoryDB, value: &T) -> bool +where + H: KeyHasher, + T: From<&'a [u8]> + PartialEq, + KF: KeyFunction, +{ + *value == db.null_node_data +} + +fn const_cmp_null_node<'a, H, KF, T>(_: &ConstNullMemoryDB, value: &T) -> bool +where + H: ConstKeyHasher, + T: From<&'a [u8]> + PartialEq, + KF: KeyFunction, +{ + value == &T::from(&[0u8]) +} + +fn null_node<'a, H, KF, T>(db: &MemoryDB) -> T +where + H: KeyHasher, + T: Clone, + KF: KeyFunction, +{ + db.null_node_data.clone() +} + +fn const_null_node<'a, H, KF, T>(_: &ConstNullMemoryDB) -> T +where + H: ConstKeyHasher, + T: From<&'a [u8]> + PartialEq, + KF: KeyFunction, +{ + T::from(&[0u8]) +} + +fn ret_hashed_null_node<'a, H, KF, T>(db: &MemoryDB) -> H::Out +where + H: KeyHasher, + T: From<&'a [u8]>, + KF: KeyFunction, +{ + db.hashed_null_node.clone() +} + +fn const_ret_hashed_null_node<'a, H, KF, T>(_: &ConstNullMemoryDB) -> H::Out +where + H: ConstKeyHasher, + T: From<&'a [u8]>, + KF: KeyFunction, +{ + let mut result: H::Out = Default::default(); + result.as_mut().copy_from_slice(H::EMPTY_ROOT); + result +} + +impl_mem_db!( + MemoryDB, + KeyHasher, + cmp_hashed_null_node, + null_node, + cmp_null_node_ref, + cmp_null_node, + ret_hashed_null_node +); + +impl_mem_db!( + ConstNullMemoryDB, + ConstKeyHasher, + const_cmp_hashed_null_node, + const_null_node, + const_cmp_null_node_ref, + const_cmp_null_node, + const_ret_hashed_null_node +); + + +#[cfg(feature = "deprecated")] +#[cfg(feature = "std")] +impl MemoryDB +where + H: KeyHasher, + T: HeapSizeOf, + KF: KeyFunction, +{ + #[deprecated(since="0.12.0", note="please use `size_of` instead")] + /// Returns the size of allocated heap memory + pub fn mem_used(&self) -> usize { + 0//self.data.heap_size_of_children() + // TODO Reenable above when HeapSizeOf supports arrays. + } +} + +// `no_std` implementation requires that hashmap +// is implementated in parity-util-mem, that +// is currently not the case. +#[cfg(feature = "std")] +impl MallocSizeOf for MemoryDB +where + H: KeyHasher, + H::Out: MallocSizeOf, + T: MallocSizeOf, + KF: KeyFunction, + KF::Key: MallocSizeOf, +{ + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + self.data.size_of(ops) + + self.null_node_data.size_of(ops) + + self.hashed_null_node.size_of(ops) + } +} + +// This is temporary code, we should use +// `parity-util-mem`, see +// https://github.com/paritytech/trie/issues/21 +#[cfg(not(feature = "std"))] +impl MallocSizeOf for MemoryDB +where + H: KeyHasher, + H::Out: MallocSizeOf, + T: MallocSizeOf, + KF: KeyFunction, + KF::Key: MallocSizeOf, +{ + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + use core::mem::size_of; + let mut n = self.data.capacity() * (size_of::() + size_of::() + size_of::()); + for (k, v) in self.data.iter() { + n += k.size_of(ops) + v.size_of(ops); + } + n + self.null_node_data.size_of(ops) + self.hashed_null_node.size_of(ops) + } +} + +#[cfg(feature = "std")] +impl MallocSizeOf for ConstNullMemoryDB +where + H: ConstKeyHasher, + H::Out: MallocSizeOf, + T: MallocSizeOf, + KF: KeyFunction, + KF::Key: MallocSizeOf, +{ + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + self.data.size_of(ops) + } +} + +// This is temporary code, we should use +// `parity-util-mem`, see +// https://github.com/paritytech/trie/issues/21 +#[cfg(not(feature = "std"))] +impl MallocSizeOf for ConstNullMemoryDB +where + H: ConstKeyHasher, + H::Out: MallocSizeOf, + T: MallocSizeOf, + KF: KeyFunction, + KF::Key: MallocSizeOf, +{ + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + use core::mem::size_of; + let mut n = self.data.capacity() * (size_of::() + size_of::() + size_of::()); + for (k, v) in self.data.iter() { + n += k.size_of(ops) + v.size_of(ops); + } + n + } +} + #[cfg(test)] mod tests { use super::{MemoryDB, HashDB, KeyHasher, HashKey}; + use super::{ConstNullMemoryDB}; use hash_db::EMPTY_PREFIX; use keccak_hasher::KeccakHasher; @@ -698,4 +902,12 @@ mod tests { assert!(db2.contains(&root, EMPTY_PREFIX)); assert!(db.contains(&root, EMPTY_PREFIX)); } + + #[test] + fn const_default_works() { + let mut db = ConstNullMemoryDB::, Vec>::default(); + let hashed_null_node = KeccakHasher::hash(&[0u8][..]); + assert!(db.contains(&hashed_null_node, EMPTY_PREFIX)); + assert_eq!(db.insert(EMPTY_PREFIX, &[0u8][..]), hashed_null_node); + } } diff --git a/test-support/keccak-hasher/src/lib.rs b/test-support/keccak-hasher/src/lib.rs index ed64612a..239e6ef3 100644 --- a/test-support/keccak-hasher/src/lib.rs +++ b/test-support/keccak-hasher/src/lib.rs @@ -15,6 +15,7 @@ //! Hasher implementation for the Keccak-256 hash use hash_db::Hasher; +use hash_db::HasherNullEmptyRoot; use tiny_keccak::Keccak; use hash256_std_hasher::Hash256StdHasher; @@ -35,11 +36,26 @@ impl Hasher for KeccakHasher { } } +impl HasherNullEmptyRoot for KeccakHasher { + const EMPTY_ROOT: &'static [u8] = &[ + 188, 54, 120, 158, 122, 30, 40, 20, 54, 70, + 66, 41, 130, 143, 129, 125, 102, 18, 247, 180, + 119, 214, 101, 145, 255, 150, 169, 224, 100, 188, + 201, 138, + ]; +} + #[cfg(test)] mod tests { use super::*; use std::collections::HashMap; + #[test] + fn empty_root_const() { + use hash_db::test_associated_empty_root; + assert!(test_associated_empty_root::()); + } + #[test] fn hash256_std_hasher_works() { let hello_bytes = b"Hello world!"; From dc86ddf8a3abbed2761c33aae1a899bc418cc2a0 Mon Sep 17 00:00:00 2001 From: cheme Date: Thu, 6 Feb 2020 14:22:29 +0100 Subject: [PATCH 2/2] removing unused constraints. --- hash-db/src/lib.rs | 4 +- memory-db/src/lib.rs | 195 +++++++++++++++++++++---------------------- 2 files changed, 98 insertions(+), 101 deletions(-) diff --git a/hash-db/src/lib.rs b/hash-db/src/lib.rs index 2869a142..37a2e14a 100644 --- a/hash-db/src/lib.rs +++ b/hash-db/src/lib.rs @@ -69,12 +69,10 @@ pub trait Hasher: Sync + Send { pub trait HasherNullEmptyRoot: Hasher { /// Associated constant value. const EMPTY_ROOT: &'static [u8]; - - } /// Test to call for all new `HasherNullEmptyRoot` implementation. -pub fn test_associated_empty_root() -> bool { +pub fn test_associated_empty_root() -> bool { let empty = ::hash(&[0u8]); H::EMPTY_ROOT == empty.as_ref() } diff --git a/memory-db/src/lib.rs b/memory-db/src/lib.rs index 0b92b7dc..c9d2df01 100644 --- a/memory-db/src/lib.rs +++ b/memory-db/src/lib.rs @@ -319,6 +319,101 @@ where } } +#[cfg(feature = "deprecated")] +#[cfg(feature = "std")] +impl MemoryDB +where + H: KeyHasher, + T: HeapSizeOf, + KF: KeyFunction, +{ + #[deprecated(since="0.12.0", note="please use `size_of` instead")] + /// Returns the size of allocated heap memory + pub fn mem_used(&self) -> usize { + 0//self.data.heap_size_of_children() + // TODO Reenable above when HeapSizeOf supports arrays. + } +} + +// `no_std` implementation requires that hashmap +// is implementated in parity-util-mem, that +// is currently not the case. +#[cfg(feature = "std")] +impl MallocSizeOf for MemoryDB +where + H: KeyHasher, + H::Out: MallocSizeOf, + T: MallocSizeOf, + KF: KeyFunction, + KF::Key: MallocSizeOf, +{ + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + self.data.size_of(ops) + + self.null_node_data.size_of(ops) + + self.hashed_null_node.size_of(ops) + } +} + +// This is temporary code, we should use +// `parity-util-mem`, see +// https://github.com/paritytech/trie/issues/21 +#[cfg(not(feature = "std"))] +impl MallocSizeOf for MemoryDB +where + H: KeyHasher, + H::Out: MallocSizeOf, + T: MallocSizeOf, + KF: KeyFunction, + KF::Key: MallocSizeOf, +{ + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + use core::mem::size_of; + let mut n = self.data.capacity() * (size_of::() + size_of::() + size_of::()); + for (k, v) in self.data.iter() { + n += k.size_of(ops) + v.size_of(ops); + } + n + self.null_node_data.size_of(ops) + self.hashed_null_node.size_of(ops) + } +} + +#[cfg(feature = "std")] +impl MallocSizeOf for ConstNullMemoryDB +where + H: ConstKeyHasher, + H::Out: MallocSizeOf, + T: MallocSizeOf, + KF: KeyFunction, + KF::Key: MallocSizeOf, +{ + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + self.data.size_of(ops) + } +} + +// This is temporary code, we should use +// `parity-util-mem`, see +// https://github.com/paritytech/trie/issues/21 +#[cfg(not(feature = "std"))] +impl MallocSizeOf for ConstNullMemoryDB +where + H: ConstKeyHasher, + H::Out: MallocSizeOf, + T: MallocSizeOf, + KF: KeyFunction, + KF::Key: MallocSizeOf, +{ + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + use core::mem::size_of; + let mut n = self.data.capacity() * (size_of::() + size_of::() + size_of::()); + for (k, v) in self.data.iter() { + n += k.size_of(ops) + v.size_of(ops); + } + n + } +} + + + macro_rules! impl_mem_db {( $db_type: tt, $hash_constraint: tt, @@ -667,7 +762,7 @@ where fn cmp_null_node<'a, H, KF, T>(db: &MemoryDB, value: &T) -> bool where H: KeyHasher, - T: From<&'a [u8]> + PartialEq, + T: PartialEq, KF: KeyFunction, { *value == db.null_node_data @@ -694,7 +789,7 @@ where fn const_null_node<'a, H, KF, T>(_: &ConstNullMemoryDB) -> T where H: ConstKeyHasher, - T: From<&'a [u8]> + PartialEq, + T: From<&'a [u8]>, KF: KeyFunction, { T::from(&[0u8]) @@ -703,7 +798,6 @@ where fn ret_hashed_null_node<'a, H, KF, T>(db: &MemoryDB) -> H::Out where H: KeyHasher, - T: From<&'a [u8]>, KF: KeyFunction, { db.hashed_null_node.clone() @@ -712,7 +806,6 @@ where fn const_ret_hashed_null_node<'a, H, KF, T>(_: &ConstNullMemoryDB) -> H::Out where H: ConstKeyHasher, - T: From<&'a [u8]>, KF: KeyFunction, { let mut result: H::Out = Default::default(); @@ -740,100 +833,6 @@ impl_mem_db!( const_ret_hashed_null_node ); - -#[cfg(feature = "deprecated")] -#[cfg(feature = "std")] -impl MemoryDB -where - H: KeyHasher, - T: HeapSizeOf, - KF: KeyFunction, -{ - #[deprecated(since="0.12.0", note="please use `size_of` instead")] - /// Returns the size of allocated heap memory - pub fn mem_used(&self) -> usize { - 0//self.data.heap_size_of_children() - // TODO Reenable above when HeapSizeOf supports arrays. - } -} - -// `no_std` implementation requires that hashmap -// is implementated in parity-util-mem, that -// is currently not the case. -#[cfg(feature = "std")] -impl MallocSizeOf for MemoryDB -where - H: KeyHasher, - H::Out: MallocSizeOf, - T: MallocSizeOf, - KF: KeyFunction, - KF::Key: MallocSizeOf, -{ - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.data.size_of(ops) - + self.null_node_data.size_of(ops) - + self.hashed_null_node.size_of(ops) - } -} - -// This is temporary code, we should use -// `parity-util-mem`, see -// https://github.com/paritytech/trie/issues/21 -#[cfg(not(feature = "std"))] -impl MallocSizeOf for MemoryDB -where - H: KeyHasher, - H::Out: MallocSizeOf, - T: MallocSizeOf, - KF: KeyFunction, - KF::Key: MallocSizeOf, -{ - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - use core::mem::size_of; - let mut n = self.data.capacity() * (size_of::() + size_of::() + size_of::()); - for (k, v) in self.data.iter() { - n += k.size_of(ops) + v.size_of(ops); - } - n + self.null_node_data.size_of(ops) + self.hashed_null_node.size_of(ops) - } -} - -#[cfg(feature = "std")] -impl MallocSizeOf for ConstNullMemoryDB -where - H: ConstKeyHasher, - H::Out: MallocSizeOf, - T: MallocSizeOf, - KF: KeyFunction, - KF::Key: MallocSizeOf, -{ - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.data.size_of(ops) - } -} - -// This is temporary code, we should use -// `parity-util-mem`, see -// https://github.com/paritytech/trie/issues/21 -#[cfg(not(feature = "std"))] -impl MallocSizeOf for ConstNullMemoryDB -where - H: ConstKeyHasher, - H::Out: MallocSizeOf, - T: MallocSizeOf, - KF: KeyFunction, - KF::Key: MallocSizeOf, -{ - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - use core::mem::size_of; - let mut n = self.data.capacity() * (size_of::() + size_of::() + size_of::()); - for (k, v) in self.data.iter() { - n += k.size_of(ops) + v.size_of(ops); - } - n - } -} - #[cfg(test)] mod tests { use super::{MemoryDB, HashDB, KeyHasher, HashKey};