1use super::{
16 CError, DBValue, Query, Result, Trie, TrieDB, TrieDBIterator, TrieDBKeyIterator, TrieHash,
17 TrieItem, TrieIterator, TrieKeyItem, TrieLayout,
18};
19use hash_db::{HashDBRef, Hasher};
20
21use crate::{rstd::boxed::Box, triedb::TrieDBDoubleEndedIterator, MerkleValue, TrieDBBuilder};
22
23pub struct FatDB<'db, 'cache, L>
28where
29 L: TrieLayout,
30{
31 raw: TrieDB<'db, 'cache, L>,
32}
33
34impl<'db, 'cache, L> FatDB<'db, 'cache, L>
35where
36 L: TrieLayout,
37{
38 pub fn new(db: &'db dyn HashDBRef<L::Hash, DBValue>, root: &'db TrieHash<L>) -> Self {
42 FatDB { raw: TrieDBBuilder::new(db, root).build() }
43 }
44
45 pub fn db(&self) -> &dyn HashDBRef<L::Hash, DBValue> {
47 self.raw.db()
48 }
49}
50
51impl<'db, 'cache, L> Trie<L> for FatDB<'db, 'cache, L>
52where
53 L: TrieLayout,
54{
55 fn root(&self) -> &TrieHash<L> {
56 self.raw.root()
57 }
58
59 fn contains(&self, key: &[u8]) -> Result<bool, TrieHash<L>, CError<L>> {
60 self.raw.contains(L::Hash::hash(key).as_ref())
61 }
62
63 fn get_hash(&self, key: &[u8]) -> Result<Option<TrieHash<L>>, TrieHash<L>, CError<L>> {
64 self.raw.get_hash(key)
65 }
66
67 fn get_with<Q: Query<L::Hash>>(
68 &self,
69 key: &[u8],
70 query: Q,
71 ) -> Result<Option<Q::Item>, TrieHash<L>, CError<L>> {
72 self.raw.get_with(L::Hash::hash(key).as_ref(), query)
73 }
74
75 fn lookup_first_descendant(
76 &self,
77 key: &[u8],
78 ) -> Result<Option<MerkleValue<TrieHash<L>>>, TrieHash<L>, CError<L>> {
79 self.raw.lookup_first_descendant(key)
80 }
81
82 fn iter<'a>(
83 &'a self,
84 ) -> Result<
85 Box<dyn TrieIterator<L, Item = TrieItem<TrieHash<L>, CError<L>>> + 'a>,
86 TrieHash<L>,
87 CError<L>,
88 > {
89 FatDBIterator::<L>::new(&self.raw).map(|iter| Box::new(iter) as Box<_>)
90 }
91
92 fn key_iter<'a>(
93 &'a self,
94 ) -> Result<
95 Box<dyn TrieIterator<L, Item = TrieKeyItem<TrieHash<L>, CError<L>>> + 'a>,
96 TrieHash<L>,
97 CError<L>,
98 > {
99 FatDBKeyIterator::<L>::new(&self.raw).map(|iter| Box::new(iter) as Box<_>)
100 }
101}
102
103pub struct FatDBIterator<'db, 'cache, L>
105where
106 L: TrieLayout,
107{
108 trie_iterator: TrieDBIterator<'db, 'cache, L>,
109 trie: &'db TrieDB<'db, 'cache, L>,
110}
111
112pub struct FatDBDoubleEndedIterator<'db, 'cache, L>
114where
115 L: TrieLayout,
116{
117 trie_iterator: TrieDBDoubleEndedIterator<'db, 'cache, L>,
118 trie: &'db TrieDB<'db, 'cache, L>,
119}
120
121impl<'a, 'cache, L: TrieLayout> FatDBDoubleEndedIterator<'a, 'cache, L> {
122 pub fn new(db: &'a TrieDB<'a, 'cache, L>) -> Result<Self, TrieHash<L>, CError<L>> {
124 Ok(Self { trie_iterator: TrieDBDoubleEndedIterator::new(db)?, trie: db })
125 }
126}
127
128impl<'db, 'cache, L> FatDBIterator<'db, 'cache, L>
129where
130 L: TrieLayout,
131{
132 pub fn new(trie: &'db TrieDB<'db, 'cache, L>) -> Result<Self, TrieHash<L>, CError<L>> {
134 Ok(FatDBIterator { trie_iterator: TrieDBIterator::new(trie)?, trie })
135 }
136}
137
138impl<'db, 'cache, L> TrieIterator<L> for FatDBIterator<'db, 'cache, L>
139where
140 L: TrieLayout,
141{
142 fn seek(&mut self, key: &[u8]) -> Result<(), TrieHash<L>, CError<L>> {
143 let hashed_key = L::Hash::hash(key);
144 self.trie_iterator.seek(hashed_key.as_ref())
145 }
146}
147
148impl<'db, 'cache, L> Iterator for FatDBIterator<'db, 'cache, L>
149where
150 L: TrieLayout,
151{
152 type Item = TrieItem<TrieHash<L>, CError<L>>;
153
154 fn next(&mut self) -> Option<Self::Item> {
155 self.trie_iterator.next().map(|res| {
156 res.map(|(hash, value)| {
157 let aux_hash = L::Hash::hash(&hash);
158 (
159 self.trie.db().get(&aux_hash, Default::default()).expect("Missing fatdb hash"),
160 value,
161 )
162 })
163 })
164 }
165}
166
167impl<'db, 'cache, L> TrieIterator<L> for FatDBDoubleEndedIterator<'db, 'cache, L>
168where
169 L: TrieLayout,
170{
171 fn seek(&mut self, key: &[u8]) -> Result<(), TrieHash<L>, CError<L>> {
172 let hashed_key = L::Hash::hash(key);
173 self.trie_iterator.seek(hashed_key.as_ref())
174 }
175}
176
177impl<'db, 'cache, L> Iterator for FatDBDoubleEndedIterator<'db, 'cache, L>
178where
179 L: TrieLayout,
180{
181 type Item = TrieItem<TrieHash<L>, CError<L>>;
182
183 fn next(&mut self) -> Option<Self::Item> {
184 self.trie_iterator.next().map(|res| {
185 res.map(|(hash, value)| {
186 let aux_hash = L::Hash::hash(&hash);
187 (
188 self.trie.db().get(&aux_hash, Default::default()).expect("Missing fatdb hash"),
189 value,
190 )
191 })
192 })
193 }
194}
195
196impl<'db, 'cache, L> DoubleEndedIterator for FatDBDoubleEndedIterator<'db, 'cache, L>
197where
198 L: TrieLayout,
199{
200 fn next_back(&mut self) -> Option<Self::Item> {
201 self.trie_iterator.next_back().map(|res| {
202 res.map(|(hash, value)| {
203 let aux_hash = L::Hash::hash(&hash);
204 (
205 self.trie.db().get(&aux_hash, Default::default()).expect("Missing fatdb hash"),
206 value,
207 )
208 })
209 })
210 }
211}
212
213pub struct FatDBKeyIterator<'db, 'cache, L>
215where
216 L: TrieLayout,
217{
218 trie_iterator: TrieDBKeyIterator<'db, 'cache, L>,
219 trie: &'db TrieDB<'db, 'cache, L>,
220}
221
222impl<'db, 'cache, L> FatDBKeyIterator<'db, 'cache, L>
223where
224 L: TrieLayout,
225{
226 pub fn new(trie: &'db TrieDB<'db, 'cache, L>) -> Result<Self, TrieHash<L>, CError<L>> {
228 Ok(FatDBKeyIterator { trie_iterator: TrieDBKeyIterator::new(trie)?, trie })
229 }
230}
231
232impl<'db, 'cache, L> TrieIterator<L> for FatDBKeyIterator<'db, 'cache, L>
233where
234 L: TrieLayout,
235{
236 fn seek(&mut self, key: &[u8]) -> Result<(), TrieHash<L>, CError<L>> {
237 let hashed_key = L::Hash::hash(key);
238 self.trie_iterator.seek(hashed_key.as_ref())
239 }
240}
241
242impl<'db, 'cache, L> Iterator for FatDBKeyIterator<'db, 'cache, L>
243where
244 L: TrieLayout,
245{
246 type Item = TrieKeyItem<TrieHash<L>, CError<L>>;
247
248 fn next(&mut self) -> Option<Self::Item> {
249 self.trie_iterator.next().map(|res| {
250 res.map(|hash| {
251 let aux_hash = L::Hash::hash(&hash);
252 self.trie.db().get(&aux_hash, Default::default()).expect("Missing fatdb hash")
253 })
254 })
255 }
256}