1use tetsy_hash_db::{HashDBRef, Hasher};
16use super::{Result, DBValue, TrieDB, Trie, TrieDBIterator, TrieItem, TrieIterator, Query,
17 TrieLayout, CError, TrieHash};
18
19use crate::rstd::boxed::Box;
20
21pub struct FatDB<'db, L>
26where
27 L: TrieLayout,
28{
29 raw: TrieDB<'db, L>,
30}
31
32impl<'db, L> FatDB<'db, L>
33where
34 L: TrieLayout,
35{
36 pub fn new(
40 db: &'db dyn HashDBRef<L::Hash, DBValue>,
41 root: &'db TrieHash<L>,
42 ) -> Result<Self, TrieHash<L>, CError<L>> {
43 Ok(FatDB { raw: TrieDB::new(db, root)? })
44 }
45
46 pub fn db(&self) -> &dyn HashDBRef<L::Hash, DBValue> { self.raw.db() }
48}
49
50impl<'db, L> Trie<L> for FatDB<'db, L>
51where
52 L: TrieLayout,
53{
54 fn root(&self) -> &TrieHash<L> { self.raw.root() }
55
56 fn contains(&self, key: &[u8]) -> Result<bool, TrieHash<L>, CError<L>> {
57 self.raw.contains(L::Hash::hash(key).as_ref())
58 }
59
60 fn get_with<'a, 'key, Q: Query<L::Hash>>(&'a self, key: &'key [u8], query: Q)
61 -> Result<Option<Q::Item>, TrieHash<L>, CError<L>>
62 where 'a: 'key
63 {
64 self.raw.get_with(L::Hash::hash(key).as_ref(), query)
65 }
66
67 fn iter<'a>(&'a self) -> Result<
68 Box<dyn TrieIterator<L, Item = TrieItem<TrieHash<L>, CError<L>>> + 'a>,
69 TrieHash<L>,
70 CError<L>,
71 > {
72 FatDBIterator::<L>::new(&self.raw).map(|iter| Box::new(iter) as Box<_>)
73 }
74}
75
76pub struct FatDBIterator<'db, L>
78where
79 L: TrieLayout,
80{
81 trie_iterator: TrieDBIterator<'db, L>,
82 trie: &'db TrieDB<'db, L>,
83}
84
85impl<'db, L> FatDBIterator<'db, L>
86where
87 L: TrieLayout,
88{
89 pub fn new(trie: &'db TrieDB<L>) -> Result<Self, TrieHash<L>, CError<L>> {
91 Ok(FatDBIterator {
92 trie_iterator: TrieDBIterator::new(trie)?,
93 trie,
94 })
95 }
96}
97
98impl<'db, L> TrieIterator<L> for FatDBIterator<'db, L>
99where
100 L: TrieLayout,
101{
102 fn seek(&mut self, key: &[u8]) -> Result<(), TrieHash<L>, CError<L>> {
103 let hashed_key = L::Hash::hash(key);
104 self.trie_iterator.seek(hashed_key.as_ref())
105 }
106}
107
108impl<'db, L> Iterator for FatDBIterator<'db, L>
109where
110 L: TrieLayout,
111{
112 type Item = TrieItem<'db, TrieHash<L>, CError<L>>;
113
114 fn next(&mut self) -> Option<Self::Item> {
115 self.trie_iterator.next()
116 .map(|res| {
117 res.map(|(hash, value)| {
118 let aux_hash = L::Hash::hash(&hash);
119 (
120 self.trie.db().get(&aux_hash, Default::default())
121 .expect("Missing fatdb hash"),
122 value,
123 )
124 })
125 })
126 }
127}