trie_db_fun/
iterator.rs

1// Copyright 2017, 2021 Parity Technologies
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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	/// Move on to the next status in the node's sequence in a direction.
46	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
72/// Iterator for going through all nodes in the trie in pre-order traversal order.
73pub struct TrieDBRawIterator<L: TrieLayout> {
74	/// Forward trail of nodes to visit.
75	trail: Vec<Crumb<L::Hash>>,
76	/// Forward iteration key nibbles of the current node.
77	key_nibbles: NibbleVec,
78}
79
80impl<L: TrieLayout> TrieDBRawIterator<L> {
81	/// Create a new empty iterator.
82	pub fn empty() -> Self {
83		Self { trail: Vec::new(), key_nibbles: NibbleVec::new() }
84	}
85
86	/// Create a new iterator.
87	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	/// Create a new iterator, but limited to a given prefix.
102	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	/// Create a new iterator, but limited to a given prefix.
110	/// It then do a seek operation from prefixed context (using `seek` lose
111	/// prefix context by default).
112	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	/// Descend into a node.
123	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	/// Fetch value by hash at a current node height
129	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	/// Seek a node position at 'key' for iterator.
140	/// Returns true if the cursor is at or after the key, but still shares
141	/// a common prefix with the key, return false if the key do not
142	/// share its prefix with the node.
143	/// This indicates if there is still nodes to iterate over in the case
144	/// where we limit iteration to 'key' as a prefix.
145	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	/// Advance the iterator into a prefix, no value out of the prefix will be accessed
284	/// or returned after this operation.
285	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	/// Advance the iterator into a prefix, no value out of the prefix will be accessed
304	/// or returned after this operation.
305	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			// There's no prefix, so just seek.
313			return self.seek(db, seek, true).map(|_| ());
314		}
315
316		if seek.is_empty() || seek <= prefix {
317			// Either we're not supposed to seek anywhere,
318			// or we're supposed to seek *before* the prefix,
319			// so just directly go to the prefix.
320			return self.prefix(db, prefix, true);
321		}
322
323		if !seek.starts_with(prefix) {
324			// We're supposed to seek *after* the prefix,
325			// so just return an empty iterator.
326			self.trail.clear();
327			return Ok(());
328		}
329
330		if !self.seek(db, prefix, true)? {
331			// The database doesn't have a key with such a prefix.
332			self.trail.clear();
333			return Ok(());
334		}
335
336		// Now seek forward again.
337		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		// look first prefix in trail
342		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	/// Fetches the next raw item.
370	//
371	/// Must be called with the same `db` as when the iterator was created.
372	///
373	/// Specify `fwd` to indicate the direction of the iteration (`true` for forward).
374	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	/// Fetches the next trie item.
491	///
492	/// Must be called with the same `db` as when the iterator was created.
493	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	/// Fetches the previous trie item.
519	///
520	/// Must be called with the same `db` as when the iterator was created.
521	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	/// Fetches the next key.
547	///
548	/// Must be called with the same `db` as when the iterator was created.
549	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	/// Fetches the previous key.
567	///
568	/// Must be called with the same `db` as when the iterator was created.
569	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	/// Extracts the key from the result of a raw item retrieval.
587	///
588	/// Given a raw item, it extracts the key information, including the key bytes, an optional
589	/// extra nibble (prefix padding), and the node value.
590	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
628/// Iterator for going through all nodes in the trie in pre-order traversal order.
629///
630/// You can reduce the number of iterations and simultaneously iterate in both directions with two
631/// cursors by using `TrieDBNodeDoubleEndedIterator`. You can convert this iterator into a double
632/// ended iterator with `into_double_ended_iter`.
633pub 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	/// Create a new iterator.
640	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	/// Restore an iterator from a raw iterator.
645	pub fn from_raw(db: &'a TrieDB<'a, 'cache, L>, raw_iter: TrieDBRawIterator<L>) -> Self {
646		Self { db, raw_iter }
647	}
648
649	/// Convert the iterator to a raw iterator.
650	pub fn into_raw(self) -> TrieDBRawIterator<L> {
651		self.raw_iter
652	}
653
654	/// Fetch value by hash at a current node height
655	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	/// Advance the iterator into a prefix, no value out of the prefix will be accessed
664	/// or returned after this operation.
665	pub fn prefix(&mut self, prefix: &[u8]) -> Result<(), TrieHash<L>, CError<L>> {
666		self.raw_iter.prefix(self.db, prefix, true)
667	}
668
669	/// Advance the iterator into a prefix, no value out of the prefix will be accessed
670	/// or returned after this operation.
671	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	/// Access inner hash db.
680	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
702/// Double ended iterator for going through all nodes in the trie in pre-order traversal order.
703pub 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	/// Create a new double ended iterator.
711	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	/// Restore an iterator from a raw iterators.
720	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	/// Convert the iterator to a raw forward iterator.
729	pub fn into_raw(self) -> TrieDBRawIterator<L> {
730		self.raw_iter
731	}
732
733	/// Convert the iterator to a raw backward iterator.
734	pub fn into_raw_back(self) -> TrieDBRawIterator<L> {
735		self.back_raw_iter
736	}
737
738	/// Fetch value by hash at a current node height
739	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	/// Advance the iterator into a prefix, no value out of the prefix will be accessed
748	/// or returned after this operation.
749	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	/// Advance the iterator into a prefix, no value out of the prefix will be accessed
755	/// or returned after this operation.
756	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	/// Access inner hash db.
766	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}