1use super::{CError, DBValue, Result, Trie, TrieHash, TrieIterator, TrieLayout};
16use crate::{
17 nibble::{nibble_ops, NibbleSlice, NibbleVec},
18 node::{Node, NodeHandle, NodePlan, OwnedNode, Value},
19 triedb::TrieDB,
20 TrieDoubleEndedIterator, TrieError, TrieItem, TrieKeyItem,
21};
22use hash_db::{Hasher, Prefix, EMPTY_PREFIX};
23
24use crate::rstd::{boxed::Box, sync::Arc, vec::Vec};
25
26#[cfg_attr(feature = "std", derive(Debug))]
27#[derive(Clone, Copy, Eq, PartialEq)]
28enum Status {
29 Entering,
30 At,
31 AtChild(usize),
32 Exiting,
33 AftExiting,
34}
35
36#[cfg_attr(feature = "std", derive(Debug))]
37#[derive(Eq, PartialEq)]
38struct Crumb<H: Hasher> {
39 hash: Option<H::Out>,
40 node: Arc<OwnedNode<DBValue>>,
41 status: Status,
42}
43
44impl<H: Hasher> Crumb<H> {
45 fn step(&mut self, fwd: bool) {
47 self.status = match (self.status, self.node.node_plan()) {
48 (Status::Entering, NodePlan::Extension { .. }) => Status::At,
49 (Status::Entering, NodePlan::Branch { .. }) |
50 (Status::Entering, NodePlan::NibbledBranch { .. }) => Status::At,
51 (Status::At, NodePlan::Branch { .. }) |
52 (Status::At, NodePlan::NibbledBranch { .. }) =>
53 if fwd {
54 Status::AtChild(0)
55 } else {
56 Status::AtChild(nibble_ops::NIBBLE_LENGTH - 1)
57 },
58 (Status::AtChild(x), NodePlan::Branch { .. }) |
59 (Status::AtChild(x), NodePlan::NibbledBranch { .. })
60 if fwd && x < (nibble_ops::NIBBLE_LENGTH - 1) =>
61 Status::AtChild(x + 1),
62 (Status::AtChild(x), NodePlan::Branch { .. }) |
63 (Status::AtChild(x), NodePlan::NibbledBranch { .. })
64 if !fwd && x > 0 =>
65 Status::AtChild(x - 1),
66 (Status::Exiting, _) => Status::AftExiting,
67 _ => Status::Exiting,
68 }
69 }
70}
71
72pub struct TrieDBRawIterator<L: TrieLayout> {
74 trail: Vec<Crumb<L::Hash>>,
76 key_nibbles: NibbleVec,
78}
79
80impl<L: TrieLayout> TrieDBRawIterator<L> {
81 pub fn empty() -> Self {
83 Self { trail: Vec::new(), key_nibbles: NibbleVec::new() }
84 }
85
86 pub fn new(db: &TrieDB<L>) -> Result<Self, TrieHash<L>, CError<L>> {
88 let mut r =
89 TrieDBRawIterator { trail: Vec::with_capacity(8), key_nibbles: NibbleVec::new() };
90 let (root_node, root_hash) = db.get_raw_or_lookup(
91 *db.root(),
92 NodeHandle::Hash(db.root().as_ref()),
93 EMPTY_PREFIX,
94 true,
95 )?;
96
97 r.descend(root_node, root_hash);
98 Ok(r)
99 }
100
101 pub fn new_prefixed(db: &TrieDB<L>, prefix: &[u8]) -> Result<Self, TrieHash<L>, CError<L>> {
103 let mut iter = TrieDBRawIterator::new(db)?;
104 iter.prefix(db, prefix, true)?;
105
106 Ok(iter)
107 }
108
109 pub fn new_prefixed_then_seek(
113 db: &TrieDB<L>,
114 prefix: &[u8],
115 start_at: &[u8],
116 ) -> Result<Self, TrieHash<L>, CError<L>> {
117 let mut iter = TrieDBRawIterator::new(db)?;
118 iter.prefix_then_seek(db, prefix, start_at)?;
119 Ok(iter)
120 }
121
122 fn descend(&mut self, node: OwnedNode<DBValue>, node_hash: Option<TrieHash<L>>) {
124 self.trail
125 .push(Crumb { hash: node_hash, status: Status::Entering, node: Arc::new(node) });
126 }
127
128 pub(crate) fn fetch_value(
130 db: &TrieDB<L>,
131 key: &[u8],
132 prefix: Prefix,
133 ) -> Result<DBValue, TrieHash<L>, CError<L>> {
134 let mut res = TrieHash::<L>::default();
135 res.as_mut().copy_from_slice(key);
136 db.fetch_value(res, prefix)
137 }
138
139 pub(crate) fn seek(
146 &mut self,
147 db: &TrieDB<L>,
148 key: &[u8],
149 fwd: bool,
150 ) -> Result<bool, TrieHash<L>, CError<L>> {
151 self.trail.clear();
152 self.key_nibbles.clear();
153 let key = NibbleSlice::new(key);
154
155 let (mut node, mut node_hash) = db.get_raw_or_lookup(
156 <TrieHash<L>>::default(),
157 NodeHandle::Hash(db.root().as_ref()),
158 EMPTY_PREFIX,
159 true,
160 )?;
161 let mut partial = key;
162 let mut full_key_nibbles = 0;
163 loop {
164 let (next_node, next_node_hash) = {
165 self.descend(node, node_hash);
166 let crumb = self.trail.last_mut().expect(
167 "descend pushes a crumb onto the trail; \
168 thus the trail is non-empty; qed",
169 );
170 let node_data = crumb.node.data();
171
172 match crumb.node.node_plan() {
173 NodePlan::Leaf { partial: partial_plan, .. } => {
174 let slice = partial_plan.build(node_data);
175 if (fwd && slice < partial) || (!fwd && slice > partial) {
176 crumb.status = Status::Exiting;
177 return Ok(false);
178 }
179 return Ok(slice.starts_with(&partial));
180 },
181 NodePlan::Extension { partial: partial_plan, child } => {
182 let slice = partial_plan.build(node_data);
183 if !partial.starts_with(&slice) {
184 if (fwd && slice < partial) || (!fwd && slice > partial) {
185 crumb.status = Status::Exiting;
186 self.key_nibbles.append_partial(slice.right());
187 return Ok(false);
188 }
189 return Ok(slice.starts_with(&partial));
190 }
191
192 full_key_nibbles += slice.len();
193 partial = partial.mid(slice.len());
194 crumb.status = Status::At;
195 self.key_nibbles.append_partial(slice.right());
196
197 let prefix = key.back(full_key_nibbles);
198 db.get_raw_or_lookup(
199 node_hash.unwrap_or_default(),
200 child.build(node_data),
201 prefix.left(),
202 true,
203 )?
204 },
205 NodePlan::Branch { value: _, children } => {
206 if partial.is_empty() {
207 return Ok(true);
208 }
209
210 let i = partial.at(0);
211 crumb.status = Status::AtChild(i as usize);
212 self.key_nibbles.push(i);
213
214 if let Some(child) = &children[i as usize] {
215 full_key_nibbles += 1;
216 partial = partial.mid(1);
217
218 let prefix = key.back(full_key_nibbles);
219 db.get_raw_or_lookup(
220 node_hash.unwrap_or_default(),
221 child.build(node_data),
222 prefix.left(),
223 true,
224 )?
225 } else {
226 return Ok(false);
227 }
228 },
229 NodePlan::NibbledBranch { partial: partial_plan, value: _, children } => {
230 let slice = partial_plan.build(node_data);
231 if !partial.starts_with(&slice) {
232 if (fwd && slice < partial) || (!fwd && slice > partial) {
233 crumb.status = Status::Exiting;
234 self.key_nibbles.append_partial(slice.right());
235 self.key_nibbles.push((nibble_ops::NIBBLE_LENGTH - 1) as u8);
236 return Ok(false);
237 }
238 return Ok(slice.starts_with(&partial));
239 }
240
241 full_key_nibbles += slice.len();
242 partial = partial.mid(slice.len());
243
244 if partial.is_empty() {
245 return Ok(true);
246 }
247
248 let i = partial.at(0);
249 crumb.status = Status::AtChild(i as usize);
250 self.key_nibbles.append_partial(slice.right());
251 self.key_nibbles.push(i);
252
253 if let Some(child) = &children[i as usize] {
254 full_key_nibbles += 1;
255 partial = partial.mid(1);
256
257 let prefix = key.back(full_key_nibbles);
258 db.get_raw_or_lookup(
259 node_hash.unwrap_or_default(),
260 child.build(node_data),
261 prefix.left(),
262 true,
263 )?
264 } else {
265 return Ok(false);
266 }
267 },
268 NodePlan::Empty => {
269 if !partial.is_empty() {
270 crumb.status = Status::Exiting;
271 return Ok(false);
272 }
273 return Ok(true);
274 },
275 }
276 };
277
278 node = next_node;
279 node_hash = next_node_hash;
280 }
281 }
282
283 fn prefix(
286 &mut self,
287 db: &TrieDB<L>,
288 prefix: &[u8],
289 fwd: bool,
290 ) -> Result<(), TrieHash<L>, CError<L>> {
291 if self.seek(db, prefix, fwd)? {
292 if let Some(v) = self.trail.pop() {
293 self.trail.clear();
294 self.trail.push(v);
295 }
296 } else {
297 self.trail.clear();
298 }
299
300 Ok(())
301 }
302
303 fn prefix_then_seek(
306 &mut self,
307 db: &TrieDB<L>,
308 prefix: &[u8],
309 seek: &[u8],
310 ) -> Result<(), TrieHash<L>, CError<L>> {
311 if prefix.is_empty() {
312 return self.seek(db, seek, true).map(|_| ());
314 }
315
316 if seek.is_empty() || seek <= prefix {
317 return self.prefix(db, prefix, true);
321 }
322
323 if !seek.starts_with(prefix) {
324 self.trail.clear();
327 return Ok(());
328 }
329
330 if !self.seek(db, prefix, true)? {
331 self.trail.clear();
333 return Ok(());
334 }
335
336 self.seek(db, seek, true)?;
338
339 let prefix_len = prefix.len() * crate::nibble::nibble_ops::NIBBLE_PER_BYTE;
340 let mut len = 0;
341 for i in 0..self.trail.len() {
343 match self.trail[i].node.node_plan() {
344 NodePlan::Empty => {},
345 NodePlan::Branch { .. } => {
346 len += 1;
347 },
348 NodePlan::Leaf { partial, .. } => {
349 len += partial.len();
350 },
351 NodePlan::Extension { partial, .. } => {
352 len += partial.len();
353 },
354 NodePlan::NibbledBranch { partial, .. } => {
355 len += 1;
356 len += partial.len();
357 },
358 }
359 if len > prefix_len {
360 self.trail = self.trail.split_off(i);
361 return Ok(());
362 }
363 }
364
365 self.trail.clear();
366 Ok(())
367 }
368
369 pub(crate) fn next_raw_item(
375 &mut self,
376 db: &TrieDB<L>,
377 fwd: bool,
378 ) -> Option<
379 Result<
380 (&NibbleVec, Option<&TrieHash<L>>, &Arc<OwnedNode<DBValue>>),
381 TrieHash<L>,
382 CError<L>,
383 >,
384 > {
385 loop {
386 let crumb = self.trail.last_mut()?;
387 let node_data = crumb.node.data();
388
389 match (crumb.status, crumb.node.node_plan()) {
390 (Status::Entering, _) =>
391 if fwd {
392 let crumb = self.trail.last_mut().expect("we've just fetched the last element using `last_mut` so this cannot fail; qed");
393 crumb.step(fwd);
394 return Some(Ok((&self.key_nibbles, crumb.hash.as_ref(), &crumb.node)));
395 } else {
396 crumb.step(fwd);
397 },
398 (Status::AftExiting, _) => {
399 self.trail.pop().expect("we've just fetched the last element using `last_mut` so this cannot fail; qed");
400 self.trail.last_mut()?.step(fwd);
401 },
402 (Status::Exiting, node) => {
403 match node {
404 NodePlan::Empty | NodePlan::Leaf { .. } => {},
405 NodePlan::Extension { partial, .. } => {
406 self.key_nibbles.drop_lasts(partial.len());
407 },
408 NodePlan::Branch { .. } => {
409 self.key_nibbles.pop();
410 },
411 NodePlan::NibbledBranch { partial, .. } => {
412 self.key_nibbles.drop_lasts(partial.len() + 1);
413 },
414 }
415 self.trail.last_mut()?.step(fwd);
416 if !fwd {
417 let crumb = self.trail.last_mut().expect("we've just fetched the last element using `last_mut` so this cannot fail; qed");
418 return Some(Ok((&self.key_nibbles, crumb.hash.as_ref(), &crumb.node)));
419 }
420 },
421 (Status::At, NodePlan::Extension { partial: partial_plan, child }) => {
422 let partial = partial_plan.build(node_data);
423 self.key_nibbles.append_partial(partial.right());
424
425 match db.get_raw_or_lookup(
426 crumb.hash.unwrap_or_default(),
427 child.build(node_data),
428 self.key_nibbles.as_prefix(),
429 true,
430 ) {
431 Ok((node, node_hash)) => {
432 self.descend(node, node_hash);
433 },
434 Err(err) => {
435 crumb.step(fwd);
436 return Some(Err(err));
437 },
438 }
439 },
440 (Status::At, NodePlan::Branch { .. }) => {
441 self.key_nibbles.push(if fwd {
442 0
443 } else {
444 (nibble_ops::NIBBLE_LENGTH - 1) as u8
445 });
446 crumb.step(fwd);
447 },
448 (Status::At, NodePlan::NibbledBranch { partial: partial_plan, .. }) => {
449 let partial = partial_plan.build(node_data);
450 self.key_nibbles.append_partial(partial.right());
451 self.key_nibbles.push(if fwd {
452 0
453 } else {
454 (nibble_ops::NIBBLE_LENGTH - 1) as u8
455 });
456 crumb.step(fwd);
457 },
458 (Status::AtChild(i), NodePlan::Branch { children, .. }) |
459 (Status::AtChild(i), NodePlan::NibbledBranch { children, .. }) => {
460 if let Some(child) = &children[i] {
461 self.key_nibbles.pop();
462 self.key_nibbles.push(i as u8);
463
464 match db.get_raw_or_lookup(
465 crumb.hash.unwrap_or_default(),
466 child.build(node_data),
467 self.key_nibbles.as_prefix(),
468 true,
469 ) {
470 Ok((node, node_hash)) => {
471 self.descend(node, node_hash);
472 },
473 Err(err) => {
474 crumb.step(fwd);
475 return Some(Err(err));
476 },
477 }
478 } else {
479 crumb.step(fwd);
480 }
481 },
482 _ => panic!(
483 "Crumb::step and TrieDBNodeIterator are implemented so that \
484 the above arms are the only possible states"
485 ),
486 }
487 }
488 }
489
490 pub fn next_item(&mut self, db: &TrieDB<L>) -> Option<TrieItem<TrieHash<L>, CError<L>>> {
494 while let Some(raw_item) = self.next_raw_item(db, true) {
495 let (key, maybe_extra_nibble, value) = match Self::extract_key_from_raw_item(raw_item) {
496 Some(Ok(k)) => k,
497 Some(Err(err)) => return Some(Err(err)),
498 None => continue,
499 };
500
501 if let Some(extra_nibble) = maybe_extra_nibble {
502 return Some(Err(Box::new(TrieError::ValueAtIncompleteKey(key, extra_nibble))));
503 }
504
505 let value = match value {
506 Value::Node(hash) => match Self::fetch_value(db, &hash, (key.as_slice(), None)) {
507 Ok(value) => value,
508 Err(err) => return Some(Err(err)),
509 },
510 Value::Inline(value) => value.to_vec(),
511 };
512
513 return Some(Ok((key, value)));
514 }
515 None
516 }
517
518 pub fn prev_item(&mut self, db: &TrieDB<L>) -> Option<TrieItem<TrieHash<L>, CError<L>>> {
522 while let Some(raw_item) = self.next_raw_item(db, false) {
523 let (key, maybe_extra_nibble, value) = match Self::extract_key_from_raw_item(raw_item) {
524 Some(Ok(k)) => k,
525 Some(Err(err)) => return Some(Err(err)),
526 None => continue,
527 };
528
529 if let Some(extra_nibble) = maybe_extra_nibble {
530 return Some(Err(Box::new(TrieError::ValueAtIncompleteKey(key, extra_nibble))));
531 }
532
533 let value = match value {
534 Value::Node(hash) => match Self::fetch_value(db, &hash, (key.as_slice(), None)) {
535 Ok(value) => value,
536 Err(err) => return Some(Err(err)),
537 },
538 Value::Inline(value) => value.to_vec(),
539 };
540
541 return Some(Ok((key, value)));
542 }
543 None
544 }
545
546 pub fn next_key(&mut self, db: &TrieDB<L>) -> Option<TrieKeyItem<TrieHash<L>, CError<L>>> {
550 while let Some(raw_item) = self.next_raw_item(db, true) {
551 let (key, maybe_extra_nibble, _) = match Self::extract_key_from_raw_item(raw_item) {
552 Some(Ok(k)) => k,
553 Some(Err(err)) => return Some(Err(err)),
554 None => continue,
555 };
556
557 if let Some(extra_nibble) = maybe_extra_nibble {
558 return Some(Err(Box::new(TrieError::ValueAtIncompleteKey(key, extra_nibble))));
559 }
560
561 return Some(Ok(key));
562 }
563 None
564 }
565
566 pub fn prev_key(&mut self, db: &TrieDB<L>) -> Option<TrieKeyItem<TrieHash<L>, CError<L>>> {
570 while let Some(raw_item) = self.next_raw_item(db, false) {
571 let (key, maybe_extra_nibble, _) = match Self::extract_key_from_raw_item(raw_item) {
572 Some(Ok(k)) => k,
573 Some(Err(err)) => return Some(Err(err)),
574 None => continue,
575 };
576
577 if let Some(extra_nibble) = maybe_extra_nibble {
578 return Some(Err(Box::new(TrieError::ValueAtIncompleteKey(key, extra_nibble))));
579 }
580
581 return Some(Ok(key));
582 }
583 None
584 }
585
586 fn extract_key_from_raw_item<'a>(
591 raw_item: Result<
592 (&NibbleVec, Option<&TrieHash<L>>, &'a Arc<OwnedNode<DBValue>>),
593 TrieHash<L>,
594 CError<L>,
595 >,
596 ) -> Option<Result<(Vec<u8>, Option<u8>, Value<'a>), TrieHash<L>, CError<L>>> {
597 let (prefix, _, node) = match raw_item {
598 Ok(raw_item) => raw_item,
599 Err(err) => return Some(Err(err)),
600 };
601
602 let mut prefix = prefix.clone();
603 let value = match node.node() {
604 Node::Leaf(partial, value) => {
605 prefix.append_partial(partial.right());
606 value
607 },
608 Node::Branch(_, value) => match value {
609 Some(value) => value,
610 None => return None,
611 },
612 Node::NibbledBranch(partial, _, value) => {
613 prefix.append_partial(partial.right());
614 match value {
615 Some(value) => value,
616 None => return None,
617 }
618 },
619 _ => return None,
620 };
621
622 let (key_slice, maybe_extra_nibble) = prefix.as_prefix();
623
624 Some(Ok((key_slice.to_vec(), maybe_extra_nibble, value)))
625 }
626}
627
628pub struct TrieDBNodeIterator<'a, 'cache, L: TrieLayout> {
634 db: &'a TrieDB<'a, 'cache, L>,
635 raw_iter: TrieDBRawIterator<L>,
636}
637
638impl<'a, 'cache, L: TrieLayout> TrieDBNodeIterator<'a, 'cache, L> {
639 pub fn new(db: &'a TrieDB<'a, 'cache, L>) -> Result<Self, TrieHash<L>, CError<L>> {
641 Ok(Self { raw_iter: TrieDBRawIterator::new(db)?, db })
642 }
643
644 pub fn from_raw(db: &'a TrieDB<'a, 'cache, L>, raw_iter: TrieDBRawIterator<L>) -> Self {
646 Self { db, raw_iter }
647 }
648
649 pub fn into_raw(self) -> TrieDBRawIterator<L> {
651 self.raw_iter
652 }
653
654 pub fn fetch_value(
656 &self,
657 key: &[u8],
658 prefix: Prefix,
659 ) -> Result<DBValue, TrieHash<L>, CError<L>> {
660 TrieDBRawIterator::fetch_value(self.db, key, prefix)
661 }
662
663 pub fn prefix(&mut self, prefix: &[u8]) -> Result<(), TrieHash<L>, CError<L>> {
666 self.raw_iter.prefix(self.db, prefix, true)
667 }
668
669 pub fn prefix_then_seek(
672 &mut self,
673 prefix: &[u8],
674 seek: &[u8],
675 ) -> Result<(), TrieHash<L>, CError<L>> {
676 self.raw_iter.prefix_then_seek(self.db, prefix, seek)
677 }
678
679 pub fn db(&self) -> &dyn hash_db::HashDBRef<L::Hash, DBValue> {
681 self.db.db()
682 }
683}
684
685impl<'a, 'cache, L: TrieLayout> TrieIterator<L> for TrieDBNodeIterator<'a, 'cache, L> {
686 fn seek(&mut self, key: &[u8]) -> Result<(), TrieHash<L>, CError<L>> {
687 self.raw_iter.seek(self.db, key, true).map(|_| ())
688 }
689}
690
691impl<'a, 'cache, L: TrieLayout> Iterator for TrieDBNodeIterator<'a, 'cache, L> {
692 type Item =
693 Result<(NibbleVec, Option<TrieHash<L>>, Arc<OwnedNode<DBValue>>), TrieHash<L>, CError<L>>;
694
695 fn next(&mut self) -> Option<Self::Item> {
696 self.raw_iter.next_raw_item(self.db, true).map(|result| {
697 result.map(|(nibble, hash, node)| (nibble.clone(), hash.cloned(), node.clone()))
698 })
699 }
700}
701
702pub struct TrieDBNodeDoubleEndedIterator<'a, 'cache, L: TrieLayout> {
704 db: &'a TrieDB<'a, 'cache, L>,
705 raw_iter: TrieDBRawIterator<L>,
706 back_raw_iter: TrieDBRawIterator<L>,
707}
708
709impl<'a, 'cache, L: TrieLayout> TrieDBNodeDoubleEndedIterator<'a, 'cache, L> {
710 pub fn new(db: &'a TrieDB<'a, 'cache, L>) -> Result<Self, TrieHash<L>, CError<L>> {
712 Ok(Self {
713 db,
714 raw_iter: TrieDBRawIterator::new(db)?,
715 back_raw_iter: TrieDBRawIterator::new(db)?,
716 })
717 }
718
719 pub fn from_raw(
721 db: &'a TrieDB<'a, 'cache, L>,
722 raw_iter: TrieDBRawIterator<L>,
723 back_raw_iter: TrieDBRawIterator<L>,
724 ) -> Self {
725 Self { db, raw_iter, back_raw_iter }
726 }
727
728 pub fn into_raw(self) -> TrieDBRawIterator<L> {
730 self.raw_iter
731 }
732
733 pub fn into_raw_back(self) -> TrieDBRawIterator<L> {
735 self.back_raw_iter
736 }
737
738 pub fn fetch_value(
740 &self,
741 key: &[u8],
742 prefix: Prefix,
743 ) -> Result<DBValue, TrieHash<L>, CError<L>> {
744 TrieDBRawIterator::fetch_value(self.db, key, prefix)
745 }
746
747 pub fn prefix(&mut self, prefix: &[u8]) -> Result<(), TrieHash<L>, CError<L>> {
750 self.raw_iter.prefix(self.db, prefix, true)?;
751 self.back_raw_iter.prefix(self.db, prefix, false)
752 }
753
754 pub fn prefix_then_seek(
757 &mut self,
758 prefix: &[u8],
759 seek: &[u8],
760 ) -> Result<(), TrieHash<L>, CError<L>> {
761 self.raw_iter.prefix_then_seek(self.db, prefix, seek)?;
762 self.back_raw_iter.prefix_then_seek(self.db, prefix, seek)
763 }
764
765 pub fn db(&self) -> &dyn hash_db::HashDBRef<L::Hash, DBValue> {
767 self.db.db()
768 }
769}
770
771impl<L: TrieLayout> TrieDoubleEndedIterator<L> for TrieDBNodeDoubleEndedIterator<'_, '_, L> {}
772
773impl<'a, 'cache, L: TrieLayout> TrieIterator<L> for TrieDBNodeDoubleEndedIterator<'a, 'cache, L> {
774 fn seek(&mut self, key: &[u8]) -> Result<(), TrieHash<L>, CError<L>> {
775 self.raw_iter.seek(self.db, key, true).map(|_| ())?;
776 self.back_raw_iter.seek(self.db, key, false).map(|_| ())
777 }
778}
779
780impl<'a, 'cache, L: TrieLayout> Iterator for TrieDBNodeDoubleEndedIterator<'a, 'cache, L> {
781 type Item =
782 Result<(NibbleVec, Option<TrieHash<L>>, Arc<OwnedNode<DBValue>>), TrieHash<L>, CError<L>>;
783
784 fn next(&mut self) -> Option<Self::Item> {
785 self.raw_iter.next_raw_item(self.db, true).map(|result| {
786 result.map(|(nibble, hash, node)| (nibble.clone(), hash.cloned(), node.clone()))
787 })
788 }
789}
790
791impl<'a, 'cache, L: TrieLayout> DoubleEndedIterator
792 for TrieDBNodeDoubleEndedIterator<'a, 'cache, L>
793{
794 fn next_back(&mut self) -> Option<Self::Item> {
795 self.back_raw_iter.next_raw_item(self.db, false).map(|result| {
796 result.map(|(nibble, hash, node)| (nibble.clone(), hash.cloned(), node.clone()))
797 })
798 }
799}