/__w/smoldot/smoldot/repo/lib/src/trie/trie_structure.rs
Line | Count | Source |
1 | | // Smoldot |
2 | | // Copyright (C) 2019-2022 Parity Technologies (UK) Ltd. |
3 | | // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 |
4 | | |
5 | | // This program is free software: you can redistribute it and/or modify |
6 | | // it under the terms of the GNU General Public License as published by |
7 | | // the Free Software Foundation, either version 3 of the License, or |
8 | | // (at your option) any later version. |
9 | | |
10 | | // This program is distributed in the hope that it will be useful, |
11 | | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | | // GNU General Public License for more details. |
14 | | |
15 | | // You should have received a copy of the GNU General Public License |
16 | | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | | |
18 | | //! Manages the structure of a trie. Allows inserting and removing nodes, but does not store any |
19 | | //! value. Only the structure is stored. |
20 | | //! |
21 | | //! See the [`TrieStructure`] struct. |
22 | | |
23 | | // TODO: the API of `TrieStructure` is rather wonky and could be simplified |
24 | | |
25 | | use super::nibble::{Nibble, bytes_to_nibbles}; |
26 | | |
27 | | use alloc::{borrow::ToOwned as _, vec, vec::Vec}; |
28 | | use core::{cmp, fmt, iter, mem, ops}; |
29 | | use either::Either; |
30 | | use slab::Slab; |
31 | | |
32 | | mod tests; |
33 | | |
34 | | /// Stores the structure of a trie, including branch nodes that have no storage value. |
35 | | /// |
36 | | /// The `TUd` parameter is a user data stored in each node. |
37 | | /// |
38 | | /// This struct doesn't represent a complete trie. It only manages the structure of the trie, and |
39 | | /// the storage values have to be maintained in parallel of this. |
40 | | #[derive(Clone)] |
41 | | pub struct TrieStructure<TUd> { |
42 | | /// List of nodes. Using a [`Slab`] guarantees that the node indices never change. |
43 | | nodes: Slab<Node<TUd>>, |
44 | | /// Index of the root node within [`TrieStructure::nodes`]. `None` if the trie is empty. |
45 | | root_index: Option<usize>, |
46 | | } |
47 | | |
48 | | /// Entry in the structure. |
49 | | #[derive(Debug, Clone)] |
50 | | struct Node<TUd> { |
51 | | /// Index of the parent within [`TrieStructure::nodes`]. `None` if this is the root. |
52 | | parent: Option<(usize, Nibble)>, |
53 | | /// Partial key of the node. Portion to add to the values in `parent` to obtain the full key. |
54 | | partial_key: Vec<Nibble>, |
55 | | /// Indices of the children within [`TrieStructure::nodes`]. |
56 | | children: [Option<usize>; 16], |
57 | | /// If true, this node is a so-called "storage node" with a storage value associated to it. If |
58 | | /// false, then it is a so-called "branch node". Branch nodes are automatically removed from |
59 | | /// the trie if their number of children is inferior to 2. |
60 | | has_storage_value: bool, |
61 | | /// User data associated to the node. |
62 | | user_data: TUd, |
63 | | } |
64 | | |
65 | | impl<TUd> TrieStructure<TUd> { |
66 | | /// Builds a new empty trie. |
67 | | /// |
68 | | /// Equivalent to calling [`TrieStructure::with_capacity`] with a capacity of 0. |
69 | | /// |
70 | | /// # Examples |
71 | | /// |
72 | | /// ``` |
73 | | /// use smoldot::trie::trie_structure; |
74 | | /// |
75 | | /// let trie = trie_structure::TrieStructure::<()>::new(); |
76 | | /// assert!(trie.is_empty()); |
77 | | /// assert_eq!(trie.capacity(), 0); |
78 | | /// ``` |
79 | 45.5k | pub fn new() -> Self { |
80 | 45.5k | TrieStructure { |
81 | 45.5k | nodes: Slab::new(), |
82 | 45.5k | root_index: None, |
83 | 45.5k | } |
84 | 45.5k | } _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE3newB6_ Line | Count | Source | 79 | 1.02k | pub fn new() -> Self { | 80 | 1.02k | TrieStructure { | 81 | 1.02k | nodes: Slab::new(), | 82 | 1.02k | root_index: None, | 83 | 1.02k | } | 84 | 1.02k | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureuE3newB6_ Line | Count | Source | 79 | 11.7k | pub fn new() -> Self { | 80 | 11.7k | TrieStructure { | 81 | 11.7k | nodes: Slab::new(), | 82 | 11.7k | root_index: None, | 83 | 11.7k | } | 84 | 11.7k | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB4_16TrieEntryVersionEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE3newB6_ Line | Count | Source | 79 | 32.7k | pub fn new() -> Self { | 80 | 32.7k | TrieStructure { | 81 | 32.7k | nodes: Slab::new(), | 82 | 32.7k | root_index: None, | 83 | 32.7k | } | 84 | 32.7k | } |
Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE3newCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructurepE3newB6_ _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE3newCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 79 | 2 | pub fn new() -> Self { | 80 | 2 | TrieStructure { | 81 | 2 | nodes: Slab::new(), | 82 | 2 | root_index: None, | 83 | 2 | } | 84 | 2 | } |
_RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE3newCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 79 | 19 | pub fn new() -> Self { | 80 | 19 | TrieStructure { | 81 | 19 | nodes: Slab::new(), | 82 | 19 | root_index: None, | 83 | 19 | } | 84 | 19 | } |
|
85 | | |
86 | | /// Builds a new empty trie with a capacity for the given number of nodes. |
87 | | /// |
88 | | /// # Examples |
89 | | /// |
90 | | /// ``` |
91 | | /// use smoldot::trie::trie_structure; |
92 | | /// |
93 | | /// let trie = trie_structure::TrieStructure::<()>::with_capacity(12); |
94 | | /// assert!(trie.is_empty()); |
95 | | /// assert_eq!(trie.capacity(), 12); |
96 | | /// ``` |
97 | 1.50k | pub fn with_capacity(capacity: usize) -> Self { |
98 | 1.50k | TrieStructure { |
99 | 1.50k | nodes: Slab::with_capacity(capacity), |
100 | 1.50k | root_index: None, |
101 | 1.50k | } |
102 | 1.50k | } _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE13with_capacityB6_ Line | Count | Source | 97 | 1.50k | pub fn with_capacity(capacity: usize) -> Self { | 98 | 1.50k | TrieStructure { | 99 | 1.50k | nodes: Slab::with_capacity(capacity), | 100 | 1.50k | root_index: None, | 101 | 1.50k | } | 102 | 1.50k | } |
Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE13with_capacityB6_ |
103 | | |
104 | | /// Returns the number of nodes (storage or branch nodes) the trie can hold without |
105 | | /// reallocating. |
106 | | /// |
107 | | /// # Examples |
108 | | /// |
109 | | /// ``` |
110 | | /// use smoldot::trie::trie_structure; |
111 | | /// |
112 | | /// let trie = trie_structure::TrieStructure::<()>::with_capacity(7); |
113 | | /// assert_eq!(trie.capacity(), 7); |
114 | | /// ``` |
115 | 0 | pub fn capacity(&self) -> usize { |
116 | 0 | self.nodes.capacity() |
117 | 0 | } Unexecuted instantiation: _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructurepE8capacityB6_ Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructurepE8capacityB6_ |
118 | | |
119 | | /// Returns `true` if the trie doesn't contain any node. |
120 | | /// |
121 | | /// Equivalent to [`TrieStructure::len`] returning 0. |
122 | | /// |
123 | | /// # Examples |
124 | | /// |
125 | | /// ``` |
126 | | /// use smoldot::trie::{self, trie_structure}; |
127 | | /// |
128 | | /// let mut trie = trie_structure::TrieStructure::new(); |
129 | | /// assert!(trie.is_empty()); |
130 | | /// |
131 | | /// // Insert a node. |
132 | | /// trie |
133 | | /// .node(trie::bytes_to_nibbles(b"foo".iter().cloned())) |
134 | | /// .into_vacant() |
135 | | /// .unwrap() |
136 | | /// .insert_storage_value() |
137 | | /// .insert((), ()); |
138 | | /// assert!(!trie.is_empty()); |
139 | | /// |
140 | | /// // Remove the newly-inserted node. |
141 | | /// trie |
142 | | /// .node(trie::bytes_to_nibbles(b"foo".iter().cloned())) |
143 | | /// .into_occupied() |
144 | | /// .unwrap() |
145 | | /// .into_storage() |
146 | | /// .unwrap() |
147 | | /// .remove(); |
148 | | /// assert!(trie.is_empty()); |
149 | | /// ``` |
150 | 1 | pub fn is_empty(&self) -> bool { |
151 | 1 | self.nodes.is_empty() |
152 | 1 | } _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureuE8is_emptyB6_ Line | Count | Source | 150 | 1 | pub fn is_empty(&self) -> bool { | 151 | 1 | self.nodes.is_empty() | 152 | 1 | } |
Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructurepE8is_emptyB6_ |
153 | | |
154 | | /// Returns the number of nodes, both branch and storage nodes, in the trie structure. |
155 | 4 | pub fn len(&self) -> usize { |
156 | 4 | self.nodes.len() |
157 | 4 | } _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureuE3lenB6_ Line | Count | Source | 155 | 4 | pub fn len(&self) -> usize { | 156 | 4 | self.nodes.len() | 157 | 4 | } |
Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructurepE3lenB6_ |
158 | | |
159 | | /// Reduces the capacity of the trie as much as possible. |
160 | | /// |
161 | | /// See [`Vec::shrink_to_fit`]. |
162 | 0 | pub fn shrink_to_fit(&mut self) { |
163 | 0 | self.nodes.shrink_to_fit(); |
164 | 0 | } Unexecuted instantiation: _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructurepE13shrink_to_fitB6_ Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructurepE13shrink_to_fitB6_ |
165 | | |
166 | | /// Returns a list of all nodes in the structure, without any specific order. |
167 | 8.14k | pub fn iter_unordered(&self) -> impl Iterator<Item = NodeIndex> { |
168 | 318k | self.nodes8.14k .iter8.14k ().map8.14k (|(k, _)| NodeIndex(k)) _RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB6_12proof_encode4NodeEE14iter_unordered0B8_ Line | Count | Source | 168 | 29.7k | self.nodes.iter().map(|(k, _)| NodeIndex(k)) |
_RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE14iter_unordered0B8_ Line | Count | Source | 168 | 2.56k | self.nodes.iter().map(|(k, _)| NodeIndex(k)) |
_RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureuE14iter_unordered0B8_ Line | Count | Source | 168 | 285k | self.nodes.iter().map(|(k, _)| NodeIndex(k)) |
Unexecuted instantiation: _RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE14iter_unordered0Cs4ISLcsFEGeP_6author Unexecuted instantiation: _RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB6_12proof_encode4NodeEE14iter_unordered0B8_ _RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE14iter_unordered0Cs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 168 | 96 | self.nodes.iter().map(|(k, _)| NodeIndex(k)) |
_RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE14iter_unordered0Cs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 168 | 912 | self.nodes.iter().map(|(k, _)| NodeIndex(k)) |
|
169 | 8.14k | } _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE14iter_unorderedB6_ Line | Count | Source | 167 | 1.02k | pub fn iter_unordered(&self) -> impl Iterator<Item = NodeIndex> { | 168 | 1.02k | self.nodes.iter().map(|(k, _)| NodeIndex(k)) | 169 | 1.02k | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureuE14iter_unorderedB6_ Line | Count | Source | 167 | 5.59k | pub fn iter_unordered(&self) -> impl Iterator<Item = NodeIndex> { | 168 | 5.59k | self.nodes.iter().map(|(k, _)| NodeIndex(k)) | 169 | 5.59k | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE14iter_unorderedB6_ Line | Count | Source | 167 | 1.50k | pub fn iter_unordered(&self) -> impl Iterator<Item = NodeIndex> { | 168 | 1.50k | self.nodes.iter().map(|(k, _)| NodeIndex(k)) | 169 | 1.50k | } |
Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE14iter_unorderedCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE14iter_unorderedB6_ _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE14iter_unorderedCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 167 | 2 | pub fn iter_unordered(&self) -> impl Iterator<Item = NodeIndex> { | 168 | 2 | self.nodes.iter().map(|(k, _)| NodeIndex(k)) | 169 | 2 | } |
_RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE14iter_unorderedCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 167 | 19 | pub fn iter_unordered(&self) -> impl Iterator<Item = NodeIndex> { | 168 | 19 | self.nodes.iter().map(|(k, _)| NodeIndex(k)) | 169 | 19 | } |
|
170 | | |
171 | | /// Returns a list of all nodes in the structure in lexicographic order of keys. |
172 | 3.32M | pub fn iter_ordered(&self) -> impl Iterator<Item = NodeIndex> { |
173 | 3.32M | self.all_node_lexicographic_ordered().map(NodeIndex) |
174 | 3.32M | } _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE12iter_orderedB6_ Line | Count | Source | 172 | 2.09M | pub fn iter_ordered(&self) -> impl Iterator<Item = NodeIndex> { | 173 | 2.09M | self.all_node_lexicographic_ordered().map(NodeIndex) | 174 | 2.09M | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureuE12iter_orderedB6_ Line | Count | Source | 172 | 1.09M | pub fn iter_ordered(&self) -> impl Iterator<Item = NodeIndex> { | 173 | 1.09M | self.all_node_lexicographic_ordered().map(NodeIndex) | 174 | 1.09M | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB4_16TrieEntryVersionEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE12iter_orderedB6_ Line | Count | Source | 172 | 131k | pub fn iter_ordered(&self) -> impl Iterator<Item = NodeIndex> { | 173 | 131k | self.all_node_lexicographic_ordered().map(NodeIndex) | 174 | 131k | } |
Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE12iter_orderedCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructurepE12iter_orderedB6_ _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE12iter_orderedCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 172 | 2 | pub fn iter_ordered(&self) -> impl Iterator<Item = NodeIndex> { | 173 | 2 | self.all_node_lexicographic_ordered().map(NodeIndex) | 174 | 2 | } |
_RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE12iter_orderedCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 172 | 19 | pub fn iter_ordered(&self) -> impl Iterator<Item = NodeIndex> { | 173 | 19 | self.all_node_lexicographic_ordered().map(NodeIndex) | 174 | 19 | } |
|
175 | | |
176 | | /// Returns the root node of the trie, or `None` if the trie is empty. |
177 | | /// |
178 | | /// # Examples |
179 | | /// |
180 | | /// ``` |
181 | | /// use smoldot::trie::{self, trie_structure}; |
182 | | /// |
183 | | /// let mut trie = trie_structure::TrieStructure::new(); |
184 | | /// assert!(trie.root_node().is_none()); |
185 | | /// |
186 | | /// // Insert a node. It becomes the root. |
187 | | /// trie |
188 | | /// .node(trie::bytes_to_nibbles(b"foo".iter().cloned())) |
189 | | /// .into_vacant() |
190 | | /// .unwrap() |
191 | | /// .insert_storage_value() |
192 | | /// .insert((), ()); |
193 | | /// |
194 | | /// assert!(trie.root_node().is_some()); |
195 | | /// assert!(trie.root_node().unwrap().parent().is_none()); |
196 | | /// ``` |
197 | 3.00k | pub fn root_node(&'_ mut self) -> Option<NodeAccess<'_, TUd>> { |
198 | 3.00k | Some(self.node_by_index_inner3.00k (self.root_index?1 ).unwrap3.00k ()) |
199 | 3.00k | } _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE9root_nodeB6_ Line | Count | Source | 197 | 3.00k | pub fn root_node(&'_ mut self) -> Option<NodeAccess<'_, TUd>> { | 198 | 3.00k | Some(self.node_by_index_inner3.00k (self.root_index?1 ).unwrap3.00k ()) | 199 | 3.00k | } |
Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE9root_nodeB6_ |
200 | | |
201 | | /// Returns the user data associated with the root node of the trie, or `None` if the trie |
202 | | /// is empty. |
203 | | // TODO: this function exists only because `root_node` mutably borrows |
204 | 35.2k | pub fn root_user_data(&self) -> Option<&TUd> { |
205 | 35.2k | Some(&self.nodes[self.root_index?3 ].user_data) |
206 | 35.2k | } _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE14root_user_dataB6_ Line | Count | Source | 204 | 1.02k | pub fn root_user_data(&self) -> Option<&TUd> { | 205 | 1.02k | Some(&self.nodes[self.root_index?0 ].user_data) | 206 | 1.02k | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE14root_user_dataB6_ Line | Count | Source | 204 | 1.50k | pub fn root_user_data(&self) -> Option<&TUd> { | 205 | 1.50k | Some(&self.nodes[self.root_index?0 ].user_data) | 206 | 1.50k | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB4_16TrieEntryVersionEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE14root_user_dataB6_ Line | Count | Source | 204 | 32.7k | pub fn root_user_data(&self) -> Option<&TUd> { | 205 | 32.7k | Some(&self.nodes[self.root_index?3 ].user_data) | 206 | 32.7k | } |
Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE14root_user_dataB6_ |
207 | | |
208 | | /// Returns an [`Entry`] corresponding to the node whose key is the concatenation of the list |
209 | | /// of nibbles passed as parameter. |
210 | | /// |
211 | | /// # Examples |
212 | | /// |
213 | | /// ``` |
214 | | /// use smoldot::trie::{self, trie_structure}; |
215 | | /// |
216 | | /// let mut trie = trie_structure::TrieStructure::new(); |
217 | | /// |
218 | | /// let node: trie_structure::Entry<_, _> = trie |
219 | | /// .node(trie::bytes_to_nibbles(b"ful".iter().cloned())); |
220 | | /// |
221 | | /// match node { |
222 | | /// // `Occupied` is returned if a node with this key exists. |
223 | | /// trie_structure::Entry::Occupied(_) => unreachable!(), |
224 | | /// |
225 | | /// // `Vacant` is returned if no node with this key exists yet. |
226 | | /// // In this example, a node is inserted. |
227 | | /// trie_structure::Entry::Vacant(entry) => { |
228 | | /// entry.insert_storage_value().insert((), ()) |
229 | | /// }, |
230 | | /// }; |
231 | | /// |
232 | | /// // The same node can for example be queried again. |
233 | | /// // This time, it will be in the `Occupied` state. |
234 | | /// match trie.node(trie::bytes_to_nibbles(b"ful".iter().cloned())) { |
235 | | /// // `NodeAccess::Storage` is used if the node has been explicitly inserted. |
236 | | /// trie_structure::Entry::Occupied(trie_structure::NodeAccess::Storage(_)) => {}, |
237 | | /// |
238 | | /// // `Branch` would be returned if this was a branch node. See below. |
239 | | /// trie_structure::Entry::Occupied(trie_structure::NodeAccess::Branch(_)) => { |
240 | | /// unreachable!() |
241 | | /// }, |
242 | | /// trie_structure::Entry::Vacant(e) => unreachable!(), |
243 | | /// }; |
244 | | /// |
245 | | /// // In order to demonstrate branch nodes, let's insert a node at the key `fez`. |
246 | | /// trie |
247 | | /// .node(trie::bytes_to_nibbles(b"fez".iter().cloned())) |
248 | | /// .into_vacant() |
249 | | /// .unwrap() |
250 | | /// .insert_storage_value() |
251 | | /// .insert((), ()); |
252 | | /// |
253 | | /// // The trie now contains not two but three nodes. A branch node whose key is `f` has |
254 | | /// // automatically been inserted as the parent of both `ful` and `fez`. |
255 | | /// assert_eq!(trie.len(), 3); |
256 | | /// match trie.node(trie::bytes_to_nibbles(b"f".iter().cloned())) { |
257 | | /// trie_structure::Entry::Occupied(trie_structure::NodeAccess::Branch(_)) => {}, |
258 | | /// _ => unreachable!(), |
259 | | /// }; |
260 | | /// ``` |
261 | 2.15M | pub fn node<TKIter>(&'_ mut self, key: TKIter) -> Entry<'_, TUd, TKIter> |
262 | 2.15M | where |
263 | 2.15M | TKIter: Iterator<Item = Nibble> + Clone, |
264 | | { |
265 | 2.15M | match self.existing_node_inner(key.clone()) { |
266 | | ExistingNodeInnerResult::Found { |
267 | 333k | node_index, |
268 | | has_storage_value: true, |
269 | 333k | } => Entry::Occupied(NodeAccess::Storage(StorageNodeAccess { |
270 | 333k | trie: self, |
271 | 333k | node_index, |
272 | 333k | })), |
273 | | ExistingNodeInnerResult::Found { |
274 | 166k | node_index, |
275 | | has_storage_value: false, |
276 | 166k | } => Entry::Occupied(NodeAccess::Branch(BranchNodeAccess { |
277 | 166k | trie: self, |
278 | 166k | node_index, |
279 | 166k | })), |
280 | 1.65M | ExistingNodeInnerResult::NotFound { closest_ancestor } => Entry::Vacant(Vacant { |
281 | 1.65M | trie: self, |
282 | 1.65M | key, |
283 | 1.65M | closest_ancestor: closest_ancestor.map(|(i, _)| i), |
284 | | }), |
285 | | } |
286 | 2.15M | } _RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB5_12proof_encode4NodeEE4nodeINtNtNtNtB1e_4iter8adapters6copied6CopiedINtNtNtB1e_5slice4iter4IterNtNtB5_6nibble6NibbleEEEB7_ Line | Count | Source | 261 | 58.0k | pub fn node<TKIter>(&'_ mut self, key: TKIter) -> Entry<'_, TUd, TKIter> | 262 | 58.0k | where | 263 | 58.0k | TKIter: Iterator<Item = Nibble> + Clone, | 264 | | { | 265 | 58.0k | match self.existing_node_inner(key.clone()) { | 266 | | ExistingNodeInnerResult::Found { | 267 | 28.2k | node_index, | 268 | | has_storage_value: true, | 269 | 28.2k | } => Entry::Occupied(NodeAccess::Storage(StorageNodeAccess { | 270 | 28.2k | trie: self, | 271 | 28.2k | node_index, | 272 | 28.2k | })), | 273 | | ExistingNodeInnerResult::Found { | 274 | 0 | node_index, | 275 | | has_storage_value: false, | 276 | 0 | } => Entry::Occupied(NodeAccess::Branch(BranchNodeAccess { | 277 | 0 | trie: self, | 278 | 0 | node_index, | 279 | 0 | })), | 280 | 29.7k | ExistingNodeInnerResult::NotFound { closest_ancestor } => Entry::Vacant(Vacant { | 281 | 29.7k | trie: self, | 282 | 29.7k | key, | 283 | 29.7k | closest_ancestor: closest_ancestor.map(|(i, _)| i), | 284 | | }), | 285 | | } | 286 | 58.0k | } |
_RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1b_NtNtB5_9trie_node17MerkleValueOutputEEE4nodeINtNtB5_6nibble14BytesToNibblesINtNtNtNtB1f_4iter8adapters6copied6CopiedINtNtNtB1f_5slice4iter4IterhEEEEB7_ Line | Count | Source | 261 | 3.04k | pub fn node<TKIter>(&'_ mut self, key: TKIter) -> Entry<'_, TUd, TKIter> | 262 | 3.04k | where | 263 | 3.04k | TKIter: Iterator<Item = Nibble> + Clone, | 264 | | { | 265 | 3.04k | match self.existing_node_inner(key.clone()) { | 266 | | ExistingNodeInnerResult::Found { | 267 | 531 | node_index, | 268 | | has_storage_value: true, | 269 | 531 | } => Entry::Occupied(NodeAccess::Storage(StorageNodeAccess { | 270 | 531 | trie: self, | 271 | 531 | node_index, | 272 | 531 | })), | 273 | | ExistingNodeInnerResult::Found { | 274 | 0 | node_index, | 275 | | has_storage_value: false, | 276 | 0 | } => Entry::Occupied(NodeAccess::Branch(BranchNodeAccess { | 277 | 0 | trie: self, | 278 | 0 | node_index, | 279 | 0 | })), | 280 | 2.51k | ExistingNodeInnerResult::NotFound { closest_ancestor } => Entry::Vacant(Vacant { | 281 | 2.51k | trie: self, | 282 | 2.51k | key, | 283 | 2.51k | closest_ancestor: closest_ancestor.map(|(i, _)| i), | 284 | | }), | 285 | | } | 286 | 3.04k | } |
_RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB5_16TrieEntryVersionEEIB1b_NtNtB5_9trie_node17MerkleValueOutputEEE4nodeINtNtB1Q_9into_iter8IntoIterNtNtB5_6nibble6NibbleEEB7_ Line | Count | Source | 261 | 366k | pub fn node<TKIter>(&'_ mut self, key: TKIter) -> Entry<'_, TUd, TKIter> | 262 | 366k | where | 263 | 366k | TKIter: Iterator<Item = Nibble> + Clone, | 264 | | { | 265 | 366k | match self.existing_node_inner(key.clone()) { | 266 | | ExistingNodeInnerResult::Found { | 267 | 65.1k | node_index, | 268 | | has_storage_value: true, | 269 | 65.1k | } => Entry::Occupied(NodeAccess::Storage(StorageNodeAccess { | 270 | 65.1k | trie: self, | 271 | 65.1k | node_index, | 272 | 65.1k | })), | 273 | | ExistingNodeInnerResult::Found { | 274 | 1.42k | node_index, | 275 | | has_storage_value: false, | 276 | 1.42k | } => Entry::Occupied(NodeAccess::Branch(BranchNodeAccess { | 277 | 1.42k | trie: self, | 278 | 1.42k | node_index, | 279 | 1.42k | })), | 280 | 300k | ExistingNodeInnerResult::NotFound { closest_ancestor } => Entry::Vacant(Vacant { | 281 | 300k | trie: self, | 282 | 300k | key, | 283 | 300k | closest_ancestor: closest_ancestor.map(|(i, _)| i), | 284 | | }), | 285 | | } | 286 | 366k | } |
_RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB5_16TrieEntryVersionEEIB1b_NtNtB5_9trie_node17MerkleValueOutputEEE4nodeINtNtB5_6nibble14BytesToNibblesINtNtNtNtB1f_4iter8adapters6copied6CopiedINtNtNtB1f_5slice4iter4IterhEEEEB7_ Line | Count | Source | 261 | 590k | pub fn node<TKIter>(&'_ mut self, key: TKIter) -> Entry<'_, TUd, TKIter> | 262 | 590k | where | 263 | 590k | TKIter: Iterator<Item = Nibble> + Clone, | 264 | | { | 265 | 590k | match self.existing_node_inner(key.clone()) { | 266 | | ExistingNodeInnerResult::Found { | 267 | 187k | node_index, | 268 | | has_storage_value: true, | 269 | 187k | } => Entry::Occupied(NodeAccess::Storage(StorageNodeAccess { | 270 | 187k | trie: self, | 271 | 187k | node_index, | 272 | 187k | })), | 273 | | ExistingNodeInnerResult::Found { | 274 | 66.6k | node_index, | 275 | | has_storage_value: false, | 276 | 66.6k | } => Entry::Occupied(NodeAccess::Branch(BranchNodeAccess { | 277 | 66.6k | trie: self, | 278 | 66.6k | node_index, | 279 | 66.6k | })), | 280 | 335k | ExistingNodeInnerResult::NotFound { closest_ancestor } => Entry::Vacant(Vacant { | 281 | 335k | trie: self, | 282 | 335k | key, | 283 | 335k | closest_ancestor: closest_ancestor.map(|(i, _)| i), | 284 | | }), | 285 | | } | 286 | 590k | } |
_RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureuE4nodeINtNtB5_6nibble14BytesToNibblesINtNtNtNtCs66KPHxksi63_4core4iter8adapters6copied6CopiedINtNtNtB1U_5slice4iter4IterhEEEEB7_ Line | Count | Source | 261 | 6.12k | pub fn node<TKIter>(&'_ mut self, key: TKIter) -> Entry<'_, TUd, TKIter> | 262 | 6.12k | where | 263 | 6.12k | TKIter: Iterator<Item = Nibble> + Clone, | 264 | | { | 265 | 6.12k | match self.existing_node_inner(key.clone()) { | 266 | | ExistingNodeInnerResult::Found { | 267 | 1.07k | node_index, | 268 | | has_storage_value: true, | 269 | 1.07k | } => Entry::Occupied(NodeAccess::Storage(StorageNodeAccess { | 270 | 1.07k | trie: self, | 271 | 1.07k | node_index, | 272 | 1.07k | })), | 273 | | ExistingNodeInnerResult::Found { | 274 | 0 | node_index, | 275 | | has_storage_value: false, | 276 | 0 | } => Entry::Occupied(NodeAccess::Branch(BranchNodeAccess { | 277 | 0 | trie: self, | 278 | 0 | node_index, | 279 | 0 | })), | 280 | 5.04k | ExistingNodeInnerResult::NotFound { closest_ancestor } => Entry::Vacant(Vacant { | 281 | 5.04k | trie: self, | 282 | 5.04k | key, | 283 | 5.04k | closest_ancestor: closest_ancestor.map(|(i, _)| i), | 284 | | }), | 285 | | } | 286 | 6.12k | } |
_RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureuE4nodeINtNtNtCs8Ty2CzGA6U3_5alloc3vec9into_iter8IntoIterNtNtB5_6nibble6NibbleEEB7_ Line | Count | Source | 261 | 889k | pub fn node<TKIter>(&'_ mut self, key: TKIter) -> Entry<'_, TUd, TKIter> | 262 | 889k | where | 263 | 889k | TKIter: Iterator<Item = Nibble> + Clone, | 264 | | { | 265 | 889k | match self.existing_node_inner(key.clone()) { | 266 | | ExistingNodeInnerResult::Found { | 267 | 50.6k | node_index, | 268 | | has_storage_value: true, | 269 | 50.6k | } => Entry::Occupied(NodeAccess::Storage(StorageNodeAccess { | 270 | 50.6k | trie: self, | 271 | 50.6k | node_index, | 272 | 50.6k | })), | 273 | | ExistingNodeInnerResult::Found { | 274 | 98.5k | node_index, | 275 | | has_storage_value: false, | 276 | 98.5k | } => Entry::Occupied(NodeAccess::Branch(BranchNodeAccess { | 277 | 98.5k | trie: self, | 278 | 98.5k | node_index, | 279 | 98.5k | })), | 280 | 740k | ExistingNodeInnerResult::NotFound { closest_ancestor } => Entry::Vacant(Vacant { | 281 | 740k | trie: self, | 282 | 740k | key, | 283 | 740k | closest_ancestor: closest_ancestor.map(|(i, _)| i), | 284 | | }), | 285 | | } | 286 | 889k | } |
_RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureuE4nodeINtNtNtNtCs66KPHxksi63_4core4iter8adapters6cloned6ClonedINtNtNtB1p_5slice4iter4IterNtNtB5_6nibble6NibbleEEEB7_ Line | Count | Source | 261 | 36 | pub fn node<TKIter>(&'_ mut self, key: TKIter) -> Entry<'_, TUd, TKIter> | 262 | 36 | where | 263 | 36 | TKIter: Iterator<Item = Nibble> + Clone, | 264 | | { | 265 | 36 | match self.existing_node_inner(key.clone()) { | 266 | | ExistingNodeInnerResult::Found { | 267 | 5 | node_index, | 268 | | has_storage_value: true, | 269 | 5 | } => Entry::Occupied(NodeAccess::Storage(StorageNodeAccess { | 270 | 5 | trie: self, | 271 | 5 | node_index, | 272 | 5 | })), | 273 | | ExistingNodeInnerResult::Found { | 274 | 1 | node_index, | 275 | | has_storage_value: false, | 276 | 1 | } => Entry::Occupied(NodeAccess::Branch(BranchNodeAccess { | 277 | 1 | trie: self, | 278 | 1 | node_index, | 279 | 1 | })), | 280 | 30 | ExistingNodeInnerResult::NotFound { closest_ancestor } => Entry::Vacant(Vacant { | 281 | 30 | trie: self, | 282 | 30 | key, | 283 | 30 | closest_ancestor: closest_ancestor.map(|(i, _)| i), | 284 | | }), | 285 | | } | 286 | 36 | } |
_RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureuE4nodeINtNtNtNtCs66KPHxksi63_4core4iter8adapters6copied6CopiedINtNtNtB1p_5slice4iter4IterNtNtB5_6nibble6NibbleEEEB7_ Line | Count | Source | 261 | 241k | pub fn node<TKIter>(&'_ mut self, key: TKIter) -> Entry<'_, TUd, TKIter> | 262 | 241k | where | 263 | 241k | TKIter: Iterator<Item = Nibble> + Clone, | 264 | | { | 265 | 241k | match self.existing_node_inner(key.clone()) { | 266 | | ExistingNodeInnerResult::Found { | 267 | 0 | node_index, | 268 | | has_storage_value: true, | 269 | 0 | } => Entry::Occupied(NodeAccess::Storage(StorageNodeAccess { | 270 | 0 | trie: self, | 271 | 0 | node_index, | 272 | 0 | })), | 273 | | ExistingNodeInnerResult::Found { | 274 | 0 | node_index, | 275 | | has_storage_value: false, | 276 | 0 | } => Entry::Occupied(NodeAccess::Branch(BranchNodeAccess { | 277 | 0 | trie: self, | 278 | 0 | node_index, | 279 | 0 | })), | 280 | 241k | ExistingNodeInnerResult::NotFound { closest_ancestor } => Entry::Vacant(Vacant { | 281 | 241k | trie: self, | 282 | 241k | key, | 283 | 241k | closest_ancestor: closest_ancestor.map(|(i, _)| i), | 284 | | }), | 285 | | } | 286 | 241k | } |
Unexecuted instantiation: _RINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB3_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1b_NtNtB5_9trie_node17MerkleValueOutputEEE4nodeINtNtB5_6nibble14BytesToNibblesINtNtNtNtB1f_4iter8adapters6copied6CopiedINtNtNtB1f_5slice4iter4IterhEEEECs4ISLcsFEGeP_6author Unexecuted instantiation: _RINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB3_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB5_12proof_encode4NodeEE4nodeINtNtNtNtB1e_4iter8adapters6copied6CopiedINtNtNtB1e_5slice4iter4IterNtNtB5_6nibble6NibbleEEEB7_ _RINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB3_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1b_NtNtB5_9trie_node17MerkleValueOutputEEE4nodeINtNtB5_6nibble14BytesToNibblesINtNtNtNtB1f_4iter8adapters6copied6CopiedINtNtNtB1f_5slice4iter4IterhEEEECs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 261 | 70 | pub fn node<TKIter>(&'_ mut self, key: TKIter) -> Entry<'_, TUd, TKIter> | 262 | 70 | where | 263 | 70 | TKIter: Iterator<Item = Nibble> + Clone, | 264 | | { | 265 | 70 | match self.existing_node_inner(key.clone()) { | 266 | | ExistingNodeInnerResult::Found { | 267 | 0 | node_index, | 268 | | has_storage_value: true, | 269 | 0 | } => Entry::Occupied(NodeAccess::Storage(StorageNodeAccess { | 270 | 0 | trie: self, | 271 | 0 | node_index, | 272 | 0 | })), | 273 | | ExistingNodeInnerResult::Found { | 274 | 0 | node_index, | 275 | | has_storage_value: false, | 276 | 0 | } => Entry::Occupied(NodeAccess::Branch(BranchNodeAccess { | 277 | 0 | trie: self, | 278 | 0 | node_index, | 279 | 0 | })), | 280 | 70 | ExistingNodeInnerResult::NotFound { closest_ancestor } => Entry::Vacant(Vacant { | 281 | 70 | trie: self, | 282 | 70 | key, | 283 | 70 | closest_ancestor: closest_ancestor.map(|(i, _)| i), | 284 | | }), | 285 | | } | 286 | 70 | } |
_RINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB3_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1b_NtNtB5_9trie_node17MerkleValueOutputEEE4nodeINtNtB5_6nibble14BytesToNibblesINtNtNtNtB1f_4iter8adapters6copied6CopiedINtNtNtB1f_5slice4iter4IterhEEEECs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 261 | 665 | pub fn node<TKIter>(&'_ mut self, key: TKIter) -> Entry<'_, TUd, TKIter> | 262 | 665 | where | 263 | 665 | TKIter: Iterator<Item = Nibble> + Clone, | 264 | | { | 265 | 665 | match self.existing_node_inner(key.clone()) { | 266 | | ExistingNodeInnerResult::Found { | 267 | 0 | node_index, | 268 | | has_storage_value: true, | 269 | 0 | } => Entry::Occupied(NodeAccess::Storage(StorageNodeAccess { | 270 | 0 | trie: self, | 271 | 0 | node_index, | 272 | 0 | })), | 273 | | ExistingNodeInnerResult::Found { | 274 | 0 | node_index, | 275 | | has_storage_value: false, | 276 | 0 | } => Entry::Occupied(NodeAccess::Branch(BranchNodeAccess { | 277 | 0 | trie: self, | 278 | 0 | node_index, | 279 | 0 | })), | 280 | 665 | ExistingNodeInnerResult::NotFound { closest_ancestor } => Entry::Vacant(Vacant { | 281 | 665 | trie: self, | 282 | 665 | key, | 283 | 665 | closest_ancestor: closest_ancestor.map(|(i, _)| i), | 284 | | }), | 285 | | } | 286 | 665 | } |
|
287 | | |
288 | | /// Returns the [`NodeIndex`] of the node with the given full key, if any is found. |
289 | 1.04M | pub fn node_by_full_key<TKIter>(&self, key: TKIter) -> Option<NodeIndex> |
290 | 1.04M | where |
291 | 1.04M | TKIter: Iterator<Item = Nibble> + Clone, |
292 | | { |
293 | 1.04M | match self.existing_node_inner(key) { |
294 | 209k | ExistingNodeInnerResult::Found { node_index, .. } => Some(NodeIndex(node_index)), |
295 | 839k | ExistingNodeInnerResult::NotFound { .. } => None, |
296 | | } |
297 | 1.04M | } _RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1b_NtNtB5_9trie_node17MerkleValueOutputEEE16node_by_full_keyINtNtB5_6nibble14BytesToNibblesINtNtNtNtB1f_4iter8adapters6copied6CopiedINtNtNtB1f_5slice4iter4IterhEEEEB7_ Line | Count | Source | 289 | 1.04M | pub fn node_by_full_key<TKIter>(&self, key: TKIter) -> Option<NodeIndex> | 290 | 1.04M | where | 291 | 1.04M | TKIter: Iterator<Item = Nibble> + Clone, | 292 | | { | 293 | 1.04M | match self.existing_node_inner(key) { | 294 | 209k | ExistingNodeInnerResult::Found { node_index, .. } => Some(NodeIndex(node_index)), | 295 | 839k | ExistingNodeInnerResult::NotFound { .. } => None, | 296 | | } | 297 | 1.04M | } |
Unexecuted instantiation: _RINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB3_13TrieStructurepE16node_by_full_keypEB7_ |
298 | | |
299 | | /// Returns `true` if the node with the given index is a storage node. Returns `false` if it |
300 | | /// is a branch node. |
301 | | /// |
302 | | /// # Panic |
303 | | /// |
304 | | /// Panics if the [`NodeIndex`] is invalid. |
305 | | /// |
306 | 2.52M | pub fn is_storage(&self, node: NodeIndex) -> bool { |
307 | 2.52M | self.nodes[node.0].has_storage_value |
308 | 2.52M | } _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureuE10is_storageB6_ Line | Count | Source | 306 | 2.52M | pub fn is_storage(&self, node: NodeIndex) -> bool { | 307 | 2.52M | self.nodes[node.0].has_storage_value | 308 | 2.52M | } |
Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructurepE10is_storageB6_ |
309 | | |
310 | | /// Returns the node with the given key, or `None` if no such node exists. |
311 | | /// |
312 | | /// This method is a shortcut for calling [`TrieStructure::node`] followed with |
313 | | /// [`Entry::into_occupied`]. |
314 | 0 | pub fn existing_node( |
315 | 0 | &'_ mut self, |
316 | 0 | key: impl Iterator<Item = Nibble> + Clone, |
317 | 0 | ) -> Option<NodeAccess<'_, TUd>> { |
318 | | if let ExistingNodeInnerResult::Found { |
319 | 0 | node_index, |
320 | 0 | has_storage_value, |
321 | 0 | } = self.existing_node_inner(key) |
322 | | { |
323 | 0 | Some(if has_storage_value { |
324 | 0 | NodeAccess::Storage(StorageNodeAccess { |
325 | 0 | trie: self, |
326 | 0 | node_index, |
327 | 0 | }) |
328 | | } else { |
329 | 0 | NodeAccess::Branch(BranchNodeAccess { |
330 | 0 | trie: self, |
331 | 0 | node_index, |
332 | 0 | }) |
333 | | }) |
334 | | } else { |
335 | 0 | None |
336 | | } |
337 | 0 | } Unexecuted instantiation: _RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructurepE13existing_nodepEB7_ Unexecuted instantiation: _RINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB3_13TrieStructurepE13existing_nodepEB7_ |
338 | | |
339 | | /// Inner implementation of [`TrieStructure::existing_node`]. Traverses the tree, trying to |
340 | | /// find a node whose key is `key`. |
341 | 3.21M | fn existing_node_inner<I: Iterator<Item = Nibble> + Clone>( |
342 | 3.21M | &self, |
343 | 3.21M | mut key: I, |
344 | 3.21M | ) -> ExistingNodeInnerResult<I> { |
345 | 3.21M | let mut current_index3.15M = match self.root_index { |
346 | 3.15M | Some(ri) => ri, |
347 | | None => { |
348 | 53.8k | return ExistingNodeInnerResult::NotFound { |
349 | 53.8k | closest_ancestor: None, |
350 | 53.8k | }; |
351 | | } |
352 | | }; |
353 | 3.15M | debug_assert!(self.nodes.get(current_index).unwrap().parent.is_none()); |
354 | | |
355 | 3.15M | let mut closest_ancestor = None; |
356 | | |
357 | | loop { |
358 | 5.98M | let current = self.nodes.get(current_index).unwrap(); |
359 | | |
360 | | // First, we must remove `current`'s partial key from `key`, making sure that they |
361 | | // match. |
362 | 5.98M | for nibble2.22M in current.partial_key.iter().cloned() { |
363 | 2.22M | if key.next() != Some(nibble) { |
364 | 449k | return ExistingNodeInnerResult::NotFound { closest_ancestor }; |
365 | 1.77M | } |
366 | | } |
367 | | |
368 | | // At this point, the tree traversal cursor (the `key` iterator) exactly matches |
369 | | // `current`. |
370 | 5.53M | closest_ancestor = Some((current_index, key.clone())); |
371 | | |
372 | | // If `key.next()` is `Some`, put it in `child_index`, otherwise return successfully. |
373 | 5.53M | let child_index4.81M = match key.next() { |
374 | 4.81M | Some(n) => n, |
375 | | None => { |
376 | 716k | return ExistingNodeInnerResult::Found { |
377 | 716k | node_index: current_index, |
378 | 716k | has_storage_value: current.has_storage_value, |
379 | 716k | }; |
380 | | } |
381 | | }; |
382 | | |
383 | 4.81M | if let Some(next_index2.82M ) = current.children[usize::from(u8::from(child_index))] { |
384 | 2.82M | current_index = next_index; |
385 | 2.82M | } else { |
386 | 1.99M | return ExistingNodeInnerResult::NotFound { closest_ancestor }; |
387 | | } |
388 | | } |
389 | 3.21M | } _RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB5_12proof_encode4NodeEE19existing_node_innerINtNtNtNtB1e_4iter8adapters6copied6CopiedINtNtNtB1e_5slice4iter4IterNtNtB5_6nibble6NibbleEEEB7_ Line | Count | Source | 341 | 58.0k | fn existing_node_inner<I: Iterator<Item = Nibble> + Clone>( | 342 | 58.0k | &self, | 343 | 58.0k | mut key: I, | 344 | 58.0k | ) -> ExistingNodeInnerResult<I> { | 345 | 58.0k | let mut current_index56.5k = match self.root_index { | 346 | 56.5k | Some(ri) => ri, | 347 | | None => { | 348 | 1.50k | return ExistingNodeInnerResult::NotFound { | 349 | 1.50k | closest_ancestor: None, | 350 | 1.50k | }; | 351 | | } | 352 | | }; | 353 | 56.5k | debug_assert!(self.nodes.get(current_index).unwrap().parent.is_none()); | 354 | | | 355 | 56.5k | let mut closest_ancestor = None; | 356 | | | 357 | | loop { | 358 | 86.4k | let current = self.nodes.get(current_index).unwrap(); | 359 | | | 360 | | // First, we must remove `current`'s partial key from `key`, making sure that they | 361 | | // match. | 362 | 86.4k | for nibble9.45k in current.partial_key.iter().cloned() { | 363 | 9.45k | if key.next() != Some(nibble) { | 364 | 7.45k | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 365 | 2.00k | } | 366 | | } | 367 | | | 368 | | // At this point, the tree traversal cursor (the `key` iterator) exactly matches | 369 | | // `current`. | 370 | 78.9k | closest_ancestor = Some((current_index, key.clone())); | 371 | | | 372 | | // If `key.next()` is `Some`, put it in `child_index`, otherwise return successfully. | 373 | 78.9k | let child_index50.7k = match key.next() { | 374 | 50.7k | Some(n) => n, | 375 | | None => { | 376 | 28.2k | return ExistingNodeInnerResult::Found { | 377 | 28.2k | node_index: current_index, | 378 | 28.2k | has_storage_value: current.has_storage_value, | 379 | 28.2k | }; | 380 | | } | 381 | | }; | 382 | | | 383 | 50.7k | if let Some(next_index29.9k ) = current.children[usize::from(u8::from(child_index))] { | 384 | 29.9k | current_index = next_index; | 385 | 29.9k | } else { | 386 | 20.7k | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 387 | | } | 388 | | } | 389 | 58.0k | } |
_RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1b_NtNtB5_9trie_node17MerkleValueOutputEEE19existing_node_innerINtNtB5_6nibble14BytesToNibblesINtNtNtNtB1f_4iter8adapters6copied6CopiedINtNtNtB1f_5slice4iter4IterhEEEEB7_ Line | Count | Source | 341 | 1.05M | fn existing_node_inner<I: Iterator<Item = Nibble> + Clone>( | 342 | 1.05M | &self, | 343 | 1.05M | mut key: I, | 344 | 1.05M | ) -> ExistingNodeInnerResult<I> { | 345 | 1.05M | let mut current_index1.05M = match self.root_index { | 346 | 1.05M | Some(ri) => ri, | 347 | | None => { | 348 | 1.02k | return ExistingNodeInnerResult::NotFound { | 349 | 1.02k | closest_ancestor: None, | 350 | 1.02k | }; | 351 | | } | 352 | | }; | 353 | 1.05M | debug_assert!(self.nodes.get(current_index).unwrap().parent.is_none()); | 354 | | | 355 | 1.05M | let mut closest_ancestor = None; | 356 | | | 357 | | loop { | 358 | 1.12M | let current = self.nodes.get(current_index).unwrap(); | 359 | | | 360 | | // First, we must remove `current`'s partial key from `key`, making sure that they | 361 | | // match. | 362 | 1.12M | for nibble73.9k in current.partial_key.iter().cloned() { | 363 | 73.9k | if key.next() != Some(nibble) { | 364 | 69.5k | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 365 | 4.36k | } | 366 | | } | 367 | | | 368 | | // At this point, the tree traversal cursor (the `key` iterator) exactly matches | 369 | | // `current`. | 370 | 1.05M | closest_ancestor = Some((current_index, key.clone())); | 371 | | | 372 | | // If `key.next()` is `Some`, put it in `child_index`, otherwise return successfully. | 373 | 1.05M | let child_index844k = match key.next() { | 374 | 844k | Some(n) => n, | 375 | | None => { | 376 | 209k | return ExistingNodeInnerResult::Found { | 377 | 209k | node_index: current_index, | 378 | 209k | has_storage_value: current.has_storage_value, | 379 | 209k | }; | 380 | | } | 381 | | }; | 382 | | | 383 | 844k | if let Some(next_index73.7k ) = current.children[usize::from(u8::from(child_index))] { | 384 | 73.7k | current_index = next_index; | 385 | 73.7k | } else { | 386 | 771k | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 387 | | } | 388 | | } | 389 | 1.05M | } |
_RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB5_16TrieEntryVersionEEIB1b_NtNtB5_9trie_node17MerkleValueOutputEEE19existing_node_innerINtNtB1Q_9into_iter8IntoIterNtNtB5_6nibble6NibbleEEB7_ Line | Count | Source | 341 | 366k | fn existing_node_inner<I: Iterator<Item = Nibble> + Clone>( | 342 | 366k | &self, | 343 | 366k | mut key: I, | 344 | 366k | ) -> ExistingNodeInnerResult<I> { | 345 | 366k | let mut current_index = match self.root_index { | 346 | 366k | Some(ri) => ri, | 347 | | None => { | 348 | 0 | return ExistingNodeInnerResult::NotFound { | 349 | 0 | closest_ancestor: None, | 350 | 0 | }; | 351 | | } | 352 | | }; | 353 | 366k | debug_assert!(self.nodes.get(current_index).unwrap().parent.is_none()); | 354 | | | 355 | 366k | let mut closest_ancestor = None; | 356 | | | 357 | | loop { | 358 | 441k | let current = self.nodes.get(current_index).unwrap(); | 359 | | | 360 | | // First, we must remove `current`'s partial key from `key`, making sure that they | 361 | | // match. | 362 | 441k | for nibble134k in current.partial_key.iter().cloned() { | 363 | 134k | if key.next() != Some(nibble) { | 364 | 37.5k | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 365 | 97.2k | } | 366 | | } | 367 | | | 368 | | // At this point, the tree traversal cursor (the `key` iterator) exactly matches | 369 | | // `current`. | 370 | 403k | closest_ancestor = Some((current_index, key.clone())); | 371 | | | 372 | | // If `key.next()` is `Some`, put it in `child_index`, otherwise return successfully. | 373 | 403k | let child_index336k = match key.next() { | 374 | 336k | Some(n) => n, | 375 | | None => { | 376 | 66.5k | return ExistingNodeInnerResult::Found { | 377 | 66.5k | node_index: current_index, | 378 | 66.5k | has_storage_value: current.has_storage_value, | 379 | 66.5k | }; | 380 | | } | 381 | | }; | 382 | | | 383 | 336k | if let Some(next_index74.1k ) = current.children[usize::from(u8::from(child_index))] { | 384 | 74.1k | current_index = next_index; | 385 | 74.1k | } else { | 386 | 262k | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 387 | | } | 388 | | } | 389 | 366k | } |
_RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB5_16TrieEntryVersionEEIB1b_NtNtB5_9trie_node17MerkleValueOutputEEE19existing_node_innerINtNtB5_6nibble14BytesToNibblesINtNtNtNtB1f_4iter8adapters6copied6CopiedINtNtNtB1f_5slice4iter4IterhEEEEB7_ Line | Count | Source | 341 | 590k | fn existing_node_inner<I: Iterator<Item = Nibble> + Clone>( | 342 | 590k | &self, | 343 | 590k | mut key: I, | 344 | 590k | ) -> ExistingNodeInnerResult<I> { | 345 | 590k | let mut current_index551k = match self.root_index { | 346 | 551k | Some(ri) => ri, | 347 | | None => { | 348 | 38.9k | return ExistingNodeInnerResult::NotFound { | 349 | 38.9k | closest_ancestor: None, | 350 | 38.9k | }; | 351 | | } | 352 | | }; | 353 | 551k | debug_assert!(self.nodes.get(current_index).unwrap().parent.is_none()); | 354 | | | 355 | 551k | let mut closest_ancestor = None; | 356 | | | 357 | | loop { | 358 | 621k | let current = self.nodes.get(current_index).unwrap(); | 359 | | | 360 | | // First, we must remove `current`'s partial key from `key`, making sure that they | 361 | | // match. | 362 | 621k | for nibble74.8k in current.partial_key.iter().cloned() { | 363 | 74.8k | if key.next() != Some(nibble) { | 364 | 70.6k | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 365 | 4.25k | } | 366 | | } | 367 | | | 368 | | // At this point, the tree traversal cursor (the `key` iterator) exactly matches | 369 | | // `current`. | 370 | 551k | closest_ancestor = Some((current_index, key.clone())); | 371 | | | 372 | | // If `key.next()` is `Some`, put it in `child_index`, otherwise return successfully. | 373 | 551k | let child_index296k = match key.next() { | 374 | 296k | Some(n) => n, | 375 | | None => { | 376 | 254k | return ExistingNodeInnerResult::Found { | 377 | 254k | node_index: current_index, | 378 | 254k | has_storage_value: current.has_storage_value, | 379 | 254k | }; | 380 | | } | 381 | | }; | 382 | | | 383 | 296k | if let Some(next_index70.7k ) = current.children[usize::from(u8::from(child_index))] { | 384 | 70.7k | current_index = next_index; | 385 | 70.7k | } else { | 386 | 226k | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 387 | | } | 388 | | } | 389 | 590k | } |
_RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureuE19existing_node_innerINtNtB5_6nibble14BytesToNibblesINtNtNtNtCs66KPHxksi63_4core4iter8adapters6copied6CopiedINtNtNtB2a_5slice4iter4IterhEEEEB7_ Line | Count | Source | 341 | 6.12k | fn existing_node_inner<I: Iterator<Item = Nibble> + Clone>( | 342 | 6.12k | &self, | 343 | 6.12k | mut key: I, | 344 | 6.12k | ) -> ExistingNodeInnerResult<I> { | 345 | 6.12k | let mut current_index4.07k = match self.root_index { | 346 | 4.07k | Some(ri) => ri, | 347 | | None => { | 348 | 2.04k | return ExistingNodeInnerResult::NotFound { | 349 | 2.04k | closest_ancestor: None, | 350 | 2.04k | }; | 351 | | } | 352 | | }; | 353 | 4.07k | debug_assert!(self.nodes.get(current_index).unwrap().parent.is_none()); | 354 | | | 355 | 4.07k | let mut closest_ancestor = None; | 356 | | | 357 | | loop { | 358 | 4.22k | let current = self.nodes.get(current_index).unwrap(); | 359 | | | 360 | | // First, we must remove `current`'s partial key from `key`, making sure that they | 361 | | // match. | 362 | 4.22k | for nibble157 in current.partial_key.iter().cloned() { | 363 | 157 | if key.next() != Some(nibble) { | 364 | 148 | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 365 | 9 | } | 366 | | } | 367 | | | 368 | | // At this point, the tree traversal cursor (the `key` iterator) exactly matches | 369 | | // `current`. | 370 | 4.08k | closest_ancestor = Some((current_index, key.clone())); | 371 | | | 372 | | // If `key.next()` is `Some`, put it in `child_index`, otherwise return successfully. | 373 | 4.08k | let child_index3.00k = match key.next() { | 374 | 3.00k | Some(n) => n, | 375 | | None => { | 376 | 1.07k | return ExistingNodeInnerResult::Found { | 377 | 1.07k | node_index: current_index, | 378 | 1.07k | has_storage_value: current.has_storage_value, | 379 | 1.07k | }; | 380 | | } | 381 | | }; | 382 | | | 383 | 3.00k | if let Some(next_index150 ) = current.children[usize::from(u8::from(child_index))] { | 384 | 150 | current_index = next_index; | 385 | 150 | } else { | 386 | 2.85k | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 387 | | } | 388 | | } | 389 | 6.12k | } |
_RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureuE19existing_node_innerINtNtNtCs8Ty2CzGA6U3_5alloc3vec9into_iter8IntoIterNtNtB5_6nibble6NibbleEEB7_ Line | Count | Source | 341 | 897k | fn existing_node_inner<I: Iterator<Item = Nibble> + Clone>( | 342 | 897k | &self, | 343 | 897k | mut key: I, | 344 | 897k | ) -> ExistingNodeInnerResult<I> { | 345 | 897k | let mut current_index891k = match self.root_index { | 346 | 891k | Some(ri) => ri, | 347 | | None => { | 348 | 6.19k | return ExistingNodeInnerResult::NotFound { | 349 | 6.19k | closest_ancestor: None, | 350 | 6.19k | }; | 351 | | } | 352 | | }; | 353 | 891k | debug_assert!(self.nodes.get(current_index).unwrap().parent.is_none()); | 354 | | | 355 | 891k | let mut closest_ancestor = None; | 356 | | | 357 | | loop { | 358 | 3.05M | let current = self.nodes.get(current_index).unwrap(); | 359 | | | 360 | | // First, we must remove `current`'s partial key from `key`, making sure that they | 361 | | // match. | 362 | 3.05M | for nibble1.65M in current.partial_key.iter().cloned() { | 363 | 1.65M | if key.next() != Some(nibble) { | 364 | 250k | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 365 | 1.39M | } | 366 | | } | 367 | | | 368 | | // At this point, the tree traversal cursor (the `key` iterator) exactly matches | 369 | | // `current`. | 370 | 2.80M | closest_ancestor = Some((current_index, key.clone())); | 371 | | | 372 | | // If `key.next()` is `Some`, put it in `child_index`, otherwise return successfully. | 373 | 2.80M | let child_index2.65M = match key.next() { | 374 | 2.65M | Some(n) => n, | 375 | | None => { | 376 | 156k | return ExistingNodeInnerResult::Found { | 377 | 156k | node_index: current_index, | 378 | 156k | has_storage_value: current.has_storage_value, | 379 | 156k | }; | 380 | | } | 381 | | }; | 382 | | | 383 | 2.65M | if let Some(next_index2.16M ) = current.children[usize::from(u8::from(child_index))] { | 384 | 2.16M | current_index = next_index; | 385 | 2.16M | } else { | 386 | 484k | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 387 | | } | 388 | | } | 389 | 897k | } |
_RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureuE19existing_node_innerINtNtNtNtCs66KPHxksi63_4core4iter8adapters6cloned6ClonedINtNtNtB1F_5slice4iter4IterNtNtB5_6nibble6NibbleEEEB7_ Line | Count | Source | 341 | 41 | fn existing_node_inner<I: Iterator<Item = Nibble> + Clone>( | 342 | 41 | &self, | 343 | 41 | mut key: I, | 344 | 41 | ) -> ExistingNodeInnerResult<I> { | 345 | 41 | let mut current_index30 = match self.root_index { | 346 | 30 | Some(ri) => ri, | 347 | | None => { | 348 | 11 | return ExistingNodeInnerResult::NotFound { | 349 | 11 | closest_ancestor: None, | 350 | 11 | }; | 351 | | } | 352 | | }; | 353 | 30 | debug_assert!(self.nodes.get(current_index).unwrap().parent.is_none()); | 354 | | | 355 | 30 | let mut closest_ancestor = None; | 356 | | | 357 | | loop { | 358 | 42 | let current = self.nodes.get(current_index).unwrap(); | 359 | | | 360 | | // First, we must remove `current`'s partial key from `key`, making sure that they | 361 | | // match. | 362 | 68 | for nibble in current.partial_key.iter()42 .cloned42 () { | 363 | 68 | if key.next() != Some(nibble) { | 364 | 10 | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 365 | 58 | } | 366 | | } | 367 | | | 368 | | // At this point, the tree traversal cursor (the `key` iterator) exactly matches | 369 | | // `current`. | 370 | 32 | closest_ancestor = Some((current_index, key.clone())); | 371 | | | 372 | | // If `key.next()` is `Some`, put it in `child_index`, otherwise return successfully. | 373 | 32 | let child_index23 = match key.next() { | 374 | 23 | Some(n) => n, | 375 | | None => { | 376 | 9 | return ExistingNodeInnerResult::Found { | 377 | 9 | node_index: current_index, | 378 | 9 | has_storage_value: current.has_storage_value, | 379 | 9 | }; | 380 | | } | 381 | | }; | 382 | | | 383 | 23 | if let Some(next_index12 ) = current.children[usize::from(u8::from(child_index))] { | 384 | 12 | current_index = next_index; | 385 | 12 | } else { | 386 | 11 | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 387 | | } | 388 | | } | 389 | 41 | } |
_RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureuE19existing_node_innerINtNtNtNtCs66KPHxksi63_4core4iter8adapters6copied6CopiedINtNtNtB1F_5slice4iter4IterNtNtB5_6nibble6NibbleEEEB7_ Line | Count | Source | 341 | 241k | fn existing_node_inner<I: Iterator<Item = Nibble> + Clone>( | 342 | 241k | &self, | 343 | 241k | mut key: I, | 344 | 241k | ) -> ExistingNodeInnerResult<I> { | 345 | 241k | let mut current_index237k = match self.root_index { | 346 | 237k | Some(ri) => ri, | 347 | | None => { | 348 | 4.09k | return ExistingNodeInnerResult::NotFound { | 349 | 4.09k | closest_ancestor: None, | 350 | 4.09k | }; | 351 | | } | 352 | | }; | 353 | 237k | debug_assert!(self.nodes.get(current_index).unwrap().parent.is_none()); | 354 | | | 355 | 237k | let mut closest_ancestor = None; | 356 | | | 357 | | loop { | 358 | 644k | let current = self.nodes.get(current_index).unwrap(); | 359 | | | 360 | | // First, we must remove `current`'s partial key from `key`, making sure that they | 361 | | // match. | 362 | 644k | for nibble257k in current.partial_key.iter().cloned() { | 363 | 257k | if key.next() != Some(nibble) { | 364 | 13.5k | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 365 | 243k | } | 366 | | } | 367 | | | 368 | | // At this point, the tree traversal cursor (the `key` iterator) exactly matches | 369 | | // `current`. | 370 | 630k | closest_ancestor = Some((current_index, key.clone())); | 371 | | | 372 | | // If `key.next()` is `Some`, put it in `child_index`, otherwise return successfully. | 373 | 630k | let child_index = match key.next() { | 374 | 630k | Some(n) => n, | 375 | | None => { | 376 | 0 | return ExistingNodeInnerResult::Found { | 377 | 0 | node_index: current_index, | 378 | 0 | has_storage_value: current.has_storage_value, | 379 | 0 | }; | 380 | | } | 381 | | }; | 382 | | | 383 | 630k | if let Some(next_index406k ) = current.children[usize::from(u8::from(child_index))] { | 384 | 406k | current_index = next_index; | 385 | 406k | } else { | 386 | 224k | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 387 | | } | 388 | | } | 389 | 241k | } |
Unexecuted instantiation: _RINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB3_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1b_NtNtB5_9trie_node17MerkleValueOutputEEE19existing_node_innerINtNtB5_6nibble14BytesToNibblesINtNtNtNtB1f_4iter8adapters6copied6CopiedINtNtNtB1f_5slice4iter4IterhEEEECs4ISLcsFEGeP_6author Unexecuted instantiation: _RINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB3_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB5_12proof_encode4NodeEE19existing_node_innerINtNtNtNtB1e_4iter8adapters6copied6CopiedINtNtNtB1e_5slice4iter4IterNtNtB5_6nibble6NibbleEEEB7_ _RINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB3_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1b_NtNtB5_9trie_node17MerkleValueOutputEEE19existing_node_innerINtNtB5_6nibble14BytesToNibblesINtNtNtNtB1f_4iter8adapters6copied6CopiedINtNtNtB1f_5slice4iter4IterhEEEECs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 341 | 70 | fn existing_node_inner<I: Iterator<Item = Nibble> + Clone>( | 342 | 70 | &self, | 343 | 70 | mut key: I, | 344 | 70 | ) -> ExistingNodeInnerResult<I> { | 345 | 70 | let mut current_index68 = match self.root_index { | 346 | 68 | Some(ri) => ri, | 347 | | None => { | 348 | 2 | return ExistingNodeInnerResult::NotFound { | 349 | 2 | closest_ancestor: None, | 350 | 2 | }; | 351 | | } | 352 | | }; | 353 | 68 | debug_assert!(self.nodes.get(current_index).unwrap().parent.is_none()); | 354 | | | 355 | 68 | let mut closest_ancestor = None; | 356 | | | 357 | | loop { | 358 | 158 | let current = self.nodes.get(current_index).unwrap(); | 359 | | | 360 | | // First, we must remove `current`'s partial key from `key`, making sure that they | 361 | | // match. | 362 | 2.13k | for nibble in current.partial_key.iter()158 .cloned158 () { | 363 | 2.13k | if key.next() != Some(nibble) { | 364 | 26 | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 365 | 2.11k | } | 366 | | } | 367 | | | 368 | | // At this point, the tree traversal cursor (the `key` iterator) exactly matches | 369 | | // `current`. | 370 | 132 | closest_ancestor = Some((current_index, key.clone())); | 371 | | | 372 | | // If `key.next()` is `Some`, put it in `child_index`, otherwise return successfully. | 373 | 132 | let child_index = match key.next() { | 374 | 132 | Some(n) => n, | 375 | | None => { | 376 | 0 | return ExistingNodeInnerResult::Found { | 377 | 0 | node_index: current_index, | 378 | 0 | has_storage_value: current.has_storage_value, | 379 | 0 | }; | 380 | | } | 381 | | }; | 382 | | | 383 | 132 | if let Some(next_index90 ) = current.children[usize::from(u8::from(child_index))] { | 384 | 90 | current_index = next_index; | 385 | 90 | } else { | 386 | 42 | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 387 | | } | 388 | | } | 389 | 70 | } |
_RINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB3_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1b_NtNtB5_9trie_node17MerkleValueOutputEEE19existing_node_innerINtNtB5_6nibble14BytesToNibblesINtNtNtNtB1f_4iter8adapters6copied6CopiedINtNtNtB1f_5slice4iter4IterhEEEECs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 341 | 665 | fn existing_node_inner<I: Iterator<Item = Nibble> + Clone>( | 342 | 665 | &self, | 343 | 665 | mut key: I, | 344 | 665 | ) -> ExistingNodeInnerResult<I> { | 345 | 665 | let mut current_index646 = match self.root_index { | 346 | 646 | Some(ri) => ri, | 347 | | None => { | 348 | 19 | return ExistingNodeInnerResult::NotFound { | 349 | 19 | closest_ancestor: None, | 350 | 19 | }; | 351 | | } | 352 | | }; | 353 | 646 | debug_assert!(self.nodes.get(current_index).unwrap().parent.is_none()); | 354 | | | 355 | 646 | let mut closest_ancestor = None; | 356 | | | 357 | | loop { | 358 | 1.50k | let current = self.nodes.get(current_index).unwrap(); | 359 | | | 360 | | // First, we must remove `current`'s partial key from `key`, making sure that they | 361 | | // match. | 362 | 20.2k | for nibble in current.partial_key.iter()1.50k .cloned1.50k () { | 363 | 20.2k | if key.next() != Some(nibble) { | 364 | 247 | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 365 | 20.0k | } | 366 | | } | 367 | | | 368 | | // At this point, the tree traversal cursor (the `key` iterator) exactly matches | 369 | | // `current`. | 370 | 1.25k | closest_ancestor = Some((current_index, key.clone())); | 371 | | | 372 | | // If `key.next()` is `Some`, put it in `child_index`, otherwise return successfully. | 373 | 1.25k | let child_index = match key.next() { | 374 | 1.25k | Some(n) => n, | 375 | | None => { | 376 | 0 | return ExistingNodeInnerResult::Found { | 377 | 0 | node_index: current_index, | 378 | 0 | has_storage_value: current.has_storage_value, | 379 | 0 | }; | 380 | | } | 381 | | }; | 382 | | | 383 | 1.25k | if let Some(next_index855 ) = current.children[usize::from(u8::from(child_index))] { | 384 | 855 | current_index = next_index; | 385 | 855 | } else { | 386 | 399 | return ExistingNodeInnerResult::NotFound { closest_ancestor }; | 387 | | } | 388 | | } | 389 | 665 | } |
|
390 | | |
391 | | /// Removes all nodes whose key starts with the given prefix. |
392 | | /// |
393 | | /// Returns the closest ancestors to the nodes that have been removed, or `None` if that |
394 | | /// closest ancestor is not a descendant of the new trie root. |
395 | 8.31k | pub fn remove_prefix( |
396 | 8.31k | &'_ mut self, |
397 | 8.31k | prefix: impl Iterator<Item = Nibble> + Clone, |
398 | 8.31k | ) -> Option<NodeAccess<'_, TUd>> { |
399 | | // `ancestor` is the node that doesn't have the prefix but is the common ancestor of all |
400 | | // the nodes to remove. |
401 | 8.31k | let (ancestor_index7.46k , ancestor_child_nibble7.46k ) = match self.existing_node_inner(prefix.clone()) |
402 | | { |
403 | 7.09k | ExistingNodeInnerResult::Found { node_index, .. } => { |
404 | 7.09k | match self.nodes.get(node_index).unwrap().parent { |
405 | 6.89k | Some(p) => p, |
406 | | None => { |
407 | | // There is no parent, meaning that the trie is empty or the root of trie |
408 | | // is a node with the requested prefix. Simply clear the entire trie. |
409 | 197 | self.nodes.clear(); |
410 | 197 | self.root_index = None; |
411 | 197 | return None; |
412 | | } |
413 | | } |
414 | | } |
415 | | ExistingNodeInnerResult::NotFound { |
416 | | closest_ancestor: None, |
417 | | } => { |
418 | | // The trie is empty, or the key of the root node of the trie doesn't start with |
419 | | // the requested prefix, or the key of the root node of the trie starts with the |
420 | | // requested prefix. |
421 | | // If the trie is empty. then there is nothing to do and we return `None`. |
422 | 55 | let root_index34 = self.root_index?21 ; |
423 | | |
424 | | // Compare root key with the prefix. |
425 | 34 | if !self.nodes[root_index] |
426 | 34 | .partial_key |
427 | 34 | .iter() |
428 | 34 | .zip(prefix) |
429 | 101 | .all34 (|(a, b)| *a == b) _RNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureuE13remove_prefixINtNtNtCs8Ty2CzGA6U3_5alloc3vec9into_iter8IntoIterNtNtB7_6nibble6NibbleEE0B9_ Line | Count | Source | 429 | 98 | .all(|(a, b)| *a == b) |
_RNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureuE13remove_prefixINtNtNtNtCs66KPHxksi63_4core4iter8adapters6cloned6ClonedINtNtNtB1B_5slice4iter4IterNtNtB7_6nibble6NibbleEEE0B9_ Line | Count | Source | 429 | 3 | .all(|(a, b)| *a == b) |
Unexecuted instantiation: _RNCINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13TrieStructurepE13remove_prefixpE0B9_ |
430 | | { |
431 | | // Root node key doesn't match the prefix. Nothing to do. |
432 | 22 | return None; |
433 | 12 | } |
434 | | |
435 | | // Root node key starts with the requested prefix. Clear the entire trie. |
436 | 12 | self.nodes.clear(); |
437 | 12 | self.root_index = None; |
438 | 12 | return None; |
439 | | } |
440 | | ExistingNodeInnerResult::NotFound { |
441 | 1.16k | closest_ancestor: Some((ancestor, mut prefix_remain)), |
442 | | } => { |
443 | | // It is possible that there is simply no node at all with the given prefix, in |
444 | | // which case there is closest ancestor but nothing to clear. |
445 | | |
446 | 1.16k | let child_index = prefix_remain.next().unwrap(); |
447 | | |
448 | | // First possibility in case there is no node with the given prefix: the ancestor |
449 | | // simply has no child in the direction we want. For example, ancestor is |
450 | | // `[1, 2]`, there is a node at `[1, 2, 8]`, and we want to clear `[1, 2, 5]`. |
451 | 708 | let direct_child = if let Some(c) = |
452 | 1.16k | self.nodes[ancestor].children[usize::from(u8::from(child_index))] |
453 | | { |
454 | 708 | c |
455 | | } else { |
456 | 455 | return Some(self.node_by_index_inner(ancestor).unwrap()); |
457 | | }; |
458 | | |
459 | | // Second possibility in case there is no node with the given prefix: the ancestor |
460 | | // has a child in the direction we want, but this child doesn't have the prefix |
461 | | // that we want. For example, ancestor is `[1, 2]`, there is a node at |
462 | | // `[1, 2, 3, 8]`, and we want to clear `[1, 2, 3, 6]`. |
463 | | // TODO: this seems sub-optimal |
464 | 708 | if !self.nodes[direct_child] |
465 | 708 | .partial_key |
466 | 708 | .iter() |
467 | 708 | .zip(prefix_remain) |
468 | 1.44k | .all708 (|(a, b)| *a == b) _RNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureuE13remove_prefixINtNtNtCs8Ty2CzGA6U3_5alloc3vec9into_iter8IntoIterNtNtB7_6nibble6NibbleEEs_0B9_ Line | Count | Source | 468 | 1.44k | .all(|(a, b)| *a == b) |
Unexecuted instantiation: _RNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureuE13remove_prefixINtNtNtNtCs66KPHxksi63_4core4iter8adapters6cloned6ClonedINtNtNtB1B_5slice4iter4IterNtNtB7_6nibble6NibbleEEEs_0B9_ Unexecuted instantiation: _RNCINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13TrieStructurepE13remove_prefixpEs_0B9_ |
469 | | { |
470 | 143 | return Some(self.node_by_index_inner(ancestor).unwrap()); |
471 | 565 | } |
472 | | |
473 | 565 | (ancestor, child_index) |
474 | | } |
475 | | }; |
476 | | |
477 | | // Removes all the descendants of `ancestor` through `ancestor_child_nibble`. |
478 | | { |
479 | | // TODO: this performs allocations, do we care? |
480 | 7.46k | let first_remove_index = self |
481 | 7.46k | .nodes |
482 | 7.46k | .get_mut(ancestor_index) |
483 | 7.46k | .unwrap() |
484 | 7.46k | .children |
485 | 7.46k | .get_mut(usize::from(u8::from(ancestor_child_nibble))) |
486 | 7.46k | .unwrap() |
487 | 7.46k | .take() |
488 | 7.46k | .unwrap(); |
489 | | |
490 | 7.46k | let mut to_remove = vec![first_remove_index]; |
491 | 26.0k | while !to_remove.is_empty() { |
492 | 18.5k | let mut next_to_remove = Vec::new(); |
493 | 54.8k | for node_index in to_remove18.5k .drain18.5k (..18.5k ) { |
494 | 54.8k | let node = self.nodes.remove(node_index); |
495 | 54.8k | next_to_remove.extend(node.children.iter().filter_map(|n| *n)); |
496 | | } |
497 | 18.5k | mem::swap(&mut to_remove, &mut next_to_remove); |
498 | | } |
499 | | } |
500 | | |
501 | | // If `ancestor` is a branch node with only one child (had two children before this |
502 | | // function call, but we removed one earlier), we have to remove it from the tree as well. |
503 | | // If this is the case, `actual_ancestor_index` will be equal to `ancestor`'s parent. |
504 | | // Otherwise it is set to `ancestor_index`. |
505 | 7.46k | let actual_ancestor_index = { |
506 | 7.46k | let ancestor = self.nodes.get_mut(ancestor_index).unwrap(); |
507 | 7.46k | debug_assert!( |
508 | 25.4k | ancestor.has_storage_value7.46k || ancestor.children.iter()3.93k .any3.93k (|c| c.is_some()) _RNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureuE13remove_prefixINtNtNtCs8Ty2CzGA6U3_5alloc3vec9into_iter8IntoIterNtNtB7_6nibble6NibbleEEs5_0B9_ Line | Count | Source | 508 | 25.4k | ancestor.has_storage_value || ancestor.children.iter().any(|c| c.is_some()) |
Unexecuted instantiation: _RNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureuE13remove_prefixINtNtNtNtCs66KPHxksi63_4core4iter8adapters6cloned6ClonedINtNtNtB1B_5slice4iter4IterNtNtB7_6nibble6NibbleEEEs5_0B9_ Unexecuted instantiation: _RNCINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13TrieStructurepE13remove_prefixpEs5_0B9_ |
509 | | ); |
510 | 7.46k | if !ancestor.has_storage_value |
511 | 62.9k | && ancestor.children3.93k .iter3.93k ().filter3.93k (|c| c.is_some()).count3.93k () == 1 _RNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureuE13remove_prefixINtNtNtCs8Ty2CzGA6U3_5alloc3vec9into_iter8IntoIterNtNtB7_6nibble6NibbleEEs1_0B9_ Line | Count | Source | 511 | 62.9k | && ancestor.children.iter().filter(|c| c.is_some()).count() == 1 |
Unexecuted instantiation: _RNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureuE13remove_prefixINtNtNtNtCs66KPHxksi63_4core4iter8adapters6cloned6ClonedINtNtNtB1B_5slice4iter4IterNtNtB7_6nibble6NibbleEEEs1_0B9_ Unexecuted instantiation: _RNCINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13TrieStructurepE13remove_prefixpEs1_0B9_ |
512 | | { |
513 | 1.96k | let ancestor = self.nodes.remove(ancestor_index); |
514 | 1.96k | let sibling_node_index: usize = ancestor.children.iter().find_map(|c| *c).unwrap(); |
515 | | |
516 | | // Update the sibling to point to the ancestor's parent. |
517 | | { |
518 | 1.96k | let sibling = self.nodes.get_mut(sibling_node_index).unwrap(); |
519 | 1.96k | debug_assert_eq!(sibling.parent.as_ref().unwrap().0, ancestor_index); |
520 | 1.96k | insert_front( |
521 | 1.96k | &mut sibling.partial_key, |
522 | 1.96k | ancestor.partial_key, |
523 | 1.96k | sibling.parent.unwrap().1, |
524 | | ); |
525 | 1.96k | sibling.parent = ancestor.parent; |
526 | | } |
527 | | |
528 | | // Update the ancestor's parent to point to the sibling. |
529 | 1.96k | if let Some((ancestor_parent_index1.65k , parent_to_sibling_index1.65k )) = ancestor.parent { |
530 | | // Update the ancestory's parent to point to the sibling. |
531 | 1.65k | let ancestor_parent = self.nodes.get_mut(ancestor_parent_index).unwrap(); |
532 | 1.65k | debug_assert_eq!( |
533 | 1.65k | ancestor_parent.children[usize::from(u8::from(parent_to_sibling_index))], |
534 | 1.65k | Some(ancestor_index) |
535 | | ); |
536 | 1.65k | ancestor_parent.children[usize::from(u8::from(parent_to_sibling_index))] = |
537 | 1.65k | Some(sibling_node_index); |
538 | | } else { |
539 | 305 | debug_assert_eq!(self.root_index, Some(ancestor_index)); |
540 | 305 | self.root_index = Some(sibling_node_index); |
541 | | } |
542 | | |
543 | 1.96k | ancestor.parent.map(|(idx, _)| idx) |
544 | | } else { |
545 | 5.50k | Some(ancestor_index) |
546 | | } |
547 | | }; |
548 | | |
549 | | // Return value of the function. |
550 | 7.46k | actual_ancestor_index.map(move |idx| self7.15k .node_by_index_inner7.15k (idx7.15k ).unwrap7.15k ()) _RNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureuE13remove_prefixINtNtNtCs8Ty2CzGA6U3_5alloc3vec9into_iter8IntoIterNtNtB7_6nibble6NibbleEEs4_0B9_ Line | Count | Source | 550 | 7.15k | actual_ancestor_index.map(move |idx| self.node_by_index_inner(idx).unwrap()) |
_RNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureuE13remove_prefixINtNtNtNtCs66KPHxksi63_4core4iter8adapters6cloned6ClonedINtNtNtB1B_5slice4iter4IterNtNtB7_6nibble6NibbleEEEs4_0B9_ Line | Count | Source | 550 | 2 | actual_ancestor_index.map(move |idx| self.node_by_index_inner(idx).unwrap()) |
Unexecuted instantiation: _RNCINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13TrieStructurepE13remove_prefixpEs4_0B9_ |
551 | 8.31k | } _RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureuE13remove_prefixINtNtNtCs8Ty2CzGA6U3_5alloc3vec9into_iter8IntoIterNtNtB5_6nibble6NibbleEEB7_ Line | Count | Source | 395 | 8.30k | pub fn remove_prefix( | 396 | 8.30k | &'_ mut self, | 397 | 8.30k | prefix: impl Iterator<Item = Nibble> + Clone, | 398 | 8.30k | ) -> Option<NodeAccess<'_, TUd>> { | 399 | | // `ancestor` is the node that doesn't have the prefix but is the common ancestor of all | 400 | | // the nodes to remove. | 401 | 8.30k | let (ancestor_index7.46k , ancestor_child_nibble7.46k ) = match self.existing_node_inner(prefix.clone()) | 402 | | { | 403 | 7.09k | ExistingNodeInnerResult::Found { node_index, .. } => { | 404 | 7.09k | match self.nodes.get(node_index).unwrap().parent { | 405 | 6.89k | Some(p) => p, | 406 | | None => { | 407 | | // There is no parent, meaning that the trie is empty or the root of trie | 408 | | // is a node with the requested prefix. Simply clear the entire trie. | 409 | 196 | self.nodes.clear(); | 410 | 196 | self.root_index = None; | 411 | 196 | return None; | 412 | | } | 413 | | } | 414 | | } | 415 | | ExistingNodeInnerResult::NotFound { | 416 | | closest_ancestor: None, | 417 | | } => { | 418 | | // The trie is empty, or the key of the root node of the trie doesn't start with | 419 | | // the requested prefix, or the key of the root node of the trie starts with the | 420 | | // requested prefix. | 421 | | // If the trie is empty. then there is nothing to do and we return `None`. | 422 | 54 | let root_index33 = self.root_index?21 ; | 423 | | | 424 | | // Compare root key with the prefix. | 425 | 33 | if !self.nodes[root_index] | 426 | 33 | .partial_key | 427 | 33 | .iter() | 428 | 33 | .zip(prefix) | 429 | 33 | .all(|(a, b)| *a == b) | 430 | | { | 431 | | // Root node key doesn't match the prefix. Nothing to do. | 432 | 21 | return None; | 433 | 12 | } | 434 | | | 435 | | // Root node key starts with the requested prefix. Clear the entire trie. | 436 | 12 | self.nodes.clear(); | 437 | 12 | self.root_index = None; | 438 | 12 | return None; | 439 | | } | 440 | | ExistingNodeInnerResult::NotFound { | 441 | 1.16k | closest_ancestor: Some((ancestor, mut prefix_remain)), | 442 | | } => { | 443 | | // It is possible that there is simply no node at all with the given prefix, in | 444 | | // which case there is closest ancestor but nothing to clear. | 445 | | | 446 | 1.16k | let child_index = prefix_remain.next().unwrap(); | 447 | | | 448 | | // First possibility in case there is no node with the given prefix: the ancestor | 449 | | // simply has no child in the direction we want. For example, ancestor is | 450 | | // `[1, 2]`, there is a node at `[1, 2, 8]`, and we want to clear `[1, 2, 5]`. | 451 | 708 | let direct_child = if let Some(c) = | 452 | 1.16k | self.nodes[ancestor].children[usize::from(u8::from(child_index))] | 453 | | { | 454 | 708 | c | 455 | | } else { | 456 | 454 | return Some(self.node_by_index_inner(ancestor).unwrap()); | 457 | | }; | 458 | | | 459 | | // Second possibility in case there is no node with the given prefix: the ancestor | 460 | | // has a child in the direction we want, but this child doesn't have the prefix | 461 | | // that we want. For example, ancestor is `[1, 2]`, there is a node at | 462 | | // `[1, 2, 3, 8]`, and we want to clear `[1, 2, 3, 6]`. | 463 | | // TODO: this seems sub-optimal | 464 | 708 | if !self.nodes[direct_child] | 465 | 708 | .partial_key | 466 | 708 | .iter() | 467 | 708 | .zip(prefix_remain) | 468 | 708 | .all(|(a, b)| *a == b) | 469 | | { | 470 | 143 | return Some(self.node_by_index_inner(ancestor).unwrap()); | 471 | 565 | } | 472 | | | 473 | 565 | (ancestor, child_index) | 474 | | } | 475 | | }; | 476 | | | 477 | | // Removes all the descendants of `ancestor` through `ancestor_child_nibble`. | 478 | | { | 479 | | // TODO: this performs allocations, do we care? | 480 | 7.46k | let first_remove_index = self | 481 | 7.46k | .nodes | 482 | 7.46k | .get_mut(ancestor_index) | 483 | 7.46k | .unwrap() | 484 | 7.46k | .children | 485 | 7.46k | .get_mut(usize::from(u8::from(ancestor_child_nibble))) | 486 | 7.46k | .unwrap() | 487 | 7.46k | .take() | 488 | 7.46k | .unwrap(); | 489 | | | 490 | 7.46k | let mut to_remove = vec![first_remove_index]; | 491 | 26.0k | while !to_remove.is_empty() { | 492 | 18.5k | let mut next_to_remove = Vec::new(); | 493 | 54.8k | for node_index in to_remove18.5k .drain18.5k (..18.5k ) { | 494 | 54.8k | let node = self.nodes.remove(node_index); | 495 | 54.8k | next_to_remove.extend(node.children.iter().filter_map(|n| *n)); | 496 | | } | 497 | 18.5k | mem::swap(&mut to_remove, &mut next_to_remove); | 498 | | } | 499 | | } | 500 | | | 501 | | // If `ancestor` is a branch node with only one child (had two children before this | 502 | | // function call, but we removed one earlier), we have to remove it from the tree as well. | 503 | | // If this is the case, `actual_ancestor_index` will be equal to `ancestor`'s parent. | 504 | | // Otherwise it is set to `ancestor_index`. | 505 | 7.46k | let actual_ancestor_index = { | 506 | 7.46k | let ancestor = self.nodes.get_mut(ancestor_index).unwrap(); | 507 | 7.46k | debug_assert!( | 508 | 7.46k | ancestor.has_storage_value || ancestor.children.iter()3.93k .any3.93k (|c| c.is_some()) | 509 | | ); | 510 | 7.46k | if !ancestor.has_storage_value | 511 | 3.93k | && ancestor.children.iter().filter(|c| c.is_some()).count() == 1 | 512 | | { | 513 | 1.96k | let ancestor = self.nodes.remove(ancestor_index); | 514 | 1.96k | let sibling_node_index: usize = ancestor.children.iter().find_map(|c| *c).unwrap(); | 515 | | | 516 | | // Update the sibling to point to the ancestor's parent. | 517 | | { | 518 | 1.96k | let sibling = self.nodes.get_mut(sibling_node_index).unwrap(); | 519 | 1.96k | debug_assert_eq!(sibling.parent.as_ref().unwrap().0, ancestor_index); | 520 | 1.96k | insert_front( | 521 | 1.96k | &mut sibling.partial_key, | 522 | 1.96k | ancestor.partial_key, | 523 | 1.96k | sibling.parent.unwrap().1, | 524 | | ); | 525 | 1.96k | sibling.parent = ancestor.parent; | 526 | | } | 527 | | | 528 | | // Update the ancestor's parent to point to the sibling. | 529 | 1.96k | if let Some((ancestor_parent_index1.65k , parent_to_sibling_index1.65k )) = ancestor.parent { | 530 | | // Update the ancestory's parent to point to the sibling. | 531 | 1.65k | let ancestor_parent = self.nodes.get_mut(ancestor_parent_index).unwrap(); | 532 | 1.65k | debug_assert_eq!( | 533 | 1.65k | ancestor_parent.children[usize::from(u8::from(parent_to_sibling_index))], | 534 | 1.65k | Some(ancestor_index) | 535 | | ); | 536 | 1.65k | ancestor_parent.children[usize::from(u8::from(parent_to_sibling_index))] = | 537 | 1.65k | Some(sibling_node_index); | 538 | | } else { | 539 | 305 | debug_assert_eq!(self.root_index, Some(ancestor_index)); | 540 | 305 | self.root_index = Some(sibling_node_index); | 541 | | } | 542 | | | 543 | 1.96k | ancestor.parent.map(|(idx, _)| idx) | 544 | | } else { | 545 | 5.50k | Some(ancestor_index) | 546 | | } | 547 | | }; | 548 | | | 549 | | // Return value of the function. | 550 | 7.46k | actual_ancestor_index.map(move |idx| self.node_by_index_inner(idx).unwrap()) | 551 | 8.30k | } |
_RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureuE13remove_prefixINtNtNtNtCs66KPHxksi63_4core4iter8adapters6cloned6ClonedINtNtNtB1z_5slice4iter4IterNtNtB5_6nibble6NibbleEEEB7_ Line | Count | Source | 395 | 5 | pub fn remove_prefix( | 396 | 5 | &'_ mut self, | 397 | 5 | prefix: impl Iterator<Item = Nibble> + Clone, | 398 | 5 | ) -> Option<NodeAccess<'_, TUd>> { | 399 | | // `ancestor` is the node that doesn't have the prefix but is the common ancestor of all | 400 | | // the nodes to remove. | 401 | 5 | let (ancestor_index2 , ancestor_child_nibble2 ) = match self.existing_node_inner(prefix.clone()) | 402 | | { | 403 | 3 | ExistingNodeInnerResult::Found { node_index, .. } => { | 404 | 3 | match self.nodes.get(node_index).unwrap().parent { | 405 | 2 | Some(p) => p, | 406 | | None => { | 407 | | // There is no parent, meaning that the trie is empty or the root of trie | 408 | | // is a node with the requested prefix. Simply clear the entire trie. | 409 | 1 | self.nodes.clear(); | 410 | 1 | self.root_index = None; | 411 | 1 | return None; | 412 | | } | 413 | | } | 414 | | } | 415 | | ExistingNodeInnerResult::NotFound { | 416 | | closest_ancestor: None, | 417 | | } => { | 418 | | // The trie is empty, or the key of the root node of the trie doesn't start with | 419 | | // the requested prefix, or the key of the root node of the trie starts with the | 420 | | // requested prefix. | 421 | | // If the trie is empty. then there is nothing to do and we return `None`. | 422 | 1 | let root_index = self.root_index?0 ; | 423 | | | 424 | | // Compare root key with the prefix. | 425 | 1 | if !self.nodes[root_index] | 426 | 1 | .partial_key | 427 | 1 | .iter() | 428 | 1 | .zip(prefix) | 429 | 1 | .all(|(a, b)| *a == b) | 430 | | { | 431 | | // Root node key doesn't match the prefix. Nothing to do. | 432 | 1 | return None; | 433 | 0 | } | 434 | | | 435 | | // Root node key starts with the requested prefix. Clear the entire trie. | 436 | 0 | self.nodes.clear(); | 437 | 0 | self.root_index = None; | 438 | 0 | return None; | 439 | | } | 440 | | ExistingNodeInnerResult::NotFound { | 441 | 1 | closest_ancestor: Some((ancestor, mut prefix_remain)), | 442 | | } => { | 443 | | // It is possible that there is simply no node at all with the given prefix, in | 444 | | // which case there is closest ancestor but nothing to clear. | 445 | | | 446 | 1 | let child_index = prefix_remain.next().unwrap(); | 447 | | | 448 | | // First possibility in case there is no node with the given prefix: the ancestor | 449 | | // simply has no child in the direction we want. For example, ancestor is | 450 | | // `[1, 2]`, there is a node at `[1, 2, 8]`, and we want to clear `[1, 2, 5]`. | 451 | 0 | let direct_child = if let Some(c) = | 452 | 1 | self.nodes[ancestor].children[usize::from(u8::from(child_index))] | 453 | | { | 454 | 0 | c | 455 | | } else { | 456 | 1 | return Some(self.node_by_index_inner(ancestor).unwrap()); | 457 | | }; | 458 | | | 459 | | // Second possibility in case there is no node with the given prefix: the ancestor | 460 | | // has a child in the direction we want, but this child doesn't have the prefix | 461 | | // that we want. For example, ancestor is `[1, 2]`, there is a node at | 462 | | // `[1, 2, 3, 8]`, and we want to clear `[1, 2, 3, 6]`. | 463 | | // TODO: this seems sub-optimal | 464 | 0 | if !self.nodes[direct_child] | 465 | 0 | .partial_key | 466 | 0 | .iter() | 467 | 0 | .zip(prefix_remain) | 468 | 0 | .all(|(a, b)| *a == b) | 469 | | { | 470 | 0 | return Some(self.node_by_index_inner(ancestor).unwrap()); | 471 | 0 | } | 472 | | | 473 | 0 | (ancestor, child_index) | 474 | | } | 475 | | }; | 476 | | | 477 | | // Removes all the descendants of `ancestor` through `ancestor_child_nibble`. | 478 | | { | 479 | | // TODO: this performs allocations, do we care? | 480 | 2 | let first_remove_index = self | 481 | 2 | .nodes | 482 | 2 | .get_mut(ancestor_index) | 483 | 2 | .unwrap() | 484 | 2 | .children | 485 | 2 | .get_mut(usize::from(u8::from(ancestor_child_nibble))) | 486 | 2 | .unwrap() | 487 | 2 | .take() | 488 | 2 | .unwrap(); | 489 | | | 490 | 2 | let mut to_remove = vec![first_remove_index]; | 491 | 8 | while !to_remove.is_empty() { | 492 | 6 | let mut next_to_remove = Vec::new(); | 493 | 8 | for node_index in to_remove6 .drain6 (..6 ) { | 494 | 8 | let node = self.nodes.remove(node_index); | 495 | 8 | next_to_remove.extend(node.children.iter().filter_map(|n| *n)); | 496 | | } | 497 | 6 | mem::swap(&mut to_remove, &mut next_to_remove); | 498 | | } | 499 | | } | 500 | | | 501 | | // If `ancestor` is a branch node with only one child (had two children before this | 502 | | // function call, but we removed one earlier), we have to remove it from the tree as well. | 503 | | // If this is the case, `actual_ancestor_index` will be equal to `ancestor`'s parent. | 504 | | // Otherwise it is set to `ancestor_index`. | 505 | 2 | let actual_ancestor_index = { | 506 | 2 | let ancestor = self.nodes.get_mut(ancestor_index).unwrap(); | 507 | 2 | debug_assert!( | 508 | 2 | ancestor.has_storage_value || ancestor.children.iter()0 .any0 (|c| c.is_some()) | 509 | | ); | 510 | 2 | if !ancestor.has_storage_value | 511 | 0 | && ancestor.children.iter().filter(|c| c.is_some()).count() == 1 | 512 | | { | 513 | 0 | let ancestor = self.nodes.remove(ancestor_index); | 514 | 0 | let sibling_node_index: usize = ancestor.children.iter().find_map(|c| *c).unwrap(); | 515 | | | 516 | | // Update the sibling to point to the ancestor's parent. | 517 | | { | 518 | 0 | let sibling = self.nodes.get_mut(sibling_node_index).unwrap(); | 519 | 0 | debug_assert_eq!(sibling.parent.as_ref().unwrap().0, ancestor_index); | 520 | 0 | insert_front( | 521 | 0 | &mut sibling.partial_key, | 522 | 0 | ancestor.partial_key, | 523 | 0 | sibling.parent.unwrap().1, | 524 | | ); | 525 | 0 | sibling.parent = ancestor.parent; | 526 | | } | 527 | | | 528 | | // Update the ancestor's parent to point to the sibling. | 529 | 0 | if let Some((ancestor_parent_index, parent_to_sibling_index)) = ancestor.parent { | 530 | | // Update the ancestory's parent to point to the sibling. | 531 | 0 | let ancestor_parent = self.nodes.get_mut(ancestor_parent_index).unwrap(); | 532 | 0 | debug_assert_eq!( | 533 | 0 | ancestor_parent.children[usize::from(u8::from(parent_to_sibling_index))], | 534 | 0 | Some(ancestor_index) | 535 | | ); | 536 | 0 | ancestor_parent.children[usize::from(u8::from(parent_to_sibling_index))] = | 537 | 0 | Some(sibling_node_index); | 538 | | } else { | 539 | 0 | debug_assert_eq!(self.root_index, Some(ancestor_index)); | 540 | 0 | self.root_index = Some(sibling_node_index); | 541 | | } | 542 | | | 543 | 0 | ancestor.parent.map(|(idx, _)| idx) | 544 | | } else { | 545 | 2 | Some(ancestor_index) | 546 | | } | 547 | | }; | 548 | | | 549 | | // Return value of the function. | 550 | 2 | actual_ancestor_index.map(move |idx| self.node_by_index_inner(idx).unwrap()) | 551 | 5 | } |
Unexecuted instantiation: _RINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB3_13TrieStructurepE13remove_prefixpEB7_ |
552 | | |
553 | | /// Returns true if the structure of this trie is the same as the structure of `other`. |
554 | | /// |
555 | | /// Everything is compared for equality except for the user datas. |
556 | | /// |
557 | | /// > **Note**: This function does a preliminary check for `self.len() == other.len()`. If the |
558 | | /// > length are different, `false` is immediately returned. If the lengths are |
559 | | /// > equal, the function performs the expensive operation of traversing both |
560 | | /// > tries in order to detect a potential mismatch. |
561 | | /// |
562 | | /// # Examples |
563 | | /// |
564 | | /// ``` |
565 | | /// use smoldot::trie::{self, trie_structure}; |
566 | | /// |
567 | | /// let mut trie1 = trie_structure::TrieStructure::new(); |
568 | | /// let mut trie2 = trie_structure::TrieStructure::new(); |
569 | | /// assert!(trie1.structure_equal(&trie2)); |
570 | | /// |
571 | | /// // Insert a node in the first trie. |
572 | | /// trie1 |
573 | | /// .node(trie::bytes_to_nibbles(b"foo".iter().cloned())) |
574 | | /// .into_vacant() |
575 | | /// .unwrap() |
576 | | /// .insert_storage_value() |
577 | | /// .insert(1234, 5678); |
578 | | /// assert!(!trie1.structure_equal(&trie2)); |
579 | | /// |
580 | | /// // Insert the same node in the second trie, but with a different user data. |
581 | | /// // The type of the user data of the second trie (strings) isn't even the same as for the |
582 | | /// // first trie (i32s). |
583 | | /// trie2 |
584 | | /// .node(trie::bytes_to_nibbles(b"foo".iter().cloned())) |
585 | | /// .into_vacant() |
586 | | /// .unwrap() |
587 | | /// .insert_storage_value() |
588 | | /// .insert("hello", "world"); |
589 | | /// |
590 | | /// // `structure_equal` returns true because both tries have the same nodes. |
591 | | /// assert!(trie1.structure_equal(&trie2)); |
592 | | /// ``` |
593 | 3.84k | pub fn structure_equal<T>(&self, other: &TrieStructure<T>) -> bool { |
594 | 3.84k | if self.nodes.len() != other.nodes.len() { |
595 | 0 | return false; |
596 | 3.84k | } |
597 | | |
598 | 3.84k | let mut me_iter = self.all_node_lexicographic_ordered(); |
599 | 3.84k | let mut other_iter = other.all_node_lexicographic_ordered(); |
600 | | |
601 | | loop { |
602 | 713k | let (me_node_idx709k , other_node_idx709k ) = match (me_iter.next(), other_iter.next()) { |
603 | 709k | (Some(a), Some(b)) => (a, b), |
604 | 3.84k | (None, None) => return true, |
605 | 0 | _ => return false, |
606 | | }; |
607 | | |
608 | 709k | let me_node = self.nodes.get(me_node_idx).unwrap(); |
609 | 709k | let other_node = other.nodes.get(other_node_idx).unwrap(); |
610 | | |
611 | 709k | if me_node.has_storage_value != other_node.has_storage_value { |
612 | 0 | return false; |
613 | 709k | } |
614 | | |
615 | 709k | match (me_node.parent, other_node.parent) { |
616 | 705k | (Some((_, i)), Some((_, j))) if i == j => {} |
617 | 3.84k | (None, None) => {} |
618 | 0 | _ => return false, |
619 | | } |
620 | | |
621 | 709k | if me_node.partial_key != other_node.partial_key { |
622 | 0 | return false; |
623 | 709k | } |
624 | | } |
625 | 3.84k | } _RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureuE15structure_equaluEB7_ Line | Count | Source | 593 | 3.84k | pub fn structure_equal<T>(&self, other: &TrieStructure<T>) -> bool { | 594 | 3.84k | if self.nodes.len() != other.nodes.len() { | 595 | 0 | return false; | 596 | 3.84k | } | 597 | | | 598 | 3.84k | let mut me_iter = self.all_node_lexicographic_ordered(); | 599 | 3.84k | let mut other_iter = other.all_node_lexicographic_ordered(); | 600 | | | 601 | | loop { | 602 | 713k | let (me_node_idx709k , other_node_idx709k ) = match (me_iter.next(), other_iter.next()) { | 603 | 709k | (Some(a), Some(b)) => (a, b), | 604 | 3.84k | (None, None) => return true, | 605 | 0 | _ => return false, | 606 | | }; | 607 | | | 608 | 709k | let me_node = self.nodes.get(me_node_idx).unwrap(); | 609 | 709k | let other_node = other.nodes.get(other_node_idx).unwrap(); | 610 | | | 611 | 709k | if me_node.has_storage_value != other_node.has_storage_value { | 612 | 0 | return false; | 613 | 709k | } | 614 | | | 615 | 709k | match (me_node.parent, other_node.parent) { | 616 | 705k | (Some((_, i)), Some((_, j))) if i == j => {} | 617 | 3.84k | (None, None) => {} | 618 | 0 | _ => return false, | 619 | | } | 620 | | | 621 | 709k | if me_node.partial_key != other_node.partial_key { | 622 | 0 | return false; | 623 | 709k | } | 624 | | } | 625 | 3.84k | } |
Unexecuted instantiation: _RINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB3_13TrieStructurepE15structure_equalpEB7_ |
626 | | |
627 | | /// Returns all nodes whose full key is within the given range, in lexicographic order. |
628 | | // TODO: change API to accept the range trait? |
629 | | #[inline] |
630 | 0 | pub fn range<'a>( |
631 | 0 | &'a self, |
632 | 0 | start_bound: ops::Bound<&'a [u8]>, // TODO: why does this require a `'a` lifetime? I don't get it |
633 | 0 | end_bound: ops::Bound<&'a [u8]>, |
634 | 0 | ) -> impl Iterator<Item = NodeIndex> + use<'a, TUd> { |
635 | 0 | let start_bound = match start_bound { |
636 | 0 | ops::Bound::Included(key) => { |
637 | 0 | ops::Bound::Included(bytes_to_nibbles(key.iter().copied())) |
638 | | } |
639 | 0 | ops::Bound::Excluded(key) => { |
640 | 0 | ops::Bound::Excluded(bytes_to_nibbles(key.iter().copied())) |
641 | | } |
642 | 0 | ops::Bound::Unbounded => ops::Bound::Unbounded, |
643 | | }; |
644 | | |
645 | 0 | let end_bound = match end_bound { |
646 | 0 | ops::Bound::Included(key) => { |
647 | 0 | ops::Bound::Included(bytes_to_nibbles(key.iter().copied())) |
648 | | } |
649 | 0 | ops::Bound::Excluded(key) => { |
650 | 0 | ops::Bound::Excluded(bytes_to_nibbles(key.iter().copied())) |
651 | | } |
652 | 0 | ops::Bound::Unbounded => ops::Bound::Unbounded, |
653 | | }; |
654 | | |
655 | 0 | self.range_inner(start_bound, end_bound).map(NodeIndex) |
656 | 0 | } Unexecuted instantiation: _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructurepE5rangeB6_ Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructurepE5rangeB6_ |
657 | | |
658 | | /// Returns all nodes whose full key is within the given range, in lexicographic order. |
659 | 6.58M | pub fn range_iter<'a>( |
660 | 6.58M | &'a self, |
661 | 6.58M | start_bound: ops::Bound<impl Iterator<Item = Nibble>>, |
662 | 6.58M | end_bound: ops::Bound<impl Iterator<Item = Nibble> + 'a>, |
663 | 6.58M | ) -> impl Iterator<Item = NodeIndex> { |
664 | 6.58M | self.range_inner(start_bound, end_bound).map(NodeIndex) |
665 | 6.58M | } _RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureuE10range_iterINtNtNtNtCs66KPHxksi63_4core4iter8adapters6copied6CopiedINtNtNtB1w_5slice4iter4IterNtNtB5_6nibble6NibbleEEB1n_EB7_ Line | Count | Source | 659 | 262k | pub fn range_iter<'a>( | 660 | 262k | &'a self, | 661 | 262k | start_bound: ops::Bound<impl Iterator<Item = Nibble>>, | 662 | 262k | end_bound: ops::Bound<impl Iterator<Item = Nibble> + 'a>, | 663 | 262k | ) -> impl Iterator<Item = NodeIndex> { | 664 | 262k | self.range_inner(start_bound, end_bound).map(NodeIndex) | 665 | 262k | } |
_RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB5_16TrieEntryVersionEEIB1b_NtNtB5_9trie_node17MerkleValueOutputEEE10range_iterINtNtB1Q_9into_iter8IntoIterNtNtB5_6nibble6NibbleEINtNtNtNtB1f_4iter7sources5empty5EmptyB47_EEB7_ Line | Count | Source | 659 | 6.32M | pub fn range_iter<'a>( | 660 | 6.32M | &'a self, | 661 | 6.32M | start_bound: ops::Bound<impl Iterator<Item = Nibble>>, | 662 | 6.32M | end_bound: ops::Bound<impl Iterator<Item = Nibble> + 'a>, | 663 | 6.32M | ) -> impl Iterator<Item = NodeIndex> { | 664 | 6.32M | self.range_inner(start_bound, end_bound).map(NodeIndex) | 665 | 6.32M | } |
Unexecuted instantiation: _RINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB3_13TrieStructurepE10range_iterppEB7_ |
666 | | |
667 | | /// Returns all nodes whose full key is within the given range, in lexicographic order. |
668 | 6.58M | fn range_inner<'a>( |
669 | 6.58M | &'a self, |
670 | 6.58M | start_bound: ops::Bound<impl Iterator<Item = Nibble>>, |
671 | 6.58M | end_bound: ops::Bound<impl Iterator<Item = Nibble> + 'a>, |
672 | 6.58M | ) -> impl Iterator<Item = usize> { |
673 | | // Start by processing the end bound to obtain an "end key". |
674 | | // This end key is always assumed to be excluded. In other words, only keys strictly |
675 | | // inferior to the end key are returned. If the user provides `Included`, we modify the key |
676 | | // and append a dummy `0` nibble at the end of it. If the user provides `Unbounded`, we use |
677 | | // an infinite-sized key so that every finite key is always inferior to it. |
678 | | // |
679 | | // The algorithm later down this function will pop nibbles from the start of `end_key`. |
680 | | // Because `end_key` is always excluded, this iterator must always contain at least one |
681 | | // nibble, otherwise the iteration should have ended. |
682 | 6.58M | let mut end_key = match end_bound { |
683 | 6.40M | ops::Bound::Unbounded => either::Left(iter::repeat(Nibble::max())), |
684 | 87.0k | ops::Bound::Excluded(end_key) => either::Right(end_key.chain(None)), |
685 | 87.5k | ops::Bound::Included(end_key) => either::Right(end_key.chain(Some(Nibble::zero()))), |
686 | | } |
687 | 6.58M | .peekable(); |
688 | | |
689 | | // The user passed `Excluded(&[])`. Return an empty range. |
690 | 6.58M | if end_key.peek().is_none() { |
691 | 14.3k | return either::Right(iter::empty()); |
692 | 6.56M | } |
693 | | |
694 | | // The code below creates a variable named `iter`. This `iter` represents the cursor |
695 | | // where the iterator is. |
696 | | // `iter` also contains an optional nibble. If this optional nibble is `None`, the |
697 | | // iteration is currently at the node itself. If it is `Some`, the iteration isn't at the |
698 | | // node itself but at its child of the given nibble (which potentially doesn't exist). |
699 | | // If it is `Some(None)`, then the iteration is right after the last children of the node. |
700 | | // In other words, `Some(None)` represents an overflow. |
701 | 6.56M | let mut iter6.56M : (usize, Option<Option<Nibble>>)6.56M = match self.root_index { |
702 | 6.56M | Some(idx) => (idx, None), |
703 | | None => { |
704 | | // Trie is empty. Special case. |
705 | 242 | return either::Right(iter::empty()); |
706 | | } |
707 | | }; |
708 | | |
709 | | // Equal to `len(key(iter)) - len(key(iter) ∩ end_key)`. In other words, the number of |
710 | | // nibbles at the end of `iter`'s key that do not match the end key. This also includes |
711 | | // the optional nibble within `iter` if any. |
712 | 6.56M | let mut iter_key_nibbles_extra: usize = 0; |
713 | | |
714 | | // Transform `start_bound` into something more simple to process. |
715 | 6.56M | let (mut start_key, start_key_is_inclusive) = match start_bound { |
716 | 82.8k | ops::Bound::Unbounded => (either::Right(iter::empty()), true), |
717 | 6.40M | ops::Bound::Included(k) => (either::Left(k), true), |
718 | 82.2k | ops::Bound::Excluded(k) => (either::Left(k), false), |
719 | | }; |
720 | | |
721 | | // Iterate down the tree, updating the variables above. At each iteration, one of the |
722 | | // three following is true: |
723 | | // |
724 | | // - `iter` is inferior or inferior or equal (depending on `start_key_is_inclusive`) to |
725 | | // `start_key`. |
726 | | // - `iter` is the first node that is superior or strictly superior (depending on |
727 | | // `start_key_is_inclusive`) to `start_key`. |
728 | | // - `iter` points to a non-existing node that is inferior/inferior-or-equal to |
729 | | // `start_key`, but is right before the first node that is superior/strictly superior to |
730 | | // `start_key`. |
731 | | // |
732 | | // As soon as we reach one of the last two conditions, we stop iterating, as it means |
733 | | // that `iter` is at the correct position. |
734 | | 'start_search: loop { |
735 | 8.13M | debug_assert!(iter.1.is_none()); |
736 | 8.13M | let iter_node = self.nodes.get(iter.0).unwrap(); |
737 | | |
738 | | // Compare the nibbles at the front of `start_key` with the ones of `iter_node`. |
739 | | // Consumes the nibbles at the start of `start_key`. |
740 | 8.13M | let pk_compare = { |
741 | 8.13M | let mut result = cmp::Ordering::Equal; |
742 | 8.13M | for iter_node_pk_nibble2.99M in iter_node.partial_key.iter() { |
743 | 2.99M | match start_key |
744 | 2.99M | .next() |
745 | 2.99M | .map(|nibble| nibble2.93M .cmp2.93M (iter_node_pk_nibble2.93M )) _RNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1d_NtNtB7_9trie_node17MerkleValueOutputEEE11range_innerINtNtB1S_9into_iter8IntoIterNtNtB7_6nibble6NibbleEINtNtNtNtB1h_4iter7sources5empty5EmptyB4a_EE0B9_ Line | Count | Source | 745 | 2.91M | .map(|nibble| nibble.cmp(iter_node_pk_nibble)) |
_RNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureuE11range_innerINtNtNtNtCs66KPHxksi63_4core4iter8adapters6copied6CopiedINtNtNtB1z_5slice4iter4IterNtNtB7_6nibble6NibbleEEB1q_E0B9_ Line | Count | Source | 745 | 17.8k | .map(|nibble| nibble.cmp(iter_node_pk_nibble)) |
Unexecuted instantiation: _RNCINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13TrieStructurepE11range_innerppE0B9_ |
746 | | { |
747 | | None | Some(cmp::Ordering::Less) => { |
748 | 364k | result = cmp::Ordering::Less; |
749 | 364k | break; |
750 | | } |
751 | 2.33M | Some(cmp::Ordering::Equal) => {} |
752 | | Some(cmp::Ordering::Greater) => { |
753 | 299k | result = cmp::Ordering::Greater; |
754 | 299k | break; |
755 | | } |
756 | | } |
757 | | } |
758 | 8.13M | result |
759 | | }; |
760 | | |
761 | 8.13M | match pk_compare { |
762 | | cmp::Ordering::Less | cmp::Ordering::Equal => { |
763 | | // Update the value of `iter_key_nibbles_extra` to take the current value |
764 | | // of `iter` into account, as it hasn't been done yet. |
765 | 7.83M | for iter_node_pk_nibble3.38M in iter_node.partial_key.iter().cloned() { |
766 | 3.38M | if iter_key_nibbles_extra == 0 |
767 | 74.4k | && iter_node_pk_nibble == *end_key.peek().unwrap() |
768 | | { |
769 | 6.55k | let _ = end_key.next(); |
770 | | // `iter` is already past the end bound. Return an empty range. |
771 | 6.55k | if end_key.peek().is_none() { |
772 | 13 | return either::Right(iter::empty()); |
773 | 6.54k | } |
774 | 3.38M | } else if iter_key_nibbles_extra == 0 |
775 | 67.8k | && iter_node_pk_nibble > *end_key.peek().unwrap() |
776 | | { |
777 | 792 | return either::Right(iter::empty()); |
778 | 3.38M | } else { |
779 | 3.38M | iter_key_nibbles_extra += 1; |
780 | 3.38M | } |
781 | | } |
782 | | |
783 | 7.83M | if pk_compare == cmp::Ordering::Less { |
784 | | // `iter` is strictly superior to `start_key`. `iter` is now at the |
785 | | // correct position. |
786 | 364k | break 'start_search; |
787 | 7.46M | } |
788 | | } |
789 | | cmp::Ordering::Greater => { |
790 | | // `iter` is strictly inferior to `start_key`, and all of its children will |
791 | | // also be strictly inferior to `start_key`. |
792 | | // Stop the search immediately after the current node in the parent. |
793 | 299k | let Some((parent298k , parent_nibble298k )) = iter_node.parent else { |
794 | 395 | return either::Right(iter::empty()); |
795 | | }; |
796 | 298k | let next_nibble = parent_nibble.checked_add(1); |
797 | 298k | if iter_key_nibbles_extra == 0 { |
798 | 19.3k | return either::Right(iter::empty()); |
799 | 279k | } |
800 | 279k | iter_key_nibbles_extra -= 1; |
801 | 279k | if iter_key_nibbles_extra == 0 && next_nibble277k == Some(*end_key277k .peek().unwrap()) |
802 | | { |
803 | 18.6k | let _ = end_key.next(); |
804 | | // `iter` is already past the end bound. Return an empty range. |
805 | 18.6k | if end_key.peek().is_none() { |
806 | 30 | return either::Right(iter::empty()); |
807 | 18.6k | } |
808 | 260k | } else { |
809 | 260k | iter_key_nibbles_extra += 1; |
810 | 260k | } |
811 | 279k | iter = (parent, Some(next_nibble)); |
812 | 279k | break 'start_search; |
813 | | } |
814 | | } |
815 | | |
816 | | // Remove the next nibble from `start_key` and update `iter` based on it. |
817 | 7.46M | if let Some(next_nibble7.31M ) = start_key.next() { |
818 | 7.31M | if iter_key_nibbles_extra == 0 && next_nibble6.43M == *end_key6.43M .peek().unwrap() { |
819 | 401k | let _ = end_key.next(); |
820 | | // `iter` is already past the end bound. Return an empty range. |
821 | 401k | if end_key.peek().is_none() { |
822 | 994 | return either::Right(iter::empty()); |
823 | 400k | } |
824 | 6.91M | } else if iter_key_nibbles_extra == 0 && next_nibble6.03M > *end_key6.03M .peek().unwrap() { |
825 | 45.6k | return either::Right(iter::empty()); |
826 | 6.86M | } else { |
827 | 6.86M | iter_key_nibbles_extra += 1; |
828 | 6.86M | } |
829 | | |
830 | 7.26M | if let Some(child1.56M ) = iter_node.children[usize::from(u8::from(next_nibble))] { |
831 | 1.56M | // Update `iter` and continue searching. |
832 | 1.56M | iter = (child, None); |
833 | 1.56M | } else { |
834 | | // `iter` is strictly inferior to `start_key`. |
835 | 5.70M | iter.1 = Some(Some(next_nibble)); |
836 | 5.70M | break 'start_search; |
837 | | } |
838 | | } else { |
839 | | // `iter.0` is an exact match with `start_key`. If the starting bound is |
840 | | // `Excluded`, we don't want to start iterating at `iter` but at `next(iter)`, |
841 | | // which we do by adding a zero nibble afterwards. |
842 | 156k | debug_assert!(iter.1.is_none()); |
843 | 156k | if !start_key_is_inclusive { |
844 | 16.4k | iter.1 = Some(Some(Nibble::zero())); |
845 | 16.4k | if iter_key_nibbles_extra == 0 && *13.8k end_key13.8k .peek().unwrap() == Nibble::zero() { |
846 | 1.35k | let _ = end_key.next(); |
847 | | // `iter` is already past the end bound. Return an empty range. |
848 | 1.35k | if end_key.peek().is_none() { |
849 | 885 | return either::Right(iter::empty()); |
850 | 469 | } |
851 | 15.1k | } else { |
852 | 15.1k | iter_key_nibbles_extra += 1; |
853 | 15.1k | } |
854 | 139k | } |
855 | | |
856 | 155k | break 'start_search; |
857 | | } |
858 | | } |
859 | | |
860 | | // `iter` is now at the correct position and we can start yielding nodes until we reach |
861 | | // the end. This is done in the iterator that is returned from the function. |
862 | | |
863 | 13.2M | either::Left(iter::from_fn6.49M (move || { |
864 | | loop { |
865 | | // `end_key` must never be empty, as otherwise the iteration has ended. |
866 | | // We return `None` instead of panicking, as it is legitimately possible to reach |
867 | | // this situation through some code paths. |
868 | 37.4M | let _ = end_key.peek()?17.3k ; |
869 | | |
870 | | // If `iter` points to an actual node, yield it and jump to the position right |
871 | | // after. |
872 | 37.4M | let Some(iter_127.5M ) = iter.1 else { |
873 | 9.85M | iter.1 = Some(Some(Nibble::zero())); |
874 | 9.85M | if iter_key_nibbles_extra == 0 && *205k end_key205k .peek().unwrap() == Nibble::zero() { |
875 | 14.0k | let _ = end_key.next(); |
876 | 9.84M | } else { |
877 | 9.84M | iter_key_nibbles_extra += 1; |
878 | 9.84M | } |
879 | 9.85M | return Some(iter.0); |
880 | | }; |
881 | | |
882 | 27.5M | let node = self.nodes.get(iter.0).unwrap(); |
883 | | |
884 | 9.36M | if let Some(child) = |
885 | 27.5M | iter_1.and_then(|iter_1| node.children[usize::from27.1M (u8::from27.1M (iter_127.1M ))]) _RNCNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB9_16TrieEntryVersionEEIB1f_NtNtB9_9trie_node17MerkleValueOutputEEE11range_innerINtNtB1U_9into_iter8IntoIterNtNtB9_6nibble6NibbleEINtNtNtNtB1j_4iter7sources5empty5EmptyB4c_EEs_00Bb_ Line | Count | Source | 885 | 9.27M | iter_1.and_then(|iter_1| node.children[usize::from(u8::from(iter_1))]) |
_RNCNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_13TrieStructureuE11range_innerINtNtNtNtCs66KPHxksi63_4core4iter8adapters6copied6CopiedINtNtNtB1B_5slice4iter4IterNtNtB9_6nibble6NibbleEEB1s_Es_00Bb_ Line | Count | Source | 885 | 17.9M | iter_1.and_then(|iter_1| node.children[usize::from(u8::from(iter_1))]) |
Unexecuted instantiation: _RNCNCINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB7_13TrieStructurepE11range_innerppEs_00Bb_ |
886 | | { |
887 | | // `child` might be after the end bound if its partial key is superior or |
888 | | // equal to the `end_key`. |
889 | 12.8M | for child_pk_nibble in self.nodes9.36M .get9.36M (child).unwrap().partial_key.iter9.36M () { |
890 | 12.8M | match child_pk_nibble.cmp(end_key.peek().unwrap()) { |
891 | 591k | cmp::Ordering::Greater if iter_key_nibbles_extra == 011.4k => return None11.4k , |
892 | 12.0M | cmp::Ordering::Greater | cmp::Ordering::Less => { |
893 | 12.0M | iter_key_nibbles_extra += 1; |
894 | 12.0M | } |
895 | 810k | cmp::Ordering::Equal if iter_key_nibbles_extra != 0788k => { |
896 | 788k | iter_key_nibbles_extra += 1; |
897 | 788k | } |
898 | | cmp::Ordering::Equal => { |
899 | 22.2k | debug_assert_eq!(iter_key_nibbles_extra, 0); |
900 | 22.2k | let _ = end_key.next(); |
901 | 22.2k | let _ = end_key.peek()?305 ; |
902 | | } |
903 | | } |
904 | | } |
905 | | |
906 | 9.35M | iter = (child, None); |
907 | 18.1M | } else if iter_key_nibbles_extra == 0 |
908 | 17.7M | || (iter_key_nibbles_extra == 1 |
909 | 5.88M | && iter_1.map_or(true, |iter_1| iter_1 > *end_key.peek().unwrap())) _RNCNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB9_16TrieEntryVersionEEIB1f_NtNtB9_9trie_node17MerkleValueOutputEEE11range_innerINtNtB1U_9into_iter8IntoIterNtNtB9_6nibble6NibbleEINtNtNtNtB1j_4iter7sources5empty5EmptyB4c_EEs_0s_0Bb_ Line | Count | Source | 909 | 5.36M | && iter_1.map_or(true, |iter_1| iter_1 > *end_key.peek().unwrap())) |
_RNCNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_13TrieStructureuE11range_innerINtNtNtNtCs66KPHxksi63_4core4iter8adapters6copied6CopiedINtNtNtB1B_5slice4iter4IterNtNtB9_6nibble6NibbleEEB1s_Es_0s_0Bb_ Line | Count | Source | 909 | 522k | && iter_1.map_or(true, |iter_1| iter_1 > *end_key.peek().unwrap())) |
Unexecuted instantiation: _RNCNCINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB7_13TrieStructurepE11range_innerppEs_0s_0Bb_ |
910 | | { |
911 | 411k | return None; |
912 | 17.7M | } else if let Some(child_index7.41M ) = iter_1.and_then(|iter_1| {17.4M |
913 | 17.4M | node.children[(usize::from(u8::from(iter_1))) |
914 | 17.4M | ..=usize::from(u8::from(if iter_key_nibbles_extra == 1 { |
915 | 5.88M | *end_key.peek().unwrap() |
916 | | } else { |
917 | 11.5M | Nibble::max() |
918 | | }))] |
919 | 17.4M | .iter() |
920 | 148M | .position17.4M (|c| c.is_some()) _RNCNCNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB9_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtBb_16TrieEntryVersionEEIB1h_NtNtBb_9trie_node17MerkleValueOutputEEE11range_innerINtNtB1W_9into_iter8IntoIterNtNtBb_6nibble6NibbleEINtNtNtNtB1l_4iter7sources5empty5EmptyB4e_EEs_0s0_00Bd_ Line | Count | Source | 920 | 41.6M | .position(|c| c.is_some()) |
_RNCNCNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB9_13TrieStructureuE11range_innerINtNtNtNtCs66KPHxksi63_4core4iter8adapters6copied6CopiedINtNtNtB1D_5slice4iter4IterNtNtBb_6nibble6NibbleEEB1u_Es_0s0_00Bd_ Line | Count | Source | 920 | 106M | .position(|c| c.is_some()) |
Unexecuted instantiation: _RNCNCNCINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB9_13TrieStructurepE11range_innerppEs_0s0_00Bd_ |
921 | 17.4M | }) {_RNCNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB9_16TrieEntryVersionEEIB1f_NtNtB9_9trie_node17MerkleValueOutputEEE11range_innerINtNtB1U_9into_iter8IntoIterNtNtB9_6nibble6NibbleEINtNtNtNtB1j_4iter7sources5empty5EmptyB4c_EEs_0s0_0Bb_ Line | Count | Source | 912 | 6.21M | } else if let Some(child_index) = iter_1.and_then(|iter_1| { | 913 | 6.21M | node.children[(usize::from(u8::from(iter_1))) | 914 | 6.21M | ..=usize::from(u8::from(if iter_key_nibbles_extra == 1 { | 915 | 5.36M | *end_key.peek().unwrap() | 916 | | } else { | 917 | 849k | Nibble::max() | 918 | | }))] | 919 | 6.21M | .iter() | 920 | 6.21M | .position(|c| c.is_some()) | 921 | 6.21M | }) { |
_RNCNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_13TrieStructureuE11range_innerINtNtNtNtCs66KPHxksi63_4core4iter8adapters6copied6CopiedINtNtNtB1B_5slice4iter4IterNtNtB9_6nibble6NibbleEEB1s_Es_0s0_0Bb_ Line | Count | Source | 912 | 11.1M | } else if let Some(child_index) = iter_1.and_then(|iter_1| { | 913 | 11.1M | node.children[(usize::from(u8::from(iter_1))) | 914 | 11.1M | ..=usize::from(u8::from(if iter_key_nibbles_extra == 1 { | 915 | 522k | *end_key.peek().unwrap() | 916 | | } else { | 917 | 10.6M | Nibble::max() | 918 | | }))] | 919 | 11.1M | .iter() | 920 | 11.1M | .position(|c| c.is_some()) | 921 | 11.1M | }) { |
Unexecuted instantiation: _RNCNCINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB7_13TrieStructurepE11range_innerppEs_0s0_0Bb_ |
922 | 7.41M | let child_nibble = Nibble::try_from( |
923 | 7.41M | u8::try_from(usize::from(u8::from(iter_1.unwrap())) + child_index).unwrap(), |
924 | | ) |
925 | 7.41M | .unwrap(); |
926 | | |
927 | 7.41M | if iter_key_nibbles_extra == 1 && child_nibble2.99M == *end_key2.99M .peek().unwrap() { |
928 | 312k | iter_key_nibbles_extra = 0; |
929 | 312k | let _ = end_key.next(); |
930 | 7.10M | } |
931 | | |
932 | 7.41M | iter.1 = Some(Some(child_nibble)); |
933 | | } else { |
934 | | // `iter` has no child. Go to the parent. |
935 | 10.3M | let node = self.nodes.get(iter.0).unwrap(); |
936 | | |
937 | | // End the iterator if we were about to jump out of the end bound. |
938 | 10.3M | if iter_key_nibbles_extra < 2 + node.partial_key.len() { |
939 | 2.96M | return None; |
940 | 7.37M | } |
941 | | |
942 | 7.37M | let Some((parent_node_index, parent_nibble_direction)) = node.parent else { |
943 | 0 | return None; |
944 | | }; |
945 | 7.37M | iter_key_nibbles_extra -= 2; |
946 | 7.37M | iter_key_nibbles_extra -= node.partial_key.len(); |
947 | 7.37M | let next_sibling_nibble = parent_nibble_direction.checked_add(1); |
948 | 7.37M | if iter_key_nibbles_extra == 0 |
949 | 1.63M | && next_sibling_nibble == Some(*end_key.peek().unwrap()) |
950 | 148k | { |
951 | 148k | let _ = end_key.next(); |
952 | 7.22M | } else { |
953 | 7.22M | iter_key_nibbles_extra += 1; |
954 | 7.22M | } |
955 | 7.37M | iter = (parent_node_index, Some(next_sibling_nibble)); |
956 | | } |
957 | | } |
958 | 13.2M | })) _RNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1d_NtNtB7_9trie_node17MerkleValueOutputEEE11range_innerINtNtB1S_9into_iter8IntoIterNtNtB7_6nibble6NibbleEINtNtNtNtB1h_4iter7sources5empty5EmptyB4a_EEs_0B9_ Line | Count | Source | 863 | 6.30M | either::Left(iter::from_fn(move || { | 864 | | loop { | 865 | | // `end_key` must never be empty, as otherwise the iteration has ended. | 866 | | // We return `None` instead of panicking, as it is legitimately possible to reach | 867 | | // this situation through some code paths. | 868 | 12.3M | let _ = end_key.peek()?0 ; | 869 | | | 870 | | // If `iter` points to an actual node, yield it and jump to the position right | 871 | | // after. | 872 | 12.3M | let Some(iter_19.27M ) = iter.1 else { | 873 | 3.08M | iter.1 = Some(Some(Nibble::zero())); | 874 | 3.08M | if iter_key_nibbles_extra == 0 && *54.4k end_key54.4k .peek().unwrap() == Nibble::zero() { | 875 | 0 | let _ = end_key.next(); | 876 | 3.08M | } else { | 877 | 3.08M | iter_key_nibbles_extra += 1; | 878 | 3.08M | } | 879 | 3.08M | return Some(iter.0); | 880 | | }; | 881 | | | 882 | 9.27M | let node = self.nodes.get(iter.0).unwrap(); | 883 | | | 884 | 2.69M | if let Some(child) = | 885 | 9.27M | iter_1.and_then(|iter_1| node.children[usize::from(u8::from(iter_1))]) | 886 | | { | 887 | | // `child` might be after the end bound if its partial key is superior or | 888 | | // equal to the `end_key`. | 889 | 7.65M | for child_pk_nibble in self.nodes2.69M .get2.69M (child).unwrap().partial_key.iter2.69M () { | 890 | 7.65M | match child_pk_nibble.cmp(end_key.peek().unwrap()) { | 891 | 0 | cmp::Ordering::Greater if iter_key_nibbles_extra == 0 => return None, | 892 | 7.16M | cmp::Ordering::Greater | cmp::Ordering::Less => { | 893 | 7.16M | iter_key_nibbles_extra += 1; | 894 | 7.16M | } | 895 | 487k | cmp::Ordering::Equal if iter_key_nibbles_extra != 0467k => { | 896 | 467k | iter_key_nibbles_extra += 1; | 897 | 467k | } | 898 | | cmp::Ordering::Equal => { | 899 | 19.7k | debug_assert_eq!(iter_key_nibbles_extra, 0); | 900 | 19.7k | let _ = end_key.next(); | 901 | 19.7k | let _ = end_key.peek()?0 ; | 902 | | } | 903 | | } | 904 | | } | 905 | | | 906 | 2.69M | iter = (child, None); | 907 | 6.57M | } else if iter_key_nibbles_extra == 0 | 908 | 6.21M | || (iter_key_nibbles_extra == 1 | 909 | 5.36M | && iter_1.map_or(true, |iter_1| iter_1 > *end_key.peek().unwrap())) | 910 | | { | 911 | 358k | return None; | 912 | 6.21M | } else if let Some(child_index2.60M ) = iter_1.and_then(|iter_1| { | 913 | | node.children[(usize::from(u8::from(iter_1))) | 914 | | ..=usize::from(u8::from(if iter_key_nibbles_extra == 1 { | 915 | | *end_key.peek().unwrap() | 916 | | } else { | 917 | | Nibble::max() | 918 | | }))] | 919 | | .iter() | 920 | | .position(|c| c.is_some()) | 921 | | }) { | 922 | 2.60M | let child_nibble = Nibble::try_from( | 923 | 2.60M | u8::try_from(usize::from(u8::from(iter_1.unwrap())) + child_index).unwrap(), | 924 | | ) | 925 | 2.60M | .unwrap(); | 926 | | | 927 | 2.60M | if iter_key_nibbles_extra == 1 && child_nibble2.56M == *end_key2.56M .peek().unwrap() { | 928 | 266k | iter_key_nibbles_extra = 0; | 929 | 266k | let _ = end_key.next(); | 930 | 2.33M | } | 931 | | | 932 | 2.60M | iter.1 = Some(Some(child_nibble)); | 933 | | } else { | 934 | | // `iter` has no child. Go to the parent. | 935 | 3.61M | let node = self.nodes.get(iter.0).unwrap(); | 936 | | | 937 | | // End the iterator if we were about to jump out of the end bound. | 938 | 3.61M | if iter_key_nibbles_extra < 2 + node.partial_key.len() { | 939 | 2.85M | return None; | 940 | 765k | } | 941 | | | 942 | 765k | let Some((parent_node_index, parent_nibble_direction)) = node.parent else { | 943 | 0 | return None; | 944 | | }; | 945 | 765k | iter_key_nibbles_extra -= 2; | 946 | 765k | iter_key_nibbles_extra -= node.partial_key.len(); | 947 | 765k | let next_sibling_nibble = parent_nibble_direction.checked_add(1); | 948 | 765k | if iter_key_nibbles_extra == 0 | 949 | 730k | && next_sibling_nibble == Some(*end_key.peek().unwrap()) | 950 | 47.8k | { | 951 | 47.8k | let _ = end_key.next(); | 952 | 717k | } else { | 953 | 717k | iter_key_nibbles_extra += 1; | 954 | 717k | } | 955 | 765k | iter = (parent_node_index, Some(next_sibling_nibble)); | 956 | | } | 957 | | } | 958 | 6.30M | })) |
_RNCINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureuE11range_innerINtNtNtNtCs66KPHxksi63_4core4iter8adapters6copied6CopiedINtNtNtB1z_5slice4iter4IterNtNtB7_6nibble6NibbleEEB1q_Es_0B9_ Line | Count | Source | 863 | 6.96M | either::Left(iter::from_fn(move || { | 864 | | loop { | 865 | | // `end_key` must never be empty, as otherwise the iteration has ended. | 866 | | // We return `None` instead of panicking, as it is legitimately possible to reach | 867 | | // this situation through some code paths. | 868 | 25.0M | let _ = end_key.peek()?17.3k ; | 869 | | | 870 | | // If `iter` points to an actual node, yield it and jump to the position right | 871 | | // after. | 872 | 25.0M | let Some(iter_118.2M ) = iter.1 else { | 873 | 6.76M | iter.1 = Some(Some(Nibble::zero())); | 874 | 6.76M | if iter_key_nibbles_extra == 0 && *151k end_key151k .peek().unwrap() == Nibble::zero() { | 875 | 14.0k | let _ = end_key.next(); | 876 | 6.75M | } else { | 877 | 6.75M | iter_key_nibbles_extra += 1; | 878 | 6.75M | } | 879 | 6.76M | return Some(iter.0); | 880 | | }; | 881 | | | 882 | 18.2M | let node = self.nodes.get(iter.0).unwrap(); | 883 | | | 884 | 6.67M | if let Some(child) = | 885 | 18.2M | iter_1.and_then(|iter_1| node.children[usize::from(u8::from(iter_1))]) | 886 | | { | 887 | | // `child` might be after the end bound if its partial key is superior or | 888 | | // equal to the `end_key`. | 889 | 6.67M | for child_pk_nibble5.18M in self.nodes.get(child).unwrap().partial_key.iter() { | 890 | 5.18M | match child_pk_nibble.cmp(end_key.peek().unwrap()) { | 891 | 591k | cmp::Ordering::Greater if iter_key_nibbles_extra == 011.4k => return None11.4k , | 892 | 4.85M | cmp::Ordering::Greater | cmp::Ordering::Less => { | 893 | 4.85M | iter_key_nibbles_extra += 1; | 894 | 4.85M | } | 895 | 323k | cmp::Ordering::Equal if iter_key_nibbles_extra != 0320k => { | 896 | 320k | iter_key_nibbles_extra += 1; | 897 | 320k | } | 898 | | cmp::Ordering::Equal => { | 899 | 2.51k | debug_assert_eq!(iter_key_nibbles_extra, 0); | 900 | 2.51k | let _ = end_key.next(); | 901 | 2.51k | let _ = end_key.peek()?305 ; | 902 | | } | 903 | | } | 904 | | } | 905 | | | 906 | 6.65M | iter = (child, None); | 907 | 11.5M | } else if iter_key_nibbles_extra == 0 | 908 | 11.5M | || (iter_key_nibbles_extra == 1 | 909 | 522k | && iter_1.map_or(true, |iter_1| iter_1 > *end_key.peek().unwrap())) | 910 | | { | 911 | 52.4k | return None; | 912 | 11.5M | } else if let Some(child_index4.81M ) = iter_1.and_then(|iter_1| { | 913 | | node.children[(usize::from(u8::from(iter_1))) | 914 | | ..=usize::from(u8::from(if iter_key_nibbles_extra == 1 { | 915 | | *end_key.peek().unwrap() | 916 | | } else { | 917 | | Nibble::max() | 918 | | }))] | 919 | | .iter() | 920 | | .position(|c| c.is_some()) | 921 | | }) { | 922 | 4.81M | let child_nibble = Nibble::try_from( | 923 | 4.81M | u8::try_from(usize::from(u8::from(iter_1.unwrap())) + child_index).unwrap(), | 924 | | ) | 925 | 4.81M | .unwrap(); | 926 | | | 927 | 4.81M | if iter_key_nibbles_extra == 1 && child_nibble435k == *end_key435k .peek().unwrap() { | 928 | 45.9k | iter_key_nibbles_extra = 0; | 929 | 45.9k | let _ = end_key.next(); | 930 | 4.76M | } | 931 | | | 932 | 4.81M | iter.1 = Some(Some(child_nibble)); | 933 | | } else { | 934 | | // `iter` has no child. Go to the parent. | 935 | 6.72M | let node = self.nodes.get(iter.0).unwrap(); | 936 | | | 937 | | // End the iterator if we were about to jump out of the end bound. | 938 | 6.72M | if iter_key_nibbles_extra < 2 + node.partial_key.len() { | 939 | 116k | return None; | 940 | 6.61M | } | 941 | | | 942 | 6.61M | let Some((parent_node_index, parent_nibble_direction)) = node.parent else { | 943 | 0 | return None; | 944 | | }; | 945 | 6.61M | iter_key_nibbles_extra -= 2; | 946 | 6.61M | iter_key_nibbles_extra -= node.partial_key.len(); | 947 | 6.61M | let next_sibling_nibble = parent_nibble_direction.checked_add(1); | 948 | 6.61M | if iter_key_nibbles_extra == 0 | 949 | 905k | && next_sibling_nibble == Some(*end_key.peek().unwrap()) | 950 | 100k | { | 951 | 100k | let _ = end_key.next(); | 952 | 6.51M | } else { | 953 | 6.51M | iter_key_nibbles_extra += 1; | 954 | 6.51M | } | 955 | 6.61M | iter = (parent_node_index, Some(next_sibling_nibble)); | 956 | | } | 957 | | } | 958 | 6.96M | })) |
Unexecuted instantiation: _RNCINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13TrieStructurepE11range_innerppEs_0B9_ |
959 | 6.58M | } _RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB5_16TrieEntryVersionEEIB1b_NtNtB5_9trie_node17MerkleValueOutputEEE11range_innerINtNtB1Q_9into_iter8IntoIterNtNtB5_6nibble6NibbleEINtNtNtNtB1f_4iter7sources5empty5EmptyB48_EEB7_ Line | Count | Source | 668 | 6.32M | fn range_inner<'a>( | 669 | 6.32M | &'a self, | 670 | 6.32M | start_bound: ops::Bound<impl Iterator<Item = Nibble>>, | 671 | 6.32M | end_bound: ops::Bound<impl Iterator<Item = Nibble> + 'a>, | 672 | 6.32M | ) -> impl Iterator<Item = usize> { | 673 | | // Start by processing the end bound to obtain an "end key". | 674 | | // This end key is always assumed to be excluded. In other words, only keys strictly | 675 | | // inferior to the end key are returned. If the user provides `Included`, we modify the key | 676 | | // and append a dummy `0` nibble at the end of it. If the user provides `Unbounded`, we use | 677 | | // an infinite-sized key so that every finite key is always inferior to it. | 678 | | // | 679 | | // The algorithm later down this function will pop nibbles from the start of `end_key`. | 680 | | // Because `end_key` is always excluded, this iterator must always contain at least one | 681 | | // nibble, otherwise the iteration should have ended. | 682 | 6.32M | let mut end_key = match end_bound { | 683 | 6.32M | ops::Bound::Unbounded => either::Left(iter::repeat(Nibble::max())), | 684 | 0 | ops::Bound::Excluded(end_key) => either::Right(end_key.chain(None)), | 685 | 0 | ops::Bound::Included(end_key) => either::Right(end_key.chain(Some(Nibble::zero()))), | 686 | | } | 687 | 6.32M | .peekable(); | 688 | | | 689 | | // The user passed `Excluded(&[])`. Return an empty range. | 690 | 6.32M | if end_key.peek().is_none() { | 691 | 0 | return either::Right(iter::empty()); | 692 | 6.32M | } | 693 | | | 694 | | // The code below creates a variable named `iter`. This `iter` represents the cursor | 695 | | // where the iterator is. | 696 | | // `iter` also contains an optional nibble. If this optional nibble is `None`, the | 697 | | // iteration is currently at the node itself. If it is `Some`, the iteration isn't at the | 698 | | // node itself but at its child of the given nibble (which potentially doesn't exist). | 699 | | // If it is `Some(None)`, then the iteration is right after the last children of the node. | 700 | | // In other words, `Some(None)` represents an overflow. | 701 | 6.32M | let mut iter: (usize, Option<Option<Nibble>>) = match self.root_index { | 702 | 6.32M | Some(idx) => (idx, None), | 703 | | None => { | 704 | | // Trie is empty. Special case. | 705 | 0 | return either::Right(iter::empty()); | 706 | | } | 707 | | }; | 708 | | | 709 | | // Equal to `len(key(iter)) - len(key(iter) ∩ end_key)`. In other words, the number of | 710 | | // nibbles at the end of `iter`'s key that do not match the end key. This also includes | 711 | | // the optional nibble within `iter` if any. | 712 | 6.32M | let mut iter_key_nibbles_extra: usize = 0; | 713 | | | 714 | | // Transform `start_bound` into something more simple to process. | 715 | 6.32M | let (mut start_key, start_key_is_inclusive) = match start_bound { | 716 | 0 | ops::Bound::Unbounded => (either::Right(iter::empty()), true), | 717 | 6.32M | ops::Bound::Included(k) => (either::Left(k), true), | 718 | 0 | ops::Bound::Excluded(k) => (either::Left(k), false), | 719 | | }; | 720 | | | 721 | | // Iterate down the tree, updating the variables above. At each iteration, one of the | 722 | | // three following is true: | 723 | | // | 724 | | // - `iter` is inferior or inferior or equal (depending on `start_key_is_inclusive`) to | 725 | | // `start_key`. | 726 | | // - `iter` is the first node that is superior or strictly superior (depending on | 727 | | // `start_key_is_inclusive`) to `start_key`. | 728 | | // - `iter` points to a non-existing node that is inferior/inferior-or-equal to | 729 | | // `start_key`, but is right before the first node that is superior/strictly superior to | 730 | | // `start_key`. | 731 | | // | 732 | | // As soon as we reach one of the last two conditions, we stop iterating, as it means | 733 | | // that `iter` is at the correct position. | 734 | | 'start_search: loop { | 735 | 7.83M | debug_assert!(iter.1.is_none()); | 736 | 7.83M | let iter_node = self.nodes.get(iter.0).unwrap(); | 737 | | | 738 | | // Compare the nibbles at the front of `start_key` with the ones of `iter_node`. | 739 | | // Consumes the nibbles at the start of `start_key`. | 740 | 7.83M | let pk_compare = { | 741 | 7.83M | let mut result = cmp::Ordering::Equal; | 742 | 7.83M | for iter_node_pk_nibble2.97M in iter_node.partial_key.iter() { | 743 | 2.97M | match start_key | 744 | 2.97M | .next() | 745 | 2.97M | .map(|nibble| nibble.cmp(iter_node_pk_nibble)) | 746 | | { | 747 | | None | Some(cmp::Ordering::Less) => { | 748 | 351k | result = cmp::Ordering::Less; | 749 | 351k | break; | 750 | | } | 751 | 2.33M | Some(cmp::Ordering::Equal) => {} | 752 | | Some(cmp::Ordering::Greater) => { | 753 | 290k | result = cmp::Ordering::Greater; | 754 | 290k | break; | 755 | | } | 756 | | } | 757 | | } | 758 | 7.83M | result | 759 | | }; | 760 | | | 761 | 7.83M | match pk_compare { | 762 | | cmp::Ordering::Less | cmp::Ordering::Equal => { | 763 | | // Update the value of `iter_key_nibbles_extra` to take the current value | 764 | | // of `iter` into account, as it hasn't been done yet. | 765 | 7.54M | for iter_node_pk_nibble3.36M in iter_node.partial_key.iter().cloned() { | 766 | 3.36M | if iter_key_nibbles_extra == 0 | 767 | 72.3k | && iter_node_pk_nibble == *end_key.peek().unwrap() | 768 | | { | 769 | 6.45k | let _ = end_key.next(); | 770 | | // `iter` is already past the end bound. Return an empty range. | 771 | 6.45k | if end_key.peek().is_none() { | 772 | 0 | return either::Right(iter::empty()); | 773 | 6.45k | } | 774 | 3.36M | } else if iter_key_nibbles_extra == 0 | 775 | 65.8k | && iter_node_pk_nibble > *end_key.peek().unwrap() | 776 | | { | 777 | 0 | return either::Right(iter::empty()); | 778 | 3.36M | } else { | 779 | 3.36M | iter_key_nibbles_extra += 1; | 780 | 3.36M | } | 781 | | } | 782 | | | 783 | 7.54M | if pk_compare == cmp::Ordering::Less { | 784 | | // `iter` is strictly superior to `start_key`. `iter` is now at the | 785 | | // correct position. | 786 | 351k | break 'start_search; | 787 | 7.19M | } | 788 | | } | 789 | | cmp::Ordering::Greater => { | 790 | | // `iter` is strictly inferior to `start_key`, and all of its children will | 791 | | // also be strictly inferior to `start_key`. | 792 | | // Stop the search immediately after the current node in the parent. | 793 | 290k | let Some((parent, parent_nibble)) = iter_node.parent else { | 794 | 0 | return either::Right(iter::empty()); | 795 | | }; | 796 | 290k | let next_nibble = parent_nibble.checked_add(1); | 797 | 290k | if iter_key_nibbles_extra == 0 { | 798 | 18.7k | return either::Right(iter::empty()); | 799 | 272k | } | 800 | 272k | iter_key_nibbles_extra -= 1; | 801 | 272k | if iter_key_nibbles_extra == 0 && next_nibble271k == Some(*end_key271k .peek().unwrap()) | 802 | | { | 803 | 17.9k | let _ = end_key.next(); | 804 | | // `iter` is already past the end bound. Return an empty range. | 805 | 17.9k | if end_key.peek().is_none() { | 806 | 0 | return either::Right(iter::empty()); | 807 | 17.9k | } | 808 | 254k | } else { | 809 | 254k | iter_key_nibbles_extra += 1; | 810 | 254k | } | 811 | 272k | iter = (parent, Some(next_nibble)); | 812 | 272k | break 'start_search; | 813 | | } | 814 | | } | 815 | | | 816 | | // Remove the next nibble from `start_key` and update `iter` based on it. | 817 | 7.19M | if let Some(next_nibble7.15M ) = start_key.next() { | 818 | 7.15M | if iter_key_nibbles_extra == 0 && next_nibble6.29M == *end_key6.29M .peek().unwrap() { | 819 | 392k | let _ = end_key.next(); | 820 | | // `iter` is already past the end bound. Return an empty range. | 821 | 392k | if end_key.peek().is_none() { | 822 | 0 | return either::Right(iter::empty()); | 823 | 392k | } | 824 | 6.76M | } else if iter_key_nibbles_extra == 0 && next_nibble5.90M > *end_key5.90M .peek().unwrap() { | 825 | 0 | return either::Right(iter::empty()); | 826 | 6.76M | } else { | 827 | 6.76M | iter_key_nibbles_extra += 1; | 828 | 6.76M | } | 829 | | | 830 | 7.15M | if let Some(child1.51M ) = iter_node.children[usize::from(u8::from(next_nibble))] { | 831 | 1.51M | // Update `iter` and continue searching. | 832 | 1.51M | iter = (child, None); | 833 | 1.51M | } else { | 834 | | // `iter` is strictly inferior to `start_key`. | 835 | 5.63M | iter.1 = Some(Some(next_nibble)); | 836 | 5.63M | break 'start_search; | 837 | | } | 838 | | } else { | 839 | | // `iter.0` is an exact match with `start_key`. If the starting bound is | 840 | | // `Excluded`, we don't want to start iterating at `iter` but at `next(iter)`, | 841 | | // which we do by adding a zero nibble afterwards. | 842 | 41.1k | debug_assert!(iter.1.is_none()); | 843 | 41.1k | if !start_key_is_inclusive { | 844 | 0 | iter.1 = Some(Some(Nibble::zero())); | 845 | 0 | if iter_key_nibbles_extra == 0 && *end_key.peek().unwrap() == Nibble::zero() { | 846 | 0 | let _ = end_key.next(); | 847 | | // `iter` is already past the end bound. Return an empty range. | 848 | 0 | if end_key.peek().is_none() { | 849 | 0 | return either::Right(iter::empty()); | 850 | 0 | } | 851 | 0 | } else { | 852 | 0 | iter_key_nibbles_extra += 1; | 853 | 0 | } | 854 | 41.1k | } | 855 | | | 856 | 41.1k | break 'start_search; | 857 | | } | 858 | | } | 859 | | | 860 | | // `iter` is now at the correct position and we can start yielding nodes until we reach | 861 | | // the end. This is done in the iterator that is returned from the function. | 862 | | | 863 | 6.30M | either::Left(iter::from_fn(move || { | 864 | | loop { | 865 | | // `end_key` must never be empty, as otherwise the iteration has ended. | 866 | | // We return `None` instead of panicking, as it is legitimately possible to reach | 867 | | // this situation through some code paths. | 868 | | let _ = end_key.peek()?; | 869 | | | 870 | | // If `iter` points to an actual node, yield it and jump to the position right | 871 | | // after. | 872 | | let Some(iter_1) = iter.1 else { | 873 | | iter.1 = Some(Some(Nibble::zero())); | 874 | | if iter_key_nibbles_extra == 0 && *end_key.peek().unwrap() == Nibble::zero() { | 875 | | let _ = end_key.next(); | 876 | | } else { | 877 | | iter_key_nibbles_extra += 1; | 878 | | } | 879 | | return Some(iter.0); | 880 | | }; | 881 | | | 882 | | let node = self.nodes.get(iter.0).unwrap(); | 883 | | | 884 | | if let Some(child) = | 885 | | iter_1.and_then(|iter_1| node.children[usize::from(u8::from(iter_1))]) | 886 | | { | 887 | | // `child` might be after the end bound if its partial key is superior or | 888 | | // equal to the `end_key`. | 889 | | for child_pk_nibble in self.nodes.get(child).unwrap().partial_key.iter() { | 890 | | match child_pk_nibble.cmp(end_key.peek().unwrap()) { | 891 | | cmp::Ordering::Greater if iter_key_nibbles_extra == 0 => return None, | 892 | | cmp::Ordering::Greater | cmp::Ordering::Less => { | 893 | | iter_key_nibbles_extra += 1; | 894 | | } | 895 | | cmp::Ordering::Equal if iter_key_nibbles_extra != 0 => { | 896 | | iter_key_nibbles_extra += 1; | 897 | | } | 898 | | cmp::Ordering::Equal => { | 899 | | debug_assert_eq!(iter_key_nibbles_extra, 0); | 900 | | let _ = end_key.next(); | 901 | | let _ = end_key.peek()?; | 902 | | } | 903 | | } | 904 | | } | 905 | | | 906 | | iter = (child, None); | 907 | | } else if iter_key_nibbles_extra == 0 | 908 | | || (iter_key_nibbles_extra == 1 | 909 | | && iter_1.map_or(true, |iter_1| iter_1 > *end_key.peek().unwrap())) | 910 | | { | 911 | | return None; | 912 | | } else if let Some(child_index) = iter_1.and_then(|iter_1| { | 913 | | node.children[(usize::from(u8::from(iter_1))) | 914 | | ..=usize::from(u8::from(if iter_key_nibbles_extra == 1 { | 915 | | *end_key.peek().unwrap() | 916 | | } else { | 917 | | Nibble::max() | 918 | | }))] | 919 | | .iter() | 920 | | .position(|c| c.is_some()) | 921 | | }) { | 922 | | let child_nibble = Nibble::try_from( | 923 | | u8::try_from(usize::from(u8::from(iter_1.unwrap())) + child_index).unwrap(), | 924 | | ) | 925 | | .unwrap(); | 926 | | | 927 | | if iter_key_nibbles_extra == 1 && child_nibble == *end_key.peek().unwrap() { | 928 | | iter_key_nibbles_extra = 0; | 929 | | let _ = end_key.next(); | 930 | | } | 931 | | | 932 | | iter.1 = Some(Some(child_nibble)); | 933 | | } else { | 934 | | // `iter` has no child. Go to the parent. | 935 | | let node = self.nodes.get(iter.0).unwrap(); | 936 | | | 937 | | // End the iterator if we were about to jump out of the end bound. | 938 | | if iter_key_nibbles_extra < 2 + node.partial_key.len() { | 939 | | return None; | 940 | | } | 941 | | | 942 | | let Some((parent_node_index, parent_nibble_direction)) = node.parent else { | 943 | | return None; | 944 | | }; | 945 | | iter_key_nibbles_extra -= 2; | 946 | | iter_key_nibbles_extra -= node.partial_key.len(); | 947 | | let next_sibling_nibble = parent_nibble_direction.checked_add(1); | 948 | | if iter_key_nibbles_extra == 0 | 949 | | && next_sibling_nibble == Some(*end_key.peek().unwrap()) | 950 | | { | 951 | | let _ = end_key.next(); | 952 | | } else { | 953 | | iter_key_nibbles_extra += 1; | 954 | | } | 955 | | iter = (parent_node_index, Some(next_sibling_nibble)); | 956 | | } | 957 | | } | 958 | | })) | 959 | 6.32M | } |
_RINvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB3_13TrieStructureuE11range_innerINtNtNtNtCs66KPHxksi63_4core4iter8adapters6copied6CopiedINtNtNtB1x_5slice4iter4IterNtNtB5_6nibble6NibbleEEB1o_EB7_ Line | Count | Source | 668 | 262k | fn range_inner<'a>( | 669 | 262k | &'a self, | 670 | 262k | start_bound: ops::Bound<impl Iterator<Item = Nibble>>, | 671 | 262k | end_bound: ops::Bound<impl Iterator<Item = Nibble> + 'a>, | 672 | 262k | ) -> impl Iterator<Item = usize> { | 673 | | // Start by processing the end bound to obtain an "end key". | 674 | | // This end key is always assumed to be excluded. In other words, only keys strictly | 675 | | // inferior to the end key are returned. If the user provides `Included`, we modify the key | 676 | | // and append a dummy `0` nibble at the end of it. If the user provides `Unbounded`, we use | 677 | | // an infinite-sized key so that every finite key is always inferior to it. | 678 | | // | 679 | | // The algorithm later down this function will pop nibbles from the start of `end_key`. | 680 | | // Because `end_key` is always excluded, this iterator must always contain at least one | 681 | | // nibble, otherwise the iteration should have ended. | 682 | 262k | let mut end_key = match end_bound { | 683 | 87.4k | ops::Bound::Unbounded => either::Left(iter::repeat(Nibble::max())), | 684 | 87.0k | ops::Bound::Excluded(end_key) => either::Right(end_key.chain(None)), | 685 | 87.5k | ops::Bound::Included(end_key) => either::Right(end_key.chain(Some(Nibble::zero()))), | 686 | | } | 687 | 262k | .peekable(); | 688 | | | 689 | | // The user passed `Excluded(&[])`. Return an empty range. | 690 | 262k | if end_key.peek().is_none() { | 691 | 14.3k | return either::Right(iter::empty()); | 692 | 247k | } | 693 | | | 694 | | // The code below creates a variable named `iter`. This `iter` represents the cursor | 695 | | // where the iterator is. | 696 | | // `iter` also contains an optional nibble. If this optional nibble is `None`, the | 697 | | // iteration is currently at the node itself. If it is `Some`, the iteration isn't at the | 698 | | // node itself but at its child of the given nibble (which potentially doesn't exist). | 699 | | // If it is `Some(None)`, then the iteration is right after the last children of the node. | 700 | | // In other words, `Some(None)` represents an overflow. | 701 | 247k | let mut iter247k : (usize, Option<Option<Nibble>>)247k = match self.root_index { | 702 | 247k | Some(idx) => (idx, None), | 703 | | None => { | 704 | | // Trie is empty. Special case. | 705 | 242 | return either::Right(iter::empty()); | 706 | | } | 707 | | }; | 708 | | | 709 | | // Equal to `len(key(iter)) - len(key(iter) ∩ end_key)`. In other words, the number of | 710 | | // nibbles at the end of `iter`'s key that do not match the end key. This also includes | 711 | | // the optional nibble within `iter` if any. | 712 | 247k | let mut iter_key_nibbles_extra: usize = 0; | 713 | | | 714 | | // Transform `start_bound` into something more simple to process. | 715 | 247k | let (mut start_key, start_key_is_inclusive) = match start_bound { | 716 | 82.8k | ops::Bound::Unbounded => (either::Right(iter::empty()), true), | 717 | 82.5k | ops::Bound::Included(k) => (either::Left(k), true), | 718 | 82.2k | ops::Bound::Excluded(k) => (either::Left(k), false), | 719 | | }; | 720 | | | 721 | | // Iterate down the tree, updating the variables above. At each iteration, one of the | 722 | | // three following is true: | 723 | | // | 724 | | // - `iter` is inferior or inferior or equal (depending on `start_key_is_inclusive`) to | 725 | | // `start_key`. | 726 | | // - `iter` is the first node that is superior or strictly superior (depending on | 727 | | // `start_key_is_inclusive`) to `start_key`. | 728 | | // - `iter` points to a non-existing node that is inferior/inferior-or-equal to | 729 | | // `start_key`, but is right before the first node that is superior/strictly superior to | 730 | | // `start_key`. | 731 | | // | 732 | | // As soon as we reach one of the last two conditions, we stop iterating, as it means | 733 | | // that `iter` is at the correct position. | 734 | | 'start_search: loop { | 735 | 296k | debug_assert!(iter.1.is_none()); | 736 | 296k | let iter_node = self.nodes.get(iter.0).unwrap(); | 737 | | | 738 | | // Compare the nibbles at the front of `start_key` with the ones of `iter_node`. | 739 | | // Consumes the nibbles at the start of `start_key`. | 740 | 296k | let pk_compare = { | 741 | 296k | let mut result = cmp::Ordering::Equal; | 742 | 296k | for iter_node_pk_nibble23.0k in iter_node.partial_key.iter() { | 743 | 23.0k | match start_key | 744 | 23.0k | .next() | 745 | 23.0k | .map(|nibble| nibble.cmp(iter_node_pk_nibble)) | 746 | | { | 747 | | None | Some(cmp::Ordering::Less) => { | 748 | 13.4k | result = cmp::Ordering::Less; | 749 | 13.4k | break; | 750 | | } | 751 | 1.09k | Some(cmp::Ordering::Equal) => {} | 752 | | Some(cmp::Ordering::Greater) => { | 753 | 8.45k | result = cmp::Ordering::Greater; | 754 | 8.45k | break; | 755 | | } | 756 | | } | 757 | | } | 758 | 296k | result | 759 | | }; | 760 | | | 761 | 296k | match pk_compare { | 762 | | cmp::Ordering::Less | cmp::Ordering::Equal => { | 763 | | // Update the value of `iter_key_nibbles_extra` to take the current value | 764 | | // of `iter` into account, as it hasn't been done yet. | 765 | 287k | for iter_node_pk_nibble20.3k in iter_node.partial_key.iter().cloned() { | 766 | 20.3k | if iter_key_nibbles_extra == 0 | 767 | 2.09k | && iter_node_pk_nibble == *end_key.peek().unwrap() | 768 | | { | 769 | 108 | let _ = end_key.next(); | 770 | | // `iter` is already past the end bound. Return an empty range. | 771 | 108 | if end_key.peek().is_none() { | 772 | 13 | return either::Right(iter::empty()); | 773 | 95 | } | 774 | 20.2k | } else if iter_key_nibbles_extra == 0 | 775 | 1.98k | && iter_node_pk_nibble > *end_key.peek().unwrap() | 776 | | { | 777 | 792 | return either::Right(iter::empty()); | 778 | 19.4k | } else { | 779 | 19.4k | iter_key_nibbles_extra += 1; | 780 | 19.4k | } | 781 | | } | 782 | | | 783 | 286k | if pk_compare == cmp::Ordering::Less { | 784 | | // `iter` is strictly superior to `start_key`. `iter` is now at the | 785 | | // correct position. | 786 | 12.6k | break 'start_search; | 787 | 274k | } | 788 | | } | 789 | | cmp::Ordering::Greater => { | 790 | | // `iter` is strictly inferior to `start_key`, and all of its children will | 791 | | // also be strictly inferior to `start_key`. | 792 | | // Stop the search immediately after the current node in the parent. | 793 | 8.45k | let Some((parent8.06k , parent_nibble8.06k )) = iter_node.parent else { | 794 | 395 | return either::Right(iter::empty()); | 795 | | }; | 796 | 8.06k | let next_nibble = parent_nibble.checked_add(1); | 797 | 8.06k | if iter_key_nibbles_extra == 0 { | 798 | 606 | return either::Right(iter::empty()); | 799 | 7.45k | } | 800 | 7.45k | iter_key_nibbles_extra -= 1; | 801 | 7.45k | if iter_key_nibbles_extra == 0 && next_nibble6.87k == Some(*end_key6.87k .peek().unwrap()) | 802 | | { | 803 | 654 | let _ = end_key.next(); | 804 | | // `iter` is already past the end bound. Return an empty range. | 805 | 654 | if end_key.peek().is_none() { | 806 | 30 | return either::Right(iter::empty()); | 807 | 624 | } | 808 | 6.80k | } else { | 809 | 6.80k | iter_key_nibbles_extra += 1; | 810 | 6.80k | } | 811 | 7.42k | iter = (parent, Some(next_nibble)); | 812 | 7.42k | break 'start_search; | 813 | | } | 814 | | } | 815 | | | 816 | | // Remove the next nibble from `start_key` and update `iter` based on it. | 817 | 274k | if let Some(next_nibble158k ) = start_key.next() { | 818 | 158k | if iter_key_nibbles_extra == 0 && next_nibble138k == *end_key138k .peek().unwrap() { | 819 | 8.72k | let _ = end_key.next(); | 820 | | // `iter` is already past the end bound. Return an empty range. | 821 | 8.72k | if end_key.peek().is_none() { | 822 | 994 | return either::Right(iter::empty()); | 823 | 7.72k | } | 824 | 150k | } else if iter_key_nibbles_extra == 0 && next_nibble129k > *end_key129k .peek().unwrap() { | 825 | 45.6k | return either::Right(iter::empty()); | 826 | 104k | } else { | 827 | 104k | iter_key_nibbles_extra += 1; | 828 | 104k | } | 829 | | | 830 | 112k | if let Some(child48.5k ) = iter_node.children[usize::from(u8::from(next_nibble))] { | 831 | 48.5k | // Update `iter` and continue searching. | 832 | 48.5k | iter = (child, None); | 833 | 48.5k | } else { | 834 | | // `iter` is strictly inferior to `start_key`. | 835 | 63.6k | iter.1 = Some(Some(next_nibble)); | 836 | 63.6k | break 'start_search; | 837 | | } | 838 | | } else { | 839 | | // `iter.0` is an exact match with `start_key`. If the starting bound is | 840 | | // `Excluded`, we don't want to start iterating at `iter` but at `next(iter)`, | 841 | | // which we do by adding a zero nibble afterwards. | 842 | 115k | debug_assert!(iter.1.is_none()); | 843 | 115k | if !start_key_is_inclusive { | 844 | 16.4k | iter.1 = Some(Some(Nibble::zero())); | 845 | 16.4k | if iter_key_nibbles_extra == 0 && *13.8k end_key13.8k .peek().unwrap() == Nibble::zero() { | 846 | 1.35k | let _ = end_key.next(); | 847 | | // `iter` is already past the end bound. Return an empty range. | 848 | 1.35k | if end_key.peek().is_none() { | 849 | 885 | return either::Right(iter::empty()); | 850 | 469 | } | 851 | 15.1k | } else { | 852 | 15.1k | iter_key_nibbles_extra += 1; | 853 | 15.1k | } | 854 | 98.8k | } | 855 | | | 856 | 114k | break 'start_search; | 857 | | } | 858 | | } | 859 | | | 860 | | // `iter` is now at the correct position and we can start yielding nodes until we reach | 861 | | // the end. This is done in the iterator that is returned from the function. | 862 | | | 863 | 198k | either::Left(iter::from_fn(move || { | 864 | | loop { | 865 | | // `end_key` must never be empty, as otherwise the iteration has ended. | 866 | | // We return `None` instead of panicking, as it is legitimately possible to reach | 867 | | // this situation through some code paths. | 868 | | let _ = end_key.peek()?; | 869 | | | 870 | | // If `iter` points to an actual node, yield it and jump to the position right | 871 | | // after. | 872 | | let Some(iter_1) = iter.1 else { | 873 | | iter.1 = Some(Some(Nibble::zero())); | 874 | | if iter_key_nibbles_extra == 0 && *end_key.peek().unwrap() == Nibble::zero() { | 875 | | let _ = end_key.next(); | 876 | | } else { | 877 | | iter_key_nibbles_extra += 1; | 878 | | } | 879 | | return Some(iter.0); | 880 | | }; | 881 | | | 882 | | let node = self.nodes.get(iter.0).unwrap(); | 883 | | | 884 | | if let Some(child) = | 885 | | iter_1.and_then(|iter_1| node.children[usize::from(u8::from(iter_1))]) | 886 | | { | 887 | | // `child` might be after the end bound if its partial key is superior or | 888 | | // equal to the `end_key`. | 889 | | for child_pk_nibble in self.nodes.get(child).unwrap().partial_key.iter() { | 890 | | match child_pk_nibble.cmp(end_key.peek().unwrap()) { | 891 | | cmp::Ordering::Greater if iter_key_nibbles_extra == 0 => return None, | 892 | | cmp::Ordering::Greater | cmp::Ordering::Less => { | 893 | | iter_key_nibbles_extra += 1; | 894 | | } | 895 | | cmp::Ordering::Equal if iter_key_nibbles_extra != 0 => { | 896 | | iter_key_nibbles_extra += 1; | 897 | | } | 898 | | cmp::Ordering::Equal => { | 899 | | debug_assert_eq!(iter_key_nibbles_extra, 0); | 900 | | let _ = end_key.next(); | 901 | | let _ = end_key.peek()?; | 902 | | } | 903 | | } | 904 | | } | 905 | | | 906 | | iter = (child, None); | 907 | | } else if iter_key_nibbles_extra == 0 | 908 | | || (iter_key_nibbles_extra == 1 | 909 | | && iter_1.map_or(true, |iter_1| iter_1 > *end_key.peek().unwrap())) | 910 | | { | 911 | | return None; | 912 | | } else if let Some(child_index) = iter_1.and_then(|iter_1| { | 913 | | node.children[(usize::from(u8::from(iter_1))) | 914 | | ..=usize::from(u8::from(if iter_key_nibbles_extra == 1 { | 915 | | *end_key.peek().unwrap() | 916 | | } else { | 917 | | Nibble::max() | 918 | | }))] | 919 | | .iter() | 920 | | .position(|c| c.is_some()) | 921 | | }) { | 922 | | let child_nibble = Nibble::try_from( | 923 | | u8::try_from(usize::from(u8::from(iter_1.unwrap())) + child_index).unwrap(), | 924 | | ) | 925 | | .unwrap(); | 926 | | | 927 | | if iter_key_nibbles_extra == 1 && child_nibble == *end_key.peek().unwrap() { | 928 | | iter_key_nibbles_extra = 0; | 929 | | let _ = end_key.next(); | 930 | | } | 931 | | | 932 | | iter.1 = Some(Some(child_nibble)); | 933 | | } else { | 934 | | // `iter` has no child. Go to the parent. | 935 | | let node = self.nodes.get(iter.0).unwrap(); | 936 | | | 937 | | // End the iterator if we were about to jump out of the end bound. | 938 | | if iter_key_nibbles_extra < 2 + node.partial_key.len() { | 939 | | return None; | 940 | | } | 941 | | | 942 | | let Some((parent_node_index, parent_nibble_direction)) = node.parent else { | 943 | | return None; | 944 | | }; | 945 | | iter_key_nibbles_extra -= 2; | 946 | | iter_key_nibbles_extra -= node.partial_key.len(); | 947 | | let next_sibling_nibble = parent_nibble_direction.checked_add(1); | 948 | | if iter_key_nibbles_extra == 0 | 949 | | && next_sibling_nibble == Some(*end_key.peek().unwrap()) | 950 | | { | 951 | | let _ = end_key.next(); | 952 | | } else { | 953 | | iter_key_nibbles_extra += 1; | 954 | | } | 955 | | iter = (parent_node_index, Some(next_sibling_nibble)); | 956 | | } | 957 | | } | 958 | | })) | 959 | 262k | } |
Unexecuted instantiation: _RINvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB3_13TrieStructurepE11range_innerppEB7_ |
960 | | |
961 | | /// Iterates over all nodes of the trie in a lexicographic order. |
962 | 3.33M | fn all_node_lexicographic_ordered(&self) -> impl Iterator<Item = usize> { |
963 | 9.51M | fn ancestry_order_next<TUd>(tree: &TrieStructure<TUd>, node_index: usize) -> Option<usize> { |
964 | 9.51M | if let Some(first_child3.22M ) = tree |
965 | 9.51M | .nodes |
966 | 9.51M | .get(node_index) |
967 | 9.51M | .unwrap() |
968 | 9.51M | .children |
969 | 9.51M | .iter() |
970 | 9.51M | .find_map(|c| *c) |
971 | | { |
972 | 3.22M | return Some(first_child); |
973 | 6.29M | } |
974 | | |
975 | 6.29M | if let Some(next_sibling2.96M ) = tree.next_sibling(node_index) { |
976 | 2.96M | return Some(next_sibling); |
977 | 3.32M | } |
978 | | |
979 | 3.32M | let mut return_value = tree.nodes[node_index].parent.map(|(i, _)| i); |
980 | 5.46M | while let Some(idx2.66M ) = return_value { |
981 | 2.66M | if let Some(next_sibling520k ) = tree.next_sibling(idx) { |
982 | 520k | return Some(next_sibling); |
983 | 2.14M | } |
984 | 2.14M | return_value = tree.nodes[idx].parent.map(|(i, _)| i); |
985 | | } |
986 | 2.80M | return_value |
987 | 9.51M | } _RINvNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructurepE30all_node_lexicographic_ordered19ancestry_order_nextTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB26_NtNtB7_9trie_node17MerkleValueOutputEEEB9_ Line | Count | Source | 963 | 4.63M | fn ancestry_order_next<TUd>(tree: &TrieStructure<TUd>, node_index: usize) -> Option<usize> { | 964 | 4.63M | if let Some(first_child1.61M ) = tree | 965 | 4.63M | .nodes | 966 | 4.63M | .get(node_index) | 967 | 4.63M | .unwrap() | 968 | 4.63M | .children | 969 | 4.63M | .iter() | 970 | 4.63M | .find_map(|c| *c) | 971 | | { | 972 | 1.61M | return Some(first_child); | 973 | 3.02M | } | 974 | | | 975 | 3.02M | if let Some(next_sibling1.24M ) = tree.next_sibling(node_index) { | 976 | 1.24M | return Some(next_sibling); | 977 | 1.77M | } | 978 | | | 979 | 1.77M | let mut return_value = tree.nodes[node_index].parent.map(|(i, _)| i); | 980 | 2.97M | while let Some(idx1.23M ) = return_value { | 981 | 1.23M | if let Some(next_sibling34.4k ) = tree.next_sibling(idx) { | 982 | 34.4k | return Some(next_sibling); | 983 | 1.19M | } | 984 | 1.19M | return_value = tree.nodes[idx].parent.map(|(i, _)| i); | 985 | | } | 986 | 1.73M | return_value | 987 | 4.63M | } |
_RINvNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructurepE30all_node_lexicographic_ordered19ancestry_order_nextTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB26_NtNtB7_9trie_node17MerkleValueOutputEEEB9_ Line | Count | Source | 963 | 936k | fn ancestry_order_next<TUd>(tree: &TrieStructure<TUd>, node_index: usize) -> Option<usize> { | 964 | 936k | if let Some(first_child236k ) = tree | 965 | 936k | .nodes | 966 | 936k | .get(node_index) | 967 | 936k | .unwrap() | 968 | 936k | .children | 969 | 936k | .iter() | 970 | 936k | .find_map(|c| *c) | 971 | | { | 972 | 236k | return Some(first_child); | 973 | 700k | } | 974 | | | 975 | 700k | if let Some(next_sibling467k ) = tree.next_sibling(node_index) { | 976 | 467k | return Some(next_sibling); | 977 | 232k | } | 978 | | | 979 | 232k | let mut return_value = tree.nodes[node_index].parent.map(|(i, _)| i); | 980 | 367k | while let Some(idx236k ) = return_value { | 981 | 236k | if let Some(next_sibling101k ) = tree.next_sibling(idx) { | 982 | 101k | return Some(next_sibling); | 983 | 134k | } | 984 | 134k | return_value = tree.nodes[idx].parent.map(|(i, _)| i); | 985 | | } | 986 | 131k | return_value | 987 | 936k | } |
_RINvNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructurepE30all_node_lexicographic_ordered19ancestry_order_nextuEB9_ Line | Count | Source | 963 | 3.94M | fn ancestry_order_next<TUd>(tree: &TrieStructure<TUd>, node_index: usize) -> Option<usize> { | 964 | 3.94M | if let Some(first_child1.37M ) = tree | 965 | 3.94M | .nodes | 966 | 3.94M | .get(node_index) | 967 | 3.94M | .unwrap() | 968 | 3.94M | .children | 969 | 3.94M | .iter() | 970 | 3.94M | .find_map(|c| *c) | 971 | | { | 972 | 1.37M | return Some(first_child); | 973 | 2.56M | } | 974 | | | 975 | 2.56M | if let Some(next_sibling1.25M ) = tree.next_sibling(node_index) { | 976 | 1.25M | return Some(next_sibling); | 977 | 1.31M | } | 978 | | | 979 | 1.31M | let mut return_value = tree.nodes[node_index].parent.map(|(i, _)| i); | 980 | 2.12M | while let Some(idx1.19M ) = return_value { | 981 | 1.19M | if let Some(next_sibling383k ) = tree.next_sibling(idx) { | 982 | 383k | return Some(next_sibling); | 983 | 808k | } | 984 | 808k | return_value = tree.nodes[idx].parent.map(|(i, _)| i); | 985 | | } | 986 | 932k | return_value | 987 | 3.94M | } |
Unexecuted instantiation: _RINvNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13TrieStructurepE30all_node_lexicographic_ordered19ancestry_order_nextTINtNtCs66KPHxksi63_4core6option6OptionRShEIB26_NtNtB7_9trie_node17MerkleValueOutputEEECs4ISLcsFEGeP_6author Unexecuted instantiation: _RINvNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13TrieStructurepE30all_node_lexicographic_ordered19ancestry_order_nextpEB9_ _RINvNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13TrieStructurepE30all_node_lexicographic_ordered19ancestry_order_nextTINtNtCs66KPHxksi63_4core6option6OptionRShEIB26_NtNtB7_9trie_node17MerkleValueOutputEEECs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 963 | 96 | fn ancestry_order_next<TUd>(tree: &TrieStructure<TUd>, node_index: usize) -> Option<usize> { | 964 | 96 | if let Some(first_child26 ) = tree | 965 | 96 | .nodes | 966 | 96 | .get(node_index) | 967 | 96 | .unwrap() | 968 | 96 | .children | 969 | 96 | .iter() | 970 | 96 | .find_map(|c| *c) | 971 | | { | 972 | 26 | return Some(first_child); | 973 | 70 | } | 974 | | | 975 | 70 | if let Some(next_sibling46 ) = tree.next_sibling(node_index) { | 976 | 46 | return Some(next_sibling); | 977 | 24 | } | 978 | | | 979 | 24 | let mut return_value = tree.nodes[node_index].parent.map(|(i, _)| i); | 980 | 28 | while let Some(idx26 ) = return_value { | 981 | 26 | if let Some(next_sibling22 ) = tree.next_sibling(idx) { | 982 | 22 | return Some(next_sibling); | 983 | 4 | } | 984 | 4 | return_value = tree.nodes[idx].parent.map(|(i, _)| i); | 985 | | } | 986 | 2 | return_value | 987 | 96 | } |
_RINvNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13TrieStructurepE30all_node_lexicographic_ordered19ancestry_order_nextTINtNtCs66KPHxksi63_4core6option6OptionRShEIB26_NtNtB7_9trie_node17MerkleValueOutputEEECs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 963 | 912 | fn ancestry_order_next<TUd>(tree: &TrieStructure<TUd>, node_index: usize) -> Option<usize> { | 964 | 912 | if let Some(first_child247 ) = tree | 965 | 912 | .nodes | 966 | 912 | .get(node_index) | 967 | 912 | .unwrap() | 968 | 912 | .children | 969 | 912 | .iter() | 970 | 912 | .find_map(|c| *c) | 971 | | { | 972 | 247 | return Some(first_child); | 973 | 665 | } | 974 | | | 975 | 665 | if let Some(next_sibling437 ) = tree.next_sibling(node_index) { | 976 | 437 | return Some(next_sibling); | 977 | 228 | } | 978 | | | 979 | 228 | let mut return_value = tree.nodes[node_index].parent.map(|(i, _)| i); | 980 | 266 | while let Some(idx247 ) = return_value { | 981 | 247 | if let Some(next_sibling209 ) = tree.next_sibling(idx) { | 982 | 209 | return Some(next_sibling); | 983 | 38 | } | 984 | 38 | return_value = tree.nodes[idx].parent.map(|(i, _)| i); | 985 | | } | 986 | 19 | return_value | 987 | 912 | } |
|
988 | | |
989 | 9.51M | iter::successors3.33M (self.root_index3.33M , move |n| ancestry_order_next(self, *n)) _RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB6_16TrieEntryVersionEEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE30all_node_lexicographic_ordered0B8_ Line | Count | Source | 989 | 936k | iter::successors(self.root_index, move |n| ancestry_order_next(self, *n)) |
_RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE30all_node_lexicographic_ordered0B8_ Line | Count | Source | 989 | 4.63M | iter::successors(self.root_index, move |n| ancestry_order_next(self, *n)) |
_RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureuE30all_node_lexicographic_ordered0B8_ Line | Count | Source | 989 | 3.94M | iter::successors(self.root_index, move |n| ancestry_order_next(self, *n)) |
Unexecuted instantiation: _RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE30all_node_lexicographic_ordered0Cs4ISLcsFEGeP_6author Unexecuted instantiation: _RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructurepE30all_node_lexicographic_ordered0B8_ _RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE30all_node_lexicographic_ordered0Cs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 989 | 96 | iter::successors(self.root_index, move |n| ancestry_order_next(self, *n)) |
_RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE30all_node_lexicographic_ordered0Cs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 989 | 912 | iter::successors(self.root_index, move |n| ancestry_order_next(self, *n)) |
|
990 | 3.33M | } _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE30all_node_lexicographic_orderedB6_ Line | Count | Source | 962 | 2.09M | fn all_node_lexicographic_ordered(&self) -> impl Iterator<Item = usize> { | 963 | | fn ancestry_order_next<TUd>(tree: &TrieStructure<TUd>, node_index: usize) -> Option<usize> { | 964 | | if let Some(first_child) = tree | 965 | | .nodes | 966 | | .get(node_index) | 967 | | .unwrap() | 968 | | .children | 969 | | .iter() | 970 | | .find_map(|c| *c) | 971 | | { | 972 | | return Some(first_child); | 973 | | } | 974 | | | 975 | | if let Some(next_sibling) = tree.next_sibling(node_index) { | 976 | | return Some(next_sibling); | 977 | | } | 978 | | | 979 | | let mut return_value = tree.nodes[node_index].parent.map(|(i, _)| i); | 980 | | while let Some(idx) = return_value { | 981 | | if let Some(next_sibling) = tree.next_sibling(idx) { | 982 | | return Some(next_sibling); | 983 | | } | 984 | | return_value = tree.nodes[idx].parent.map(|(i, _)| i); | 985 | | } | 986 | | return_value | 987 | | } | 988 | | | 989 | 2.09M | iter::successors(self.root_index, move |n| ancestry_order_next(self, *n)) | 990 | 2.09M | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureuE30all_node_lexicographic_orderedB6_ Line | Count | Source | 962 | 1.10M | fn all_node_lexicographic_ordered(&self) -> impl Iterator<Item = usize> { | 963 | | fn ancestry_order_next<TUd>(tree: &TrieStructure<TUd>, node_index: usize) -> Option<usize> { | 964 | | if let Some(first_child) = tree | 965 | | .nodes | 966 | | .get(node_index) | 967 | | .unwrap() | 968 | | .children | 969 | | .iter() | 970 | | .find_map(|c| *c) | 971 | | { | 972 | | return Some(first_child); | 973 | | } | 974 | | | 975 | | if let Some(next_sibling) = tree.next_sibling(node_index) { | 976 | | return Some(next_sibling); | 977 | | } | 978 | | | 979 | | let mut return_value = tree.nodes[node_index].parent.map(|(i, _)| i); | 980 | | while let Some(idx) = return_value { | 981 | | if let Some(next_sibling) = tree.next_sibling(idx) { | 982 | | return Some(next_sibling); | 983 | | } | 984 | | return_value = tree.nodes[idx].parent.map(|(i, _)| i); | 985 | | } | 986 | | return_value | 987 | | } | 988 | | | 989 | 1.10M | iter::successors(self.root_index, move |n| ancestry_order_next(self, *n)) | 990 | 1.10M | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB4_16TrieEntryVersionEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE30all_node_lexicographic_orderedB6_ Line | Count | Source | 962 | 131k | fn all_node_lexicographic_ordered(&self) -> impl Iterator<Item = usize> { | 963 | | fn ancestry_order_next<TUd>(tree: &TrieStructure<TUd>, node_index: usize) -> Option<usize> { | 964 | | if let Some(first_child) = tree | 965 | | .nodes | 966 | | .get(node_index) | 967 | | .unwrap() | 968 | | .children | 969 | | .iter() | 970 | | .find_map(|c| *c) | 971 | | { | 972 | | return Some(first_child); | 973 | | } | 974 | | | 975 | | if let Some(next_sibling) = tree.next_sibling(node_index) { | 976 | | return Some(next_sibling); | 977 | | } | 978 | | | 979 | | let mut return_value = tree.nodes[node_index].parent.map(|(i, _)| i); | 980 | | while let Some(idx) = return_value { | 981 | | if let Some(next_sibling) = tree.next_sibling(idx) { | 982 | | return Some(next_sibling); | 983 | | } | 984 | | return_value = tree.nodes[idx].parent.map(|(i, _)| i); | 985 | | } | 986 | | return_value | 987 | | } | 988 | | | 989 | 131k | iter::successors(self.root_index, move |n| ancestry_order_next(self, *n)) | 990 | 131k | } |
Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE30all_node_lexicographic_orderedCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructurepE30all_node_lexicographic_orderedB6_ _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE30all_node_lexicographic_orderedCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 962 | 2 | fn all_node_lexicographic_ordered(&self) -> impl Iterator<Item = usize> { | 963 | | fn ancestry_order_next<TUd>(tree: &TrieStructure<TUd>, node_index: usize) -> Option<usize> { | 964 | | if let Some(first_child) = tree | 965 | | .nodes | 966 | | .get(node_index) | 967 | | .unwrap() | 968 | | .children | 969 | | .iter() | 970 | | .find_map(|c| *c) | 971 | | { | 972 | | return Some(first_child); | 973 | | } | 974 | | | 975 | | if let Some(next_sibling) = tree.next_sibling(node_index) { | 976 | | return Some(next_sibling); | 977 | | } | 978 | | | 979 | | let mut return_value = tree.nodes[node_index].parent.map(|(i, _)| i); | 980 | | while let Some(idx) = return_value { | 981 | | if let Some(next_sibling) = tree.next_sibling(idx) { | 982 | | return Some(next_sibling); | 983 | | } | 984 | | return_value = tree.nodes[idx].parent.map(|(i, _)| i); | 985 | | } | 986 | | return_value | 987 | | } | 988 | | | 989 | 2 | iter::successors(self.root_index, move |n| ancestry_order_next(self, *n)) | 990 | 2 | } |
_RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE30all_node_lexicographic_orderedCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 962 | 19 | fn all_node_lexicographic_ordered(&self) -> impl Iterator<Item = usize> { | 963 | | fn ancestry_order_next<TUd>(tree: &TrieStructure<TUd>, node_index: usize) -> Option<usize> { | 964 | | if let Some(first_child) = tree | 965 | | .nodes | 966 | | .get(node_index) | 967 | | .unwrap() | 968 | | .children | 969 | | .iter() | 970 | | .find_map(|c| *c) | 971 | | { | 972 | | return Some(first_child); | 973 | | } | 974 | | | 975 | | if let Some(next_sibling) = tree.next_sibling(node_index) { | 976 | | return Some(next_sibling); | 977 | | } | 978 | | | 979 | | let mut return_value = tree.nodes[node_index].parent.map(|(i, _)| i); | 980 | | while let Some(idx) = return_value { | 981 | | if let Some(next_sibling) = tree.next_sibling(idx) { | 982 | | return Some(next_sibling); | 983 | | } | 984 | | return_value = tree.nodes[idx].parent.map(|(i, _)| i); | 985 | | } | 986 | | return_value | 987 | | } | 988 | | | 989 | 19 | iter::successors(self.root_index, move |n| ancestry_order_next(self, *n)) | 990 | 19 | } |
|
991 | | |
992 | | /// Returns the [`NodeAccess`] of the node at the given index, or `None` if no such node |
993 | | /// exists. |
994 | | /// |
995 | | /// # Context |
996 | | /// |
997 | | /// Each node inserted in the trie is placed in the underlying data structure at a specific |
998 | | /// [`NodeIndex`] that never changes until the node is removed from the trie. |
999 | | /// |
1000 | | /// This [`NodeIndex`] can be retrieved by calling [`NodeAccess::node_index`], |
1001 | | /// [`StorageNodeAccess::node_index`] or [`BranchNodeAccess::node_index`]. The same node can |
1002 | | /// later be accessed again by calling [`TrieStructure::node_by_index`]. |
1003 | | /// |
1004 | | /// A [`NodeIndex`] value can be reused after its previous node has been removed. |
1005 | | /// |
1006 | | /// # Examples |
1007 | | /// |
1008 | | /// ``` |
1009 | | /// use smoldot::trie::{self, trie_structure}; |
1010 | | /// |
1011 | | /// let mut trie = trie_structure::TrieStructure::new(); |
1012 | | /// |
1013 | | /// // Insert an example node. |
1014 | | /// let inserted_node = trie |
1015 | | /// .node(trie::bytes_to_nibbles(b"foo".iter().cloned())) |
1016 | | /// .into_vacant() |
1017 | | /// .unwrap() |
1018 | | /// .insert_storage_value() |
1019 | | /// .insert(12, 80); |
1020 | | /// let node_index = inserted_node.node_index(); |
1021 | | /// drop(inserted_node); // Drops the borrow to this node. |
1022 | | /// |
1023 | | /// // At this point, no borrow of the `trie` object exists anymore. |
1024 | | /// |
1025 | | /// // Later, the same node can be accessed again. |
1026 | | /// let mut node = trie.node_by_index(node_index).unwrap(); |
1027 | | /// assert_eq!(*node.user_data(), 12); |
1028 | | /// ``` |
1029 | 1.05M | pub fn node_by_index(&'_ mut self, node_index: NodeIndex) -> Option<NodeAccess<'_, TUd>> { |
1030 | 1.05M | self.node_by_index_inner(node_index.0) |
1031 | 1.05M | } _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE13node_by_indexB6_ Line | Count | Source | 1029 | 5.13k | pub fn node_by_index(&'_ mut self, node_index: NodeIndex) -> Option<NodeAccess<'_, TUd>> { | 1030 | 5.13k | self.node_by_index_inner(node_index.0) | 1031 | 5.13k | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureuE13node_by_indexB6_ Line | Count | Source | 1029 | 535k | pub fn node_by_index(&'_ mut self, node_index: NodeIndex) -> Option<NodeAccess<'_, TUd>> { | 1030 | 535k | self.node_by_index_inner(node_index.0) | 1031 | 535k | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE13node_by_indexB6_ Line | Count | Source | 1029 | 29.7k | pub fn node_by_index(&'_ mut self, node_index: NodeIndex) -> Option<NodeAccess<'_, TUd>> { | 1030 | 29.7k | self.node_by_index_inner(node_index.0) | 1031 | 29.7k | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB4_16TrieEntryVersionEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE13node_by_indexB6_ Line | Count | Source | 1029 | 484k | pub fn node_by_index(&'_ mut self, node_index: NodeIndex) -> Option<NodeAccess<'_, TUd>> { | 1030 | 484k | self.node_by_index_inner(node_index.0) | 1031 | 484k | } |
Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE13node_by_indexCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE13node_by_indexB6_ _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE13node_by_indexCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1029 | 192 | pub fn node_by_index(&'_ mut self, node_index: NodeIndex) -> Option<NodeAccess<'_, TUd>> { | 1030 | 192 | self.node_by_index_inner(node_index.0) | 1031 | 192 | } |
_RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE13node_by_indexCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1029 | 1.82k | pub fn node_by_index(&'_ mut self, node_index: NodeIndex) -> Option<NodeAccess<'_, TUd>> { | 1030 | 1.82k | self.node_by_index_inner(node_index.0) | 1031 | 1.82k | } |
|
1032 | | |
1033 | | /// Internal function. Returns the [`NodeAccess`] of the node at the given index. |
1034 | 1.56M | fn node_by_index_inner(&'_ mut self, node_index: usize) -> Option<NodeAccess<'_, TUd>> { |
1035 | 1.56M | if self.nodes.get(node_index)?0 .has_storage_value { |
1036 | 1.31M | Some(NodeAccess::Storage(StorageNodeAccess { |
1037 | 1.31M | trie: self, |
1038 | 1.31M | node_index, |
1039 | 1.31M | })) |
1040 | | } else { |
1041 | 251k | Some(NodeAccess::Branch(BranchNodeAccess { |
1042 | 251k | trie: self, |
1043 | 251k | node_index, |
1044 | 251k | })) |
1045 | | } |
1046 | 1.56M | } _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE19node_by_index_innerB6_ Line | Count | Source | 1034 | 8.22k | fn node_by_index_inner(&'_ mut self, node_index: usize) -> Option<NodeAccess<'_, TUd>> { | 1035 | 8.22k | if self.nodes.get(node_index)?0 .has_storage_value { | 1036 | 8.00k | Some(NodeAccess::Storage(StorageNodeAccess { | 1037 | 8.00k | trie: self, | 1038 | 8.00k | node_index, | 1039 | 8.00k | })) | 1040 | | } else { | 1041 | 220 | Some(NodeAccess::Branch(BranchNodeAccess { | 1042 | 220 | trie: self, | 1043 | 220 | node_index, | 1044 | 220 | })) | 1045 | | } | 1046 | 8.22k | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureuE19node_by_index_innerB6_ Line | Count | Source | 1034 | 591k | fn node_by_index_inner(&'_ mut self, node_index: usize) -> Option<NodeAccess<'_, TUd>> { | 1035 | 591k | if self.nodes.get(node_index)?0 .has_storage_value { | 1036 | 471k | Some(NodeAccess::Storage(StorageNodeAccess { | 1037 | 471k | trie: self, | 1038 | 471k | node_index, | 1039 | 471k | })) | 1040 | | } else { | 1041 | 120k | Some(NodeAccess::Branch(BranchNodeAccess { | 1042 | 120k | trie: self, | 1043 | 120k | node_index, | 1044 | 120k | })) | 1045 | | } | 1046 | 591k | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE19node_by_index_innerB6_ Line | Count | Source | 1034 | 69.1k | fn node_by_index_inner(&'_ mut self, node_index: usize) -> Option<NodeAccess<'_, TUd>> { | 1035 | 69.1k | if self.nodes.get(node_index)?0 .has_storage_value { | 1036 | 69.1k | Some(NodeAccess::Storage(StorageNodeAccess { | 1037 | 69.1k | trie: self, | 1038 | 69.1k | node_index, | 1039 | 69.1k | })) | 1040 | | } else { | 1041 | 0 | Some(NodeAccess::Branch(BranchNodeAccess { | 1042 | 0 | trie: self, | 1043 | 0 | node_index, | 1044 | 0 | })) | 1045 | | } | 1046 | 69.1k | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB4_16TrieEntryVersionEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE19node_by_index_innerB6_ Line | Count | Source | 1034 | 895k | fn node_by_index_inner(&'_ mut self, node_index: usize) -> Option<NodeAccess<'_, TUd>> { | 1035 | 895k | if self.nodes.get(node_index)?0 .has_storage_value { | 1036 | 765k | Some(NodeAccess::Storage(StorageNodeAccess { | 1037 | 765k | trie: self, | 1038 | 765k | node_index, | 1039 | 765k | })) | 1040 | | } else { | 1041 | 130k | Some(NodeAccess::Branch(BranchNodeAccess { | 1042 | 130k | trie: self, | 1043 | 130k | node_index, | 1044 | 130k | })) | 1045 | | } | 1046 | 895k | } |
Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE19node_by_index_innerCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE19node_by_index_innerB6_ _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE19node_by_index_innerCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1034 | 380 | fn node_by_index_inner(&'_ mut self, node_index: usize) -> Option<NodeAccess<'_, TUd>> { | 1035 | 380 | if self.nodes.get(node_index)?0 .has_storage_value { | 1036 | 280 | Some(NodeAccess::Storage(StorageNodeAccess { | 1037 | 280 | trie: self, | 1038 | 280 | node_index, | 1039 | 280 | })) | 1040 | | } else { | 1041 | 100 | Some(NodeAccess::Branch(BranchNodeAccess { | 1042 | 100 | trie: self, | 1043 | 100 | node_index, | 1044 | 100 | })) | 1045 | | } | 1046 | 380 | } |
_RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE19node_by_index_innerCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1034 | 3.61k | fn node_by_index_inner(&'_ mut self, node_index: usize) -> Option<NodeAccess<'_, TUd>> { | 1035 | 3.61k | if self.nodes.get(node_index)?0 .has_storage_value { | 1036 | 2.66k | Some(NodeAccess::Storage(StorageNodeAccess { | 1037 | 2.66k | trie: self, | 1038 | 2.66k | node_index, | 1039 | 2.66k | })) | 1040 | | } else { | 1041 | 950 | Some(NodeAccess::Branch(BranchNodeAccess { | 1042 | 950 | trie: self, | 1043 | 950 | node_index, | 1044 | 950 | })) | 1045 | | } | 1046 | 3.61k | } |
|
1047 | | |
1048 | | /// Returns the key of the node at the given index, or `None` if no such node exists. |
1049 | | /// |
1050 | | /// This method is a shortcut for [`TrieStructure::node_by_index`] followed with |
1051 | | /// [`NodeAccess::full_key`]. |
1052 | 11.0M | pub fn node_full_key_by_index( |
1053 | 11.0M | &self, |
1054 | 11.0M | node_index: NodeIndex, |
1055 | 11.0M | ) -> Option<impl Iterator<Item = Nibble>> { |
1056 | 11.0M | if !self.nodes.contains(node_index.0) { |
1057 | 0 | return None; |
1058 | 11.0M | } |
1059 | | |
1060 | 11.0M | Some(self.node_full_key(node_index.0)) |
1061 | 11.0M | } _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE22node_full_key_by_indexB6_ Line | Count | Source | 1052 | 4.60M | pub fn node_full_key_by_index( | 1053 | 4.60M | &self, | 1054 | 4.60M | node_index: NodeIndex, | 1055 | 4.60M | ) -> Option<impl Iterator<Item = Nibble>> { | 1056 | 4.60M | if !self.nodes.contains(node_index.0) { | 1057 | 0 | return None; | 1058 | 4.60M | } | 1059 | | | 1060 | 4.60M | Some(self.node_full_key(node_index.0)) | 1061 | 4.60M | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB4_16TrieEntryVersionEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE22node_full_key_by_indexB6_ Line | Count | Source | 1052 | 3.64M | pub fn node_full_key_by_index( | 1053 | 3.64M | &self, | 1054 | 3.64M | node_index: NodeIndex, | 1055 | 3.64M | ) -> Option<impl Iterator<Item = Nibble>> { | 1056 | 3.64M | if !self.nodes.contains(node_index.0) { | 1057 | 0 | return None; | 1058 | 3.64M | } | 1059 | | | 1060 | 3.64M | Some(self.node_full_key(node_index.0)) | 1061 | 3.64M | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureuE22node_full_key_by_indexB6_ Line | Count | Source | 1052 | 2.75M | pub fn node_full_key_by_index( | 1053 | 2.75M | &self, | 1054 | 2.75M | node_index: NodeIndex, | 1055 | 2.75M | ) -> Option<impl Iterator<Item = Nibble>> { | 1056 | 2.75M | if !self.nodes.contains(node_index.0) { | 1057 | 0 | return None; | 1058 | 2.75M | } | 1059 | | | 1060 | 2.75M | Some(self.node_full_key(node_index.0)) | 1061 | 2.75M | } |
Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructurepE22node_full_key_by_indexB6_ |
1062 | | |
1063 | | /// Returns the full key of the node with the given index. |
1064 | | /// |
1065 | | /// # Panic |
1066 | | /// |
1067 | | /// Panics if `target` is not a valid index. |
1068 | 12.2M | fn node_full_key(&self, target: usize) -> impl Iterator<Item = Nibble> { |
1069 | 12.2M | self.node_path(target) |
1070 | 12.2M | .chain(iter::once(target)) |
1071 | 22.8M | .flat_map12.2M (move |n| { |
1072 | 22.8M | let node = self.nodes.get(n).unwrap(); |
1073 | 22.8M | let child_index = node.parent.into_iter().map(|p| p.1); |
1074 | 22.8M | let partial_key = node.partial_key.iter().cloned(); |
1075 | 22.8M | child_index.chain(partial_key) |
1076 | 22.8M | }) _RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB6_12proof_encode4NodeEE13node_full_key0B8_ Line | Count | Source | 1071 | 35.3k | .flat_map(move |n| { | 1072 | 35.3k | let node = self.nodes.get(n).unwrap(); | 1073 | 35.3k | let child_index = node.parent.into_iter().map(|p| p.1); | 1074 | 35.3k | let partial_key = node.partial_key.iter().cloned(); | 1075 | 35.3k | child_index.chain(partial_key) | 1076 | 35.3k | }) |
_RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE13node_full_key0B8_ Line | Count | Source | 1071 | 7.28M | .flat_map(move |n| { | 1072 | 7.28M | let node = self.nodes.get(n).unwrap(); | 1073 | 7.28M | let child_index = node.parent.into_iter().map(|p| p.1); | 1074 | 7.28M | let partial_key = node.partial_key.iter().cloned(); | 1075 | 7.28M | child_index.chain(partial_key) | 1076 | 7.28M | }) |
_RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureuE13node_full_key0B8_ Line | Count | Source | 1071 | 7.87M | .flat_map(move |n| { | 1072 | 7.87M | let node = self.nodes.get(n).unwrap(); | 1073 | 7.87M | let child_index = node.parent.into_iter().map(|p| p.1); | 1074 | 7.87M | let partial_key = node.partial_key.iter().cloned(); | 1075 | 7.87M | child_index.chain(partial_key) | 1076 | 7.87M | }) |
_RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB6_16TrieEntryVersionEEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE13node_full_key0B8_ Line | Count | Source | 1071 | 7.63M | .flat_map(move |n| { | 1072 | 7.63M | let node = self.nodes.get(n).unwrap(); | 1073 | 7.63M | let child_index = node.parent.into_iter().map(|p| p.1); | 1074 | 7.63M | let partial_key = node.partial_key.iter().cloned(); | 1075 | 7.63M | child_index.chain(partial_key) | 1076 | 7.63M | }) |
Unexecuted instantiation: _RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE13node_full_key0Cs4ISLcsFEGeP_6author Unexecuted instantiation: _RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB6_12proof_encode4NodeEE13node_full_key0B8_ _RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE13node_full_key0Cs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1071 | 132 | .flat_map(move |n| { | 1072 | 132 | let node = self.nodes.get(n).unwrap(); | 1073 | 132 | let child_index = node.parent.into_iter().map(|p| p.1); | 1074 | 132 | let partial_key = node.partial_key.iter().cloned(); | 1075 | 132 | child_index.chain(partial_key) | 1076 | 132 | }) |
_RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE13node_full_key0Cs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1071 | 1.25k | .flat_map(move |n| { | 1072 | 1.25k | let node = self.nodes.get(n).unwrap(); | 1073 | 1.25k | let child_index = node.parent.into_iter().map(|p| p.1); | 1074 | 1.25k | let partial_key = node.partial_key.iter().cloned(); | 1075 | 1.25k | child_index.chain(partial_key) | 1076 | 1.25k | }) |
|
1077 | 12.2M | } _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE13node_full_keyB6_ Line | Count | Source | 1068 | 26.1k | fn node_full_key(&self, target: usize) -> impl Iterator<Item = Nibble> { | 1069 | 26.1k | self.node_path(target) | 1070 | 26.1k | .chain(iter::once(target)) | 1071 | 26.1k | .flat_map(move |n| { | 1072 | | let node = self.nodes.get(n).unwrap(); | 1073 | | let child_index = node.parent.into_iter().map(|p| p.1); | 1074 | | let partial_key = node.partial_key.iter().cloned(); | 1075 | | child_index.chain(partial_key) | 1076 | | }) | 1077 | 26.1k | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE13node_full_keyB6_ Line | Count | Source | 1068 | 4.61M | fn node_full_key(&self, target: usize) -> impl Iterator<Item = Nibble> { | 1069 | 4.61M | self.node_path(target) | 1070 | 4.61M | .chain(iter::once(target)) | 1071 | 4.61M | .flat_map(move |n| { | 1072 | | let node = self.nodes.get(n).unwrap(); | 1073 | | let child_index = node.parent.into_iter().map(|p| p.1); | 1074 | | let partial_key = node.partial_key.iter().cloned(); | 1075 | | child_index.chain(partial_key) | 1076 | | }) | 1077 | 4.61M | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB4_16TrieEntryVersionEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE13node_full_keyB6_ Line | Count | Source | 1068 | 3.92M | fn node_full_key(&self, target: usize) -> impl Iterator<Item = Nibble> { | 1069 | 3.92M | self.node_path(target) | 1070 | 3.92M | .chain(iter::once(target)) | 1071 | 3.92M | .flat_map(move |n| { | 1072 | | let node = self.nodes.get(n).unwrap(); | 1073 | | let child_index = node.parent.into_iter().map(|p| p.1); | 1074 | | let partial_key = node.partial_key.iter().cloned(); | 1075 | | child_index.chain(partial_key) | 1076 | | }) | 1077 | 3.92M | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureuE13node_full_keyB6_ Line | Count | Source | 1068 | 3.72M | fn node_full_key(&self, target: usize) -> impl Iterator<Item = Nibble> { | 1069 | 3.72M | self.node_path(target) | 1070 | 3.72M | .chain(iter::once(target)) | 1071 | 3.72M | .flat_map(move |n| { | 1072 | | let node = self.nodes.get(n).unwrap(); | 1073 | | let child_index = node.parent.into_iter().map(|p| p.1); | 1074 | | let partial_key = node.partial_key.iter().cloned(); | 1075 | | child_index.chain(partial_key) | 1076 | | }) | 1077 | 3.72M | } |
Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE13node_full_keyCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE13node_full_keyB6_ _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE13node_full_keyCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1068 | 66 | fn node_full_key(&self, target: usize) -> impl Iterator<Item = Nibble> { | 1069 | 66 | self.node_path(target) | 1070 | 66 | .chain(iter::once(target)) | 1071 | 66 | .flat_map(move |n| { | 1072 | | let node = self.nodes.get(n).unwrap(); | 1073 | | let child_index = node.parent.into_iter().map(|p| p.1); | 1074 | | let partial_key = node.partial_key.iter().cloned(); | 1075 | | child_index.chain(partial_key) | 1076 | | }) | 1077 | 66 | } |
_RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE13node_full_keyCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1068 | 627 | fn node_full_key(&self, target: usize) -> impl Iterator<Item = Nibble> { | 1069 | 627 | self.node_path(target) | 1070 | 627 | .chain(iter::once(target)) | 1071 | 627 | .flat_map(move |n| { | 1072 | | let node = self.nodes.get(n).unwrap(); | 1073 | | let child_index = node.parent.into_iter().map(|p| p.1); | 1074 | | let partial_key = node.partial_key.iter().cloned(); | 1075 | | child_index.chain(partial_key) | 1076 | | }) | 1077 | 627 | } |
|
1078 | | |
1079 | | /// Returns the indices of the nodes to traverse to reach `target`. The returned iterator |
1080 | | /// does *not* include `target`. In other words, if `target` is the root node, this returns |
1081 | | /// an empty iterator. |
1082 | | /// |
1083 | | /// # Panic |
1084 | | /// |
1085 | | /// Panics if `target` is not a valid index. |
1086 | 12.2M | fn node_path(&self, target: usize) -> impl Iterator<Item = usize> { |
1087 | 12.2M | debug_assert!(self.nodes.get(usize::MAX).is_none()); |
1088 | | // First element is an invalid key, each successor is the last element of |
1089 | | // `reverse_node_path(target)` that isn't equal to `current`. |
1090 | | // Since the first element is invalid, we skip it. |
1091 | | // Since `reverse_node_path` never produces `target`, we know that it also won't be |
1092 | | // produced here. |
1093 | 22.8M | iter::successors12.2M (Some(usize::MAX)12.2M , move |¤t| { |
1094 | 22.8M | self.reverse_node_path(target) |
1095 | 24.1M | .take_while22.8M (move |n| *n != current) _RNCNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB6_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB8_12proof_encode4NodeEE9node_path00Ba_ Line | Count | Source | 1095 | 18.8k | .take_while(move |n| *n != current) |
_RNCNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB6_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1e_NtNtB8_9trie_node17MerkleValueOutputEEE9node_path00Ba_ Line | Count | Source | 1095 | 5.50M | .take_while(move |n| *n != current) |
_RNCNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB6_13TrieStructureuE9node_path00Ba_ Line | Count | Source | 1095 | 11.0M | .take_while(move |n| *n != current) |
_RNCNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB6_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB8_16TrieEntryVersionEEIB1e_NtNtB8_9trie_node17MerkleValueOutputEEE9node_path00Ba_ Line | Count | Source | 1095 | 7.60M | .take_while(move |n| *n != current) |
Unexecuted instantiation: _RNCNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB6_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1e_NtNtB8_9trie_node17MerkleValueOutputEEE9node_path00Cs4ISLcsFEGeP_6author Unexecuted instantiation: _RNCNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB6_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB8_12proof_encode4NodeEE9node_path00Ba_ _RNCNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB6_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1e_NtNtB8_9trie_node17MerkleValueOutputEEE9node_path00Cs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1095 | 154 | .take_while(move |n| *n != current) |
_RNCNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB6_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1e_NtNtB8_9trie_node17MerkleValueOutputEEE9node_path00Cs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1095 | 1.46k | .take_while(move |n| *n != current) |
|
1096 | 22.8M | .last() |
1097 | 22.8M | }) _RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB6_12proof_encode4NodeEE9node_path0B8_ Line | Count | Source | 1093 | 35.3k | iter::successors(Some(usize::MAX), move |¤t| { | 1094 | 35.3k | self.reverse_node_path(target) | 1095 | 35.3k | .take_while(move |n| *n != current) | 1096 | 35.3k | .last() | 1097 | 35.3k | }) |
_RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE9node_path0B8_ Line | Count | Source | 1093 | 7.28M | iter::successors(Some(usize::MAX), move |¤t| { | 1094 | 7.28M | self.reverse_node_path(target) | 1095 | 7.28M | .take_while(move |n| *n != current) | 1096 | 7.28M | .last() | 1097 | 7.28M | }) |
_RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureuE9node_path0B8_ Line | Count | Source | 1093 | 7.87M | iter::successors(Some(usize::MAX), move |¤t| { | 1094 | 7.87M | self.reverse_node_path(target) | 1095 | 7.87M | .take_while(move |n| *n != current) | 1096 | 7.87M | .last() | 1097 | 7.87M | }) |
_RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB6_16TrieEntryVersionEEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE9node_path0B8_ Line | Count | Source | 1093 | 7.63M | iter::successors(Some(usize::MAX), move |¤t| { | 1094 | 7.63M | self.reverse_node_path(target) | 1095 | 7.63M | .take_while(move |n| *n != current) | 1096 | 7.63M | .last() | 1097 | 7.63M | }) |
Unexecuted instantiation: _RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE9node_path0Cs4ISLcsFEGeP_6author Unexecuted instantiation: _RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB6_12proof_encode4NodeEE9node_path0B8_ _RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE9node_path0Cs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1093 | 132 | iter::successors(Some(usize::MAX), move |¤t| { | 1094 | 132 | self.reverse_node_path(target) | 1095 | 132 | .take_while(move |n| *n != current) | 1096 | 132 | .last() | 1097 | 132 | }) |
_RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE9node_path0Cs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1093 | 1.25k | iter::successors(Some(usize::MAX), move |¤t| { | 1094 | 1.25k | self.reverse_node_path(target) | 1095 | 1.25k | .take_while(move |n| *n != current) | 1096 | 1.25k | .last() | 1097 | 1.25k | }) |
|
1098 | 12.2M | .skip(1) |
1099 | 12.2M | } _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE9node_pathB6_ Line | Count | Source | 1086 | 26.1k | fn node_path(&self, target: usize) -> impl Iterator<Item = usize> { | 1087 | 26.1k | debug_assert!(self.nodes.get(usize::MAX).is_none()); | 1088 | | // First element is an invalid key, each successor is the last element of | 1089 | | // `reverse_node_path(target)` that isn't equal to `current`. | 1090 | | // Since the first element is invalid, we skip it. | 1091 | | // Since `reverse_node_path` never produces `target`, we know that it also won't be | 1092 | | // produced here. | 1093 | 26.1k | iter::successors(Some(usize::MAX), move |¤t| { | 1094 | | self.reverse_node_path(target) | 1095 | | .take_while(move |n| *n != current) | 1096 | | .last() | 1097 | | }) | 1098 | 26.1k | .skip(1) | 1099 | 26.1k | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE9node_pathB6_ Line | Count | Source | 1086 | 4.61M | fn node_path(&self, target: usize) -> impl Iterator<Item = usize> { | 1087 | 4.61M | debug_assert!(self.nodes.get(usize::MAX).is_none()); | 1088 | | // First element is an invalid key, each successor is the last element of | 1089 | | // `reverse_node_path(target)` that isn't equal to `current`. | 1090 | | // Since the first element is invalid, we skip it. | 1091 | | // Since `reverse_node_path` never produces `target`, we know that it also won't be | 1092 | | // produced here. | 1093 | 4.61M | iter::successors(Some(usize::MAX), move |¤t| { | 1094 | | self.reverse_node_path(target) | 1095 | | .take_while(move |n| *n != current) | 1096 | | .last() | 1097 | | }) | 1098 | 4.61M | .skip(1) | 1099 | 4.61M | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB4_16TrieEntryVersionEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE9node_pathB6_ Line | Count | Source | 1086 | 3.92M | fn node_path(&self, target: usize) -> impl Iterator<Item = usize> { | 1087 | 3.92M | debug_assert!(self.nodes.get(usize::MAX).is_none()); | 1088 | | // First element is an invalid key, each successor is the last element of | 1089 | | // `reverse_node_path(target)` that isn't equal to `current`. | 1090 | | // Since the first element is invalid, we skip it. | 1091 | | // Since `reverse_node_path` never produces `target`, we know that it also won't be | 1092 | | // produced here. | 1093 | 3.92M | iter::successors(Some(usize::MAX), move |¤t| { | 1094 | | self.reverse_node_path(target) | 1095 | | .take_while(move |n| *n != current) | 1096 | | .last() | 1097 | | }) | 1098 | 3.92M | .skip(1) | 1099 | 3.92M | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureuE9node_pathB6_ Line | Count | Source | 1086 | 3.72M | fn node_path(&self, target: usize) -> impl Iterator<Item = usize> { | 1087 | 3.72M | debug_assert!(self.nodes.get(usize::MAX).is_none()); | 1088 | | // First element is an invalid key, each successor is the last element of | 1089 | | // `reverse_node_path(target)` that isn't equal to `current`. | 1090 | | // Since the first element is invalid, we skip it. | 1091 | | // Since `reverse_node_path` never produces `target`, we know that it also won't be | 1092 | | // produced here. | 1093 | 3.72M | iter::successors(Some(usize::MAX), move |¤t| { | 1094 | | self.reverse_node_path(target) | 1095 | | .take_while(move |n| *n != current) | 1096 | | .last() | 1097 | | }) | 1098 | 3.72M | .skip(1) | 1099 | 3.72M | } |
Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE9node_pathCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE9node_pathB6_ _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE9node_pathCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1086 | 66 | fn node_path(&self, target: usize) -> impl Iterator<Item = usize> { | 1087 | 66 | debug_assert!(self.nodes.get(usize::MAX).is_none()); | 1088 | | // First element is an invalid key, each successor is the last element of | 1089 | | // `reverse_node_path(target)` that isn't equal to `current`. | 1090 | | // Since the first element is invalid, we skip it. | 1091 | | // Since `reverse_node_path` never produces `target`, we know that it also won't be | 1092 | | // produced here. | 1093 | 66 | iter::successors(Some(usize::MAX), move |¤t| { | 1094 | | self.reverse_node_path(target) | 1095 | | .take_while(move |n| *n != current) | 1096 | | .last() | 1097 | | }) | 1098 | 66 | .skip(1) | 1099 | 66 | } |
_RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE9node_pathCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1086 | 627 | fn node_path(&self, target: usize) -> impl Iterator<Item = usize> { | 1087 | 627 | debug_assert!(self.nodes.get(usize::MAX).is_none()); | 1088 | | // First element is an invalid key, each successor is the last element of | 1089 | | // `reverse_node_path(target)` that isn't equal to `current`. | 1090 | | // Since the first element is invalid, we skip it. | 1091 | | // Since `reverse_node_path` never produces `target`, we know that it also won't be | 1092 | | // produced here. | 1093 | 627 | iter::successors(Some(usize::MAX), move |¤t| { | 1094 | | self.reverse_node_path(target) | 1095 | | .take_while(move |n| *n != current) | 1096 | | .last() | 1097 | | }) | 1098 | 627 | .skip(1) | 1099 | 627 | } |
|
1100 | | |
1101 | | /// Returns the indices of the nodes starting from `target` towards the root node. The returned |
1102 | | /// iterator does *not* include `target` but does include the root node if it is different |
1103 | | /// from `target`. If `target` is the root node, this returns an empty iterator. |
1104 | | /// |
1105 | | /// # Panic |
1106 | | /// |
1107 | | /// Panics if `target` is not a valid index. |
1108 | 22.8M | fn reverse_node_path(&self, target: usize) -> impl Iterator<Item = usize> { |
1109 | | // First element is `target`, each successor is `current.parent`. |
1110 | | // Since `target` must explicitly not be included, we skip the first element. |
1111 | 47.0M | iter::successors22.8M (Some(target)22.8M , move |current| { |
1112 | 47.0M | Some(self.nodes.get(*current).unwrap().parent?20.8M .0) |
1113 | 47.0M | }) _RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB6_12proof_encode4NodeEE17reverse_node_path0B8_ Line | Count | Source | 1111 | 54.1k | iter::successors(Some(target), move |current| { | 1112 | 54.1k | Some(self.nodes.get(*current).unwrap().parent?34.9k .0) | 1113 | 54.1k | }) |
_RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE17reverse_node_path0B8_ Line | Count | Source | 1111 | 12.7M | iter::successors(Some(target), move |current| { | 1112 | 12.7M | Some(self.nodes.get(*current).unwrap().parent?7.12M .0) | 1113 | 12.7M | }) |
_RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureuE17reverse_node_path0B8_ Line | Count | Source | 1111 | 18.9M | iter::successors(Some(target), move |current| { | 1112 | 18.9M | Some(self.nodes.get(*current).unwrap().parent?6.21M .0) | 1113 | 18.9M | }) |
_RNCNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB6_16TrieEntryVersionEEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE17reverse_node_path0B8_ Line | Count | Source | 1111 | 15.2M | iter::successors(Some(target), move |current| { | 1112 | 15.2M | Some(self.nodes.get(*current).unwrap().parent?7.44M .0) | 1113 | 15.2M | }) |
Unexecuted instantiation: _RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE17reverse_node_path0Cs4ISLcsFEGeP_6author Unexecuted instantiation: _RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB6_12proof_encode4NodeEE17reverse_node_path0B8_ _RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE17reverse_node_path0Cs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1111 | 286 | iter::successors(Some(target), move |current| { | 1112 | 286 | Some(self.nodes.get(*current).unwrap().parent?110 .0) | 1113 | 286 | }) |
_RNCNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB4_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1c_NtNtB6_9trie_node17MerkleValueOutputEEE17reverse_node_path0Cs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1111 | 2.71k | iter::successors(Some(target), move |current| { | 1112 | 2.71k | Some(self.nodes.get(*current).unwrap().parent?1.04k .0) | 1113 | 2.71k | }) |
|
1114 | 22.8M | .skip(1) |
1115 | 22.8M | } _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE17reverse_node_pathB6_ Line | Count | Source | 1108 | 35.3k | fn reverse_node_path(&self, target: usize) -> impl Iterator<Item = usize> { | 1109 | | // First element is `target`, each successor is `current.parent`. | 1110 | | // Since `target` must explicitly not be included, we skip the first element. | 1111 | 35.3k | iter::successors(Some(target), move |current| { | 1112 | | Some(self.nodes.get(*current).unwrap().parent?.0) | 1113 | | }) | 1114 | 35.3k | .skip(1) | 1115 | 35.3k | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE17reverse_node_pathB6_ Line | Count | Source | 1108 | 7.28M | fn reverse_node_path(&self, target: usize) -> impl Iterator<Item = usize> { | 1109 | | // First element is `target`, each successor is `current.parent`. | 1110 | | // Since `target` must explicitly not be included, we skip the first element. | 1111 | 7.28M | iter::successors(Some(target), move |current| { | 1112 | | Some(self.nodes.get(*current).unwrap().parent?.0) | 1113 | | }) | 1114 | 7.28M | .skip(1) | 1115 | 7.28M | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureuE17reverse_node_pathB6_ Line | Count | Source | 1108 | 7.87M | fn reverse_node_path(&self, target: usize) -> impl Iterator<Item = usize> { | 1109 | | // First element is `target`, each successor is `current.parent`. | 1110 | | // Since `target` must explicitly not be included, we skip the first element. | 1111 | 7.87M | iter::successors(Some(target), move |current| { | 1112 | | Some(self.nodes.get(*current).unwrap().parent?.0) | 1113 | | }) | 1114 | 7.87M | .skip(1) | 1115 | 7.87M | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB4_16TrieEntryVersionEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE17reverse_node_pathB6_ Line | Count | Source | 1108 | 7.63M | fn reverse_node_path(&self, target: usize) -> impl Iterator<Item = usize> { | 1109 | | // First element is `target`, each successor is `current.parent`. | 1110 | | // Since `target` must explicitly not be included, we skip the first element. | 1111 | 7.63M | iter::successors(Some(target), move |current| { | 1112 | | Some(self.nodes.get(*current).unwrap().parent?.0) | 1113 | | }) | 1114 | 7.63M | .skip(1) | 1115 | 7.63M | } |
Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE17reverse_node_pathCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE17reverse_node_pathB6_ _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE17reverse_node_pathCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1108 | 132 | fn reverse_node_path(&self, target: usize) -> impl Iterator<Item = usize> { | 1109 | | // First element is `target`, each successor is `current.parent`. | 1110 | | // Since `target` must explicitly not be included, we skip the first element. | 1111 | 132 | iter::successors(Some(target), move |current| { | 1112 | | Some(self.nodes.get(*current).unwrap().parent?.0) | 1113 | | }) | 1114 | 132 | .skip(1) | 1115 | 132 | } |
_RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE17reverse_node_pathCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1108 | 1.25k | fn reverse_node_path(&self, target: usize) -> impl Iterator<Item = usize> { | 1109 | | // First element is `target`, each successor is `current.parent`. | 1110 | | // Since `target` must explicitly not be included, we skip the first element. | 1111 | 1.25k | iter::successors(Some(target), move |current| { | 1112 | | Some(self.nodes.get(*current).unwrap().parent?.0) | 1113 | | }) | 1114 | 1.25k | .skip(1) | 1115 | 1.25k | } |
|
1116 | | |
1117 | | /// Returns the next sibling of the given node. |
1118 | | /// |
1119 | | /// # Panic |
1120 | | /// |
1121 | | /// Panics if `node_index` is not a valid index. |
1122 | 8.98M | fn next_sibling(&self, node_index: usize) -> Option<usize> { |
1123 | 8.98M | let (parent_index6.17M , child_index6.17M ) = self.nodes.get(node_index).unwrap().parent?2.80M ; |
1124 | 6.17M | let parent = self.nodes.get(parent_index).unwrap(); |
1125 | | |
1126 | 28.1M | for idx in (u8::from(child_index) + 1)6.17M ..16 { |
1127 | 28.1M | if let Some(child3.50M ) = parent.children[usize::from(idx)] { |
1128 | 3.50M | return Some(child); |
1129 | 24.6M | } |
1130 | | } |
1131 | | |
1132 | 2.67M | None |
1133 | 8.98M | } _RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE12next_siblingB6_ Line | Count | Source | 1122 | 29.7k | fn next_sibling(&self, node_index: usize) -> Option<usize> { | 1123 | 29.7k | let (parent_index28.2k , child_index28.2k ) = self.nodes.get(node_index).unwrap().parent?1.50k ; | 1124 | 28.2k | let parent = self.nodes.get(parent_index).unwrap(); | 1125 | | | 1126 | 89.6k | for idx in (u8::from(child_index) + 1)28.2k ..16 { | 1127 | 89.6k | if let Some(child20.1k ) = parent.children[usize::from(idx)] { | 1128 | 20.1k | return Some(child); | 1129 | 69.4k | } | 1130 | | } | 1131 | | | 1132 | 8.13k | None | 1133 | 29.7k | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE12next_siblingB6_ Line | Count | Source | 1122 | 4.25M | fn next_sibling(&self, node_index: usize) -> Option<usize> { | 1123 | 4.25M | let (parent_index2.51M , child_index2.51M ) = self.nodes.get(node_index).unwrap().parent?1.73M ; | 1124 | 2.51M | let parent = self.nodes.get(parent_index).unwrap(); | 1125 | | | 1126 | 12.9M | for idx in (u8::from(child_index) + 1)2.51M ..16 { | 1127 | 12.9M | if let Some(child1.28M ) = parent.children[usize::from(idx)] { | 1128 | 1.28M | return Some(child); | 1129 | 11.6M | } | 1130 | | } | 1131 | | | 1132 | 1.23M | None | 1133 | 4.25M | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB4_16TrieEntryVersionEEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE12next_siblingB6_ Line | Count | Source | 1122 | 936k | fn next_sibling(&self, node_index: usize) -> Option<usize> { | 1123 | 936k | let (parent_index805k , child_index805k ) = self.nodes.get(node_index).unwrap().parent?131k ; | 1124 | 805k | let parent = self.nodes.get(parent_index).unwrap(); | 1125 | | | 1126 | 2.63M | for idx in (u8::from(child_index) + 1)805k ..16 { | 1127 | 2.63M | if let Some(child568k ) = parent.children[usize::from(idx)] { | 1128 | 568k | return Some(child); | 1129 | 2.06M | } | 1130 | | } | 1131 | | | 1132 | 236k | None | 1133 | 936k | } |
_RNvMNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB2_13TrieStructureuE12next_siblingB6_ Line | Count | Source | 1122 | 3.76M | fn next_sibling(&self, node_index: usize) -> Option<usize> { | 1123 | 3.76M | let (parent_index2.82M , child_index2.82M ) = self.nodes.get(node_index).unwrap().parent?932k ; | 1124 | 2.82M | let parent = self.nodes.get(parent_index).unwrap(); | 1125 | | | 1126 | 12.4M | for idx in (u8::from(child_index) + 1)2.82M ..16 { | 1127 | 12.4M | if let Some(child1.63M ) = parent.children[usize::from(idx)] { | 1128 | 1.63M | return Some(child); | 1129 | 10.7M | } | 1130 | | } | 1131 | | | 1132 | 1.19M | None | 1133 | 3.76M | } |
Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE12next_siblingCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureINtNtCs66KPHxksi63_4core6option6OptionNtNtB4_12proof_encode4NodeEE12next_siblingB6_ _RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE12next_siblingCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1122 | 96 | fn next_sibling(&self, node_index: usize) -> Option<usize> { | 1123 | 96 | let (parent_index94 , child_index94 ) = self.nodes.get(node_index).unwrap().parent?2 ; | 1124 | 94 | let parent = self.nodes.get(parent_index).unwrap(); | 1125 | | | 1126 | 292 | for idx in (u8::from(child_index) + 1)94 ..16 { | 1127 | 292 | if let Some(child68 ) = parent.children[usize::from(idx)] { | 1128 | 68 | return Some(child); | 1129 | 224 | } | 1130 | | } | 1131 | | | 1132 | 26 | None | 1133 | 96 | } |
_RNvMNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB2_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB4_9trie_node17MerkleValueOutputEEE12next_siblingCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1122 | 912 | fn next_sibling(&self, node_index: usize) -> Option<usize> { | 1123 | 912 | let (parent_index893 , child_index893 ) = self.nodes.get(node_index).unwrap().parent?19 ; | 1124 | 893 | let parent = self.nodes.get(parent_index).unwrap(); | 1125 | | | 1126 | 2.77k | for idx in (u8::from(child_index) + 1)893 ..16 { | 1127 | 2.77k | if let Some(child646 ) = parent.children[usize::from(idx)] { | 1128 | 646 | return Some(child); | 1129 | 2.12k | } | 1130 | | } | 1131 | | | 1132 | 247 | None | 1133 | 912 | } |
|
1134 | | } |
1135 | | |
1136 | | impl<TUd> Default for TrieStructure<TUd> { |
1137 | 0 | fn default() -> Self { |
1138 | 0 | Self::new() |
1139 | 0 | } Unexecuted instantiation: _RNvXININtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structures_0pEINtB5_13TrieStructurepENtNtCs66KPHxksi63_4core7default7Default7defaultB9_ Unexecuted instantiation: _RNvXININtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structures_0pEINtB5_13TrieStructurepENtNtCs66KPHxksi63_4core7default7Default7defaultB9_ |
1140 | | } |
1141 | | |
1142 | | impl<TUd: fmt::Debug> fmt::Debug for TrieStructure<TUd> { |
1143 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1144 | 0 | f.debug_list() |
1145 | 0 | .entries( |
1146 | 0 | self.all_node_lexicographic_ordered() |
1147 | 0 | .map(|idx| (idx, self.nodes.get(idx).unwrap())), Unexecuted instantiation: _RNCNvXs0_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1f_NtNtB9_9trie_node17MerkleValueOutputEEENtNtB1j_3fmt5Debug3fmt0Bb_ Unexecuted instantiation: _RNCNvXs0_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB9_16TrieEntryVersionEEIB1f_NtNtB9_9trie_node17MerkleValueOutputEEENtNtB1j_3fmt5Debug3fmt0Bb_ Unexecuted instantiation: _RNCNvXs0_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_13TrieStructureuENtNtCs66KPHxksi63_4core3fmt5Debug3fmt0Bb_ Unexecuted instantiation: _RNCNvXININtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structures0_0pEINtB7_13TrieStructurepENtNtCs66KPHxksi63_4core3fmt5Debug3fmt0Bb_ |
1148 | | ) |
1149 | 0 | .finish() |
1150 | 0 | } Unexecuted instantiation: _RNvXs0_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1d_NtNtB7_9trie_node17MerkleValueOutputEEENtNtB1h_3fmt5Debug3fmtB9_ Unexecuted instantiation: _RNvXs0_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1d_NtNtB7_9trie_node17MerkleValueOutputEEENtNtB1h_3fmt5Debug3fmtB9_ Unexecuted instantiation: _RNvXs0_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureuENtNtCs66KPHxksi63_4core3fmt5Debug3fmtB9_ Unexecuted instantiation: _RNvXININtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structures0_0pEINtB5_13TrieStructurepENtNtCs66KPHxksi63_4core3fmt5Debug3fmtB9_ |
1151 | | } |
1152 | | |
1153 | | impl<TUd> ops::Index<NodeIndex> for TrieStructure<TUd> { |
1154 | | type Output = TUd; |
1155 | | |
1156 | | #[track_caller] |
1157 | 1.90M | fn index(&self, node_index: NodeIndex) -> &TUd { |
1158 | 1.90M | &self.nodes[node_index.0].user_data |
1159 | 1.90M | } _RNvXs1_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1d_NtNtB7_9trie_node17MerkleValueOutputEEEINtNtNtB1h_3ops5index5IndexNtB5_9NodeIndexE5indexB9_ Line | Count | Source | 1157 | 1.43M | fn index(&self, node_index: NodeIndex) -> &TUd { | 1158 | 1.43M | &self.nodes[node_index.0].user_data | 1159 | 1.43M | } |
_RNvXs1_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1d_NtNtB7_9trie_node17MerkleValueOutputEEEINtNtNtB1h_3ops5index5IndexNtB5_9NodeIndexE5indexB9_ Line | Count | Source | 1157 | 468k | fn index(&self, node_index: NodeIndex) -> &TUd { | 1158 | 468k | &self.nodes[node_index.0].user_data | 1159 | 468k | } |
Unexecuted instantiation: _RNvXs1_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1d_NtNtB7_9trie_node17MerkleValueOutputEEEINtNtNtB1h_3ops5index5IndexNtB5_9NodeIndexE5indexCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvXININtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structures1_0pEINtB5_13TrieStructurepEINtNtNtCs66KPHxksi63_4core3ops5index5IndexNtB5_9NodeIndexE5indexB9_ _RNvXs1_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1d_NtNtB7_9trie_node17MerkleValueOutputEEEINtNtNtB1h_3ops5index5IndexNtB5_9NodeIndexE5indexCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1157 | 96 | fn index(&self, node_index: NodeIndex) -> &TUd { | 1158 | 96 | &self.nodes[node_index.0].user_data | 1159 | 96 | } |
_RNvXs1_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13TrieStructureTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1d_NtNtB7_9trie_node17MerkleValueOutputEEEINtNtNtB1h_3ops5index5IndexNtB5_9NodeIndexE5indexCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1157 | 912 | fn index(&self, node_index: NodeIndex) -> &TUd { | 1158 | 912 | &self.nodes[node_index.0].user_data | 1159 | 912 | } |
|
1160 | | } |
1161 | | |
1162 | | impl<TUd> ops::IndexMut<NodeIndex> for TrieStructure<TUd> { |
1163 | | #[track_caller] |
1164 | 0 | fn index_mut(&mut self, node_index: NodeIndex) -> &mut TUd { |
1165 | 0 | &mut self.nodes[node_index.0].user_data |
1166 | 0 | } Unexecuted instantiation: _RNvXININtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structures2_0pEINtB5_13TrieStructurepEINtNtNtCs66KPHxksi63_4core3ops5index8IndexMutNtB5_9NodeIndexE9index_mutB9_ Unexecuted instantiation: _RNvXININtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structures2_0pEINtB5_13TrieStructurepEINtNtNtCs66KPHxksi63_4core3ops5index8IndexMutNtB5_9NodeIndexE9index_mutB9_ |
1167 | | } |
1168 | | |
1169 | | enum ExistingNodeInnerResult<I> { |
1170 | | Found { |
1171 | | node_index: usize, |
1172 | | has_storage_value: bool, |
1173 | | }, |
1174 | | NotFound { |
1175 | | /// Closest ancestor that actually exists. |
1176 | | /// If `Some`, also contains `desired_nibbles - closest_ancestor_key`. This iterator is |
1177 | | /// guaranteed to have at least one element. |
1178 | | closest_ancestor: Option<(usize, I)>, |
1179 | | }, |
1180 | | } |
1181 | | |
1182 | | /// Index of a node in the trie. Never invalidated, except when if node in question is destroyed. |
1183 | | /// |
1184 | | /// See [`TrieStructure::node_by_index`] for more information. |
1185 | | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
1186 | | pub struct NodeIndex(usize); |
1187 | | |
1188 | | /// Access to a entry for a potential node within the [`TrieStructure`]. |
1189 | | /// |
1190 | | /// See [`TrieStructure::node`] for more information. |
1191 | | pub enum Entry<'a, TUd, TKIter> { |
1192 | | /// There exists a node with this key. |
1193 | | Occupied(NodeAccess<'a, TUd>), |
1194 | | /// This entry is vacant. |
1195 | | Vacant(Vacant<'a, TUd, TKIter>), |
1196 | | } |
1197 | | |
1198 | | impl<'a, TUd, TKIter> Entry<'a, TUd, TKIter> { |
1199 | | /// Returns `Some` if `self` is an [`Entry::Vacant`]. |
1200 | 30 | pub fn into_vacant(self) -> Option<Vacant<'a, TUd, TKIter>> { |
1201 | 30 | match self { |
1202 | 30 | Entry::Vacant(e) => Some(e), |
1203 | 0 | _ => None, |
1204 | | } |
1205 | 30 | } _RNvMs3_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_5EntryuINtNtNtNtCs66KPHxksi63_4core4iter8adapters6cloned6ClonedINtNtNtB1c_5slice4iter4IterNtNtB7_6nibble6NibbleEEE11into_vacantB9_ Line | Count | Source | 1200 | 30 | pub fn into_vacant(self) -> Option<Vacant<'a, TUd, TKIter>> { | 1201 | 30 | match self { | 1202 | 30 | Entry::Vacant(e) => Some(e), | 1203 | 0 | _ => None, | 1204 | | } | 1205 | 30 | } |
Unexecuted instantiation: _RNvMs3_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_5EntryppE11into_vacantB9_ |
1206 | | |
1207 | | /// Returns `Some` if `self` is an [`Entry::Occupied`]. |
1208 | 6 | pub fn into_occupied(self) -> Option<NodeAccess<'a, TUd>> { |
1209 | 6 | match self { |
1210 | 6 | Entry::Occupied(e) => Some(e), |
1211 | 0 | _ => None, |
1212 | | } |
1213 | 6 | } _RNvMs3_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_5EntryuINtNtNtNtCs66KPHxksi63_4core4iter8adapters6cloned6ClonedINtNtNtB1c_5slice4iter4IterNtNtB7_6nibble6NibbleEEE13into_occupiedB9_ Line | Count | Source | 1208 | 6 | pub fn into_occupied(self) -> Option<NodeAccess<'a, TUd>> { | 1209 | 6 | match self { | 1210 | 6 | Entry::Occupied(e) => Some(e), | 1211 | 0 | _ => None, | 1212 | | } | 1213 | 6 | } |
Unexecuted instantiation: _RNvMs3_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_5EntryppE13into_occupiedB9_ |
1214 | | } |
1215 | | |
1216 | | /// Access to a node within the [`TrieStructure`]. |
1217 | | pub enum NodeAccess<'a, TUd> { |
1218 | | Storage(StorageNodeAccess<'a, TUd>), |
1219 | | Branch(BranchNodeAccess<'a, TUd>), |
1220 | | } |
1221 | | |
1222 | | impl<'a, TUd> NodeAccess<'a, TUd> { |
1223 | | /// Returns `Some` if `self` is an [`NodeAccess::Storage`]. |
1224 | 1 | pub fn into_storage(self) -> Option<StorageNodeAccess<'a, TUd>> { |
1225 | 1 | match self { |
1226 | 1 | NodeAccess::Storage(e) => Some(e), |
1227 | 0 | _ => None, |
1228 | | } |
1229 | 1 | } _RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessuE12into_storageB9_ Line | Count | Source | 1224 | 1 | pub fn into_storage(self) -> Option<StorageNodeAccess<'a, TUd>> { | 1225 | 1 | match self { | 1226 | 1 | NodeAccess::Storage(e) => Some(e), | 1227 | 0 | _ => None, | 1228 | | } | 1229 | 1 | } |
Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccesspE12into_storageB9_ |
1230 | | |
1231 | | /// Returns an opaque [`NodeIndex`] representing the node in the trie. |
1232 | | /// |
1233 | | /// It can later be used to retrieve this same node using [`TrieStructure::node_by_index`]. |
1234 | 1.50k | pub fn node_index(&self) -> NodeIndex { |
1235 | 1.50k | match self { |
1236 | 1.50k | NodeAccess::Storage(n) => n.node_index(), |
1237 | 0 | NodeAccess::Branch(n) => n.node_index(), |
1238 | | } |
1239 | 1.50k | } _RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE10node_indexB9_ Line | Count | Source | 1234 | 1.50k | pub fn node_index(&self) -> NodeIndex { | 1235 | 1.50k | match self { | 1236 | 1.50k | NodeAccess::Storage(n) => n.node_index(), | 1237 | 0 | NodeAccess::Branch(n) => n.node_index(), | 1238 | | } | 1239 | 1.50k | } |
Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE10node_indexB9_ |
1240 | | |
1241 | | /// Returns the parent of this node, or `None` if this is the root node. |
1242 | 9.63k | pub fn into_parent(self) -> Option<NodeAccess<'a, TUd>> { |
1243 | 9.63k | match self { |
1244 | 9.63k | NodeAccess::Storage(n) => n.into_parent(), |
1245 | 0 | NodeAccess::Branch(n) => n.into_parent(), |
1246 | | } |
1247 | 9.63k | } _RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE11into_parentB9_ Line | Count | Source | 1242 | 9.63k | pub fn into_parent(self) -> Option<NodeAccess<'a, TUd>> { | 1243 | 9.63k | match self { | 1244 | 9.63k | NodeAccess::Storage(n) => n.into_parent(), | 1245 | 0 | NodeAccess::Branch(n) => n.into_parent(), | 1246 | | } | 1247 | 9.63k | } |
Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE11into_parentB9_ |
1248 | | |
1249 | | /// Returns the parent of this node, or `None` if this is the root node. |
1250 | 0 | pub fn parent(&'_ mut self) -> Option<NodeAccess<'_, TUd>> { |
1251 | 0 | match self { |
1252 | 0 | NodeAccess::Storage(n) => n.parent(), |
1253 | 0 | NodeAccess::Branch(n) => n.parent(), |
1254 | | } |
1255 | 0 | } Unexecuted instantiation: _RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccesspE6parentB9_ Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccesspE6parentB9_ |
1256 | | |
1257 | | /// Returns the user data of the child at the given index. |
1258 | | /// |
1259 | | /// > **Note**: This method exists because it accepts `&self` rather than `&mut self`. A |
1260 | | /// > cleaner alternative would be to split the [`NodeAccess`] struct into |
1261 | | /// > `NodeAccessRef` and `NodeAccessMut`, but that's a lot of efforts compare to |
1262 | | /// > this single method. |
1263 | 951k | pub fn child_user_data(&self, index: Nibble) -> Option<&TUd> { |
1264 | 951k | match self { |
1265 | 859k | NodeAccess::Storage(n) => n.child_user_data(index), |
1266 | 92.4k | NodeAccess::Branch(n) => n.child_user_data(index), |
1267 | | } |
1268 | 951k | } _RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE15child_user_dataB9_ Line | Count | Source | 1263 | 475k | pub fn child_user_data(&self, index: Nibble) -> Option<&TUd> { | 1264 | 475k | match self { | 1265 | 475k | NodeAccess::Storage(n) => n.child_user_data(index), | 1266 | 0 | NodeAccess::Branch(n) => n.child_user_data(index), | 1267 | | } | 1268 | 475k | } |
_RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessuE15child_user_dataB9_ Line | Count | Source | 1263 | 475k | pub fn child_user_data(&self, index: Nibble) -> Option<&TUd> { | 1264 | 475k | match self { | 1265 | 383k | NodeAccess::Storage(n) => n.child_user_data(index), | 1266 | 92.4k | NodeAccess::Branch(n) => n.child_user_data(index), | 1267 | | } | 1268 | 475k | } |
Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE15child_user_dataB9_ |
1269 | | |
1270 | | /// Returns the child of this node at the given index. |
1271 | 7.60M | pub fn child(&'_ mut self, index: Nibble) -> Option<NodeAccess<'_, TUd>> { |
1272 | 7.60M | match self { |
1273 | 6.47M | NodeAccess::Storage(n) => n.child(index), |
1274 | 1.12M | NodeAccess::Branch(n) => n.child(index), |
1275 | | } |
1276 | 7.60M | } _RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE5childB9_ Line | Count | Source | 1271 | 82.1k | pub fn child(&'_ mut self, index: Nibble) -> Option<NodeAccess<'_, TUd>> { | 1272 | 82.1k | match self { | 1273 | 80.4k | NodeAccess::Storage(n) => n.child(index), | 1274 | 1.76k | NodeAccess::Branch(n) => n.child(index), | 1275 | | } | 1276 | 82.1k | } |
_RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE5childB9_ Line | Count | Source | 1271 | 7.49M | pub fn child(&'_ mut self, index: Nibble) -> Option<NodeAccess<'_, TUd>> { | 1272 | 7.49M | match self { | 1273 | 6.37M | NodeAccess::Storage(n) => n.child(index), | 1274 | 1.11M | NodeAccess::Branch(n) => n.child(index), | 1275 | | } | 1276 | 7.49M | } |
Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE5childCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccesspE5childB9_ _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE5childCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1271 | 3.07k | pub fn child(&'_ mut self, index: Nibble) -> Option<NodeAccess<'_, TUd>> { | 1272 | 3.07k | match self { | 1273 | 2.24k | NodeAccess::Storage(n) => n.child(index), | 1274 | 832 | NodeAccess::Branch(n) => n.child(index), | 1275 | | } | 1276 | 3.07k | } |
_RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE5childCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1271 | 29.1k | pub fn child(&'_ mut self, index: Nibble) -> Option<NodeAccess<'_, TUd>> { | 1272 | 29.1k | match self { | 1273 | 21.2k | NodeAccess::Storage(n) => n.child(index), | 1274 | 7.90k | NodeAccess::Branch(n) => n.child(index), | 1275 | | } | 1276 | 29.1k | } |
|
1277 | | |
1278 | | /// Returns the child of this node given the given index. |
1279 | | /// |
1280 | | /// Returns back `self` if there is no such child at this index. |
1281 | 0 | pub fn into_child(self, index: Nibble) -> Result<NodeAccess<'a, TUd>, Self> { |
1282 | 0 | match self { |
1283 | 0 | NodeAccess::Storage(n) => n.into_child(index).map_err(NodeAccess::Storage), |
1284 | 0 | NodeAccess::Branch(n) => n.into_child(index).map_err(NodeAccess::Branch), |
1285 | | } |
1286 | 0 | } Unexecuted instantiation: _RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccesspE10into_childB9_ Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccesspE10into_childB9_ |
1287 | | |
1288 | | /// Returns the first child of this node. |
1289 | | /// |
1290 | | /// Returns back `self` if this node doesn't have any children. |
1291 | 29.7k | pub fn into_first_child(self) -> Result<NodeAccess<'a, TUd>, Self> { |
1292 | 29.7k | match self { |
1293 | 29.7k | NodeAccess::Storage(n) => n.into_first_child().map_err(NodeAccess::Storage), |
1294 | 0 | NodeAccess::Branch(n) => n.into_first_child().map_err(NodeAccess::Branch), |
1295 | | } |
1296 | 29.7k | } _RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE16into_first_childB9_ Line | Count | Source | 1291 | 29.7k | pub fn into_first_child(self) -> Result<NodeAccess<'a, TUd>, Self> { | 1292 | 29.7k | match self { | 1293 | 29.7k | NodeAccess::Storage(n) => n.into_first_child().map_err(NodeAccess::Storage), | 1294 | 0 | NodeAccess::Branch(n) => n.into_first_child().map_err(NodeAccess::Branch), | 1295 | | } | 1296 | 29.7k | } |
Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE16into_first_childB9_ |
1297 | | |
1298 | | /// Returns the next sibling of this node. |
1299 | | /// |
1300 | | /// Returns back `self` if this node is the last child of its parent. |
1301 | 29.7k | pub fn into_next_sibling(self) -> Result<NodeAccess<'a, TUd>, Self> { |
1302 | 29.7k | match self { |
1303 | 29.7k | NodeAccess::Storage(n) => n.into_next_sibling().map_err(NodeAccess::Storage), |
1304 | 0 | NodeAccess::Branch(n) => n.into_next_sibling().map_err(NodeAccess::Branch), |
1305 | | } |
1306 | 29.7k | } _RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE17into_next_siblingB9_ Line | Count | Source | 1301 | 29.7k | pub fn into_next_sibling(self) -> Result<NodeAccess<'a, TUd>, Self> { | 1302 | 29.7k | match self { | 1303 | 29.7k | NodeAccess::Storage(n) => n.into_next_sibling().map_err(NodeAccess::Storage), | 1304 | 0 | NodeAccess::Branch(n) => n.into_next_sibling().map_err(NodeAccess::Branch), | 1305 | | } | 1306 | 29.7k | } |
Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE17into_next_siblingB9_ |
1307 | | |
1308 | | /// Returns true if this node is the root node of the trie. |
1309 | 471k | pub fn is_root_node(&self) -> bool { |
1310 | 471k | match self { |
1311 | 401k | NodeAccess::Storage(n) => n.is_root_node(), |
1312 | 70.1k | NodeAccess::Branch(n) => n.is_root_node(), |
1313 | | } |
1314 | 471k | } _RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE12is_root_nodeB9_ Line | Count | Source | 1309 | 2.56k | pub fn is_root_node(&self) -> bool { | 1310 | 2.56k | match self { | 1311 | 2.51k | NodeAccess::Storage(n) => n.is_root_node(), | 1312 | 55 | NodeAccess::Branch(n) => n.is_root_node(), | 1313 | | } | 1314 | 2.56k | } |
_RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE12is_root_nodeB9_ Line | Count | Source | 1309 | 468k | pub fn is_root_node(&self) -> bool { | 1310 | 468k | match self { | 1311 | 398k | NodeAccess::Storage(n) => n.is_root_node(), | 1312 | 69.7k | NodeAccess::Branch(n) => n.is_root_node(), | 1313 | | } | 1314 | 468k | } |
Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE12is_root_nodeCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccesspE12is_root_nodeB9_ _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE12is_root_nodeCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1309 | 96 | pub fn is_root_node(&self) -> bool { | 1310 | 96 | match self { | 1311 | 70 | NodeAccess::Storage(n) => n.is_root_node(), | 1312 | 26 | NodeAccess::Branch(n) => n.is_root_node(), | 1313 | | } | 1314 | 96 | } |
_RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE12is_root_nodeCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1309 | 912 | pub fn is_root_node(&self) -> bool { | 1310 | 912 | match self { | 1311 | 665 | NodeAccess::Storage(n) => n.is_root_node(), | 1312 | 247 | NodeAccess::Branch(n) => n.is_root_node(), | 1313 | | } | 1314 | 912 | } |
|
1315 | | |
1316 | | /// Returns the full key of the node. |
1317 | 0 | pub fn full_key(&self) -> impl Iterator<Item = Nibble> { |
1318 | 0 | match self { |
1319 | 0 | NodeAccess::Storage(n) => Either::Left(n.full_key()), |
1320 | 0 | NodeAccess::Branch(n) => Either::Right(n.full_key()), |
1321 | | } |
1322 | 0 | } Unexecuted instantiation: _RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccesspE8full_keyB9_ Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccesspE8full_keyB9_ |
1323 | | |
1324 | | /// Returns the partial key of the node. |
1325 | 505k | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { |
1326 | 505k | match self { |
1327 | 428k | NodeAccess::Storage(n) => Either::Left(n.partial_key()), |
1328 | 76.2k | NodeAccess::Branch(n) => Either::Right(n.partial_key()), |
1329 | | } |
1330 | 505k | } _RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE11partial_keyB9_ Line | Count | Source | 1325 | 5.13k | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { | 1326 | 5.13k | match self { | 1327 | 5.02k | NodeAccess::Storage(n) => Either::Left(n.partial_key()), | 1328 | 110 | NodeAccess::Branch(n) => Either::Right(n.partial_key()), | 1329 | | } | 1330 | 5.13k | } |
_RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE11partial_keyB9_ Line | Count | Source | 1325 | 468k | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { | 1326 | 468k | match self { | 1327 | 398k | NodeAccess::Storage(n) => Either::Left(n.partial_key()), | 1328 | 69.7k | NodeAccess::Branch(n) => Either::Right(n.partial_key()), | 1329 | | } | 1330 | 468k | } |
_RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessuE11partial_keyB9_ Line | Count | Source | 1325 | 29.7k | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { | 1326 | 29.7k | match self { | 1327 | 23.9k | NodeAccess::Storage(n) => Either::Left(n.partial_key()), | 1328 | 5.77k | NodeAccess::Branch(n) => Either::Right(n.partial_key()), | 1329 | | } | 1330 | 29.7k | } |
Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE11partial_keyCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccesspE11partial_keyB9_ _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE11partial_keyCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1325 | 192 | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { | 1326 | 192 | match self { | 1327 | 140 | NodeAccess::Storage(n) => Either::Left(n.partial_key()), | 1328 | 52 | NodeAccess::Branch(n) => Either::Right(n.partial_key()), | 1329 | | } | 1330 | 192 | } |
_RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE11partial_keyCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1325 | 1.82k | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { | 1326 | 1.82k | match self { | 1327 | 1.33k | NodeAccess::Storage(n) => Either::Left(n.partial_key()), | 1328 | 494 | NodeAccess::Branch(n) => Either::Right(n.partial_key()), | 1329 | | } | 1330 | 1.82k | } |
|
1331 | | |
1332 | | /// Returns the user data stored in the node. |
1333 | 1.42M | pub fn user_data(&mut self) -> &mut TUd { |
1334 | 1.42M | match self { |
1335 | 1.22M | NodeAccess::Storage(n) => n.user_data(), |
1336 | 199k | NodeAccess::Branch(n) => n.user_data(), |
1337 | | } |
1338 | 1.42M | } _RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE9user_dataB9_ Line | Count | Source | 1333 | 72.8k | pub fn user_data(&mut self) -> &mut TUd { | 1334 | 72.8k | match self { | 1335 | 72.8k | NodeAccess::Storage(n) => n.user_data(), | 1336 | 0 | NodeAccess::Branch(n) => n.user_data(), | 1337 | | } | 1338 | 72.8k | } |
_RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE9user_dataB9_ Line | Count | Source | 1333 | 5.65k | pub fn user_data(&mut self) -> &mut TUd { | 1334 | 5.65k | match self { | 1335 | 5.49k | NodeAccess::Storage(n) => n.user_data(), | 1336 | 165 | NodeAccess::Branch(n) => n.user_data(), | 1337 | | } | 1338 | 5.65k | } |
_RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE9user_dataB9_ Line | Count | Source | 1333 | 1.33M | pub fn user_data(&mut self) -> &mut TUd { | 1334 | 1.33M | match self { | 1335 | 1.14M | NodeAccess::Storage(n) => n.user_data(), | 1336 | 198k | NodeAccess::Branch(n) => n.user_data(), | 1337 | | } | 1338 | 1.33M | } |
Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE9user_dataCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE9user_dataB9_ _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE9user_dataCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1333 | 380 | pub fn user_data(&mut self) -> &mut TUd { | 1334 | 380 | match self { | 1335 | 280 | NodeAccess::Storage(n) => n.user_data(), | 1336 | 100 | NodeAccess::Branch(n) => n.user_data(), | 1337 | | } | 1338 | 380 | } |
_RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE9user_dataCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1333 | 3.61k | pub fn user_data(&mut self) -> &mut TUd { | 1334 | 3.61k | match self { | 1335 | 2.66k | NodeAccess::Storage(n) => n.user_data(), | 1336 | 950 | NodeAccess::Branch(n) => n.user_data(), | 1337 | | } | 1338 | 3.61k | } |
|
1339 | | |
1340 | | /// Returns the user data stored in the node. |
1341 | 487k | pub fn into_user_data(self) -> &'a mut TUd { |
1342 | 487k | match self { |
1343 | 417k | NodeAccess::Storage(n) => n.into_user_data(), |
1344 | 70.7k | NodeAccess::Branch(n) => n.into_user_data(), |
1345 | | } |
1346 | 487k | } _RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE14into_user_dataB9_ Line | Count | Source | 1341 | 2.56k | pub fn into_user_data(self) -> &'a mut TUd { | 1342 | 2.56k | match self { | 1343 | 2.51k | NodeAccess::Storage(n) => n.into_user_data(), | 1344 | 55 | NodeAccess::Branch(n) => n.into_user_data(), | 1345 | | } | 1346 | 2.56k | } |
_RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE14into_user_dataB9_ Line | Count | Source | 1341 | 484k | pub fn into_user_data(self) -> &'a mut TUd { | 1342 | 484k | match self { | 1343 | 413k | NodeAccess::Storage(n) => n.into_user_data(), | 1344 | 70.4k | NodeAccess::Branch(n) => n.into_user_data(), | 1345 | | } | 1346 | 484k | } |
Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE14into_user_dataCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccesspE14into_user_dataB9_ _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE14into_user_dataCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1341 | 96 | pub fn into_user_data(self) -> &'a mut TUd { | 1342 | 96 | match self { | 1343 | 70 | NodeAccess::Storage(n) => n.into_user_data(), | 1344 | 26 | NodeAccess::Branch(n) => n.into_user_data(), | 1345 | | } | 1346 | 96 | } |
_RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1a_NtNtB7_9trie_node17MerkleValueOutputEEE14into_user_dataCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1341 | 912 | pub fn into_user_data(self) -> &'a mut TUd { | 1342 | 912 | match self { | 1343 | 665 | NodeAccess::Storage(n) => n.into_user_data(), | 1344 | 247 | NodeAccess::Branch(n) => n.into_user_data(), | 1345 | | } | 1346 | 912 | } |
|
1347 | | |
1348 | | /// Returns true if the node has a storage value associated to it. |
1349 | 29.7k | pub fn has_storage_value(&self) -> bool { |
1350 | 29.7k | match self { |
1351 | 23.9k | NodeAccess::Storage(_) => true, |
1352 | 5.77k | NodeAccess::Branch(_) => false, |
1353 | | } |
1354 | 29.7k | } _RNvMs4_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_10NodeAccessuE17has_storage_valueB9_ Line | Count | Source | 1349 | 29.7k | pub fn has_storage_value(&self) -> bool { | 1350 | 29.7k | match self { | 1351 | 23.9k | NodeAccess::Storage(_) => true, | 1352 | 5.77k | NodeAccess::Branch(_) => false, | 1353 | | } | 1354 | 29.7k | } |
Unexecuted instantiation: _RNvMs4_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_10NodeAccesspE17has_storage_valueB9_ |
1355 | | } |
1356 | | |
1357 | | /// Access to a node within the [`TrieStructure`] that is known to have a storage value associated |
1358 | | /// to it. |
1359 | | pub struct StorageNodeAccess<'a, TUd> { |
1360 | | trie: &'a mut TrieStructure<TUd>, |
1361 | | node_index: usize, |
1362 | | } |
1363 | | |
1364 | | impl<'a, TUd> StorageNodeAccess<'a, TUd> { |
1365 | | /// Returns an opaque [`NodeIndex`] representing the node in the trie. |
1366 | | /// |
1367 | | /// It can later be used to retrieve this same node using [`TrieStructure::node_by_index`]. |
1368 | 1.50k | pub fn node_index(&self) -> NodeIndex { |
1369 | 1.50k | NodeIndex(self.node_index) |
1370 | 1.50k | } _RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE10node_indexB9_ Line | Count | Source | 1368 | 1.50k | pub fn node_index(&self) -> NodeIndex { | 1369 | 1.50k | NodeIndex(self.node_index) | 1370 | 1.50k | } |
Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE10node_indexB9_ |
1371 | | |
1372 | | /// Returns the parent of this node, or `None` if this is the root node. |
1373 | 9.63k | pub fn into_parent(self) -> Option<NodeAccess<'a, TUd>> { |
1374 | 9.63k | let parent_idx8.13k = self.trie.nodes.get(self.node_index).unwrap().parent?1.50k .0; |
1375 | 8.13k | Some(self.trie.node_by_index_inner(parent_idx).unwrap()) |
1376 | 9.63k | } _RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE11into_parentB9_ Line | Count | Source | 1373 | 9.63k | pub fn into_parent(self) -> Option<NodeAccess<'a, TUd>> { | 1374 | 9.63k | let parent_idx8.13k = self.trie.nodes.get(self.node_index).unwrap().parent?1.50k .0; | 1375 | 8.13k | Some(self.trie.node_by_index_inner(parent_idx).unwrap()) | 1376 | 9.63k | } |
Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE11into_parentB9_ |
1377 | | |
1378 | | /// Returns the parent of this node, or `None` if this is the root node. |
1379 | 0 | pub fn parent(&'_ mut self) -> Option<NodeAccess<'_, TUd>> { |
1380 | 0 | let parent_idx = self.trie.nodes.get(self.node_index).unwrap().parent?.0; |
1381 | 0 | Some(self.trie.node_by_index_inner(parent_idx).unwrap()) |
1382 | 0 | } Unexecuted instantiation: _RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccesspE6parentB9_ Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccesspE6parentB9_ |
1383 | | |
1384 | | /// Returns the first child of this node. |
1385 | | /// |
1386 | | /// Returns back `self` if this node doesn't have any children. |
1387 | 29.7k | pub fn into_first_child(self) -> Result<NodeAccess<'a, TUd>, Self> { |
1388 | 29.7k | let first_child_idx = self |
1389 | 29.7k | .trie |
1390 | 29.7k | .nodes |
1391 | 29.7k | .get(self.node_index) |
1392 | 29.7k | .unwrap() |
1393 | 29.7k | .children |
1394 | 29.7k | .iter() |
1395 | 29.7k | .find_map(|c| *c); |
1396 | | |
1397 | 29.7k | let first_child_idx8.13k = match first_child_idx { |
1398 | 8.13k | Some(fc) => fc, |
1399 | 21.6k | None => return Err(self), |
1400 | | }; |
1401 | | |
1402 | 8.13k | Ok(self.trie.node_by_index_inner(first_child_idx).unwrap()) |
1403 | 29.7k | } _RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE16into_first_childB9_ Line | Count | Source | 1387 | 29.7k | pub fn into_first_child(self) -> Result<NodeAccess<'a, TUd>, Self> { | 1388 | 29.7k | let first_child_idx = self | 1389 | 29.7k | .trie | 1390 | 29.7k | .nodes | 1391 | 29.7k | .get(self.node_index) | 1392 | 29.7k | .unwrap() | 1393 | 29.7k | .children | 1394 | 29.7k | .iter() | 1395 | 29.7k | .find_map(|c| *c); | 1396 | | | 1397 | 29.7k | let first_child_idx8.13k = match first_child_idx { | 1398 | 8.13k | Some(fc) => fc, | 1399 | 21.6k | None => return Err(self), | 1400 | | }; | 1401 | | | 1402 | 8.13k | Ok(self.trie.node_by_index_inner(first_child_idx).unwrap()) | 1403 | 29.7k | } |
Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE16into_first_childB9_ |
1404 | | |
1405 | | /// Returns the next sibling of this node. |
1406 | | /// |
1407 | | /// Returns back `self` if this node is the last child of its parent. |
1408 | 29.7k | pub fn into_next_sibling(self) -> Result<NodeAccess<'a, TUd>, Self> { |
1409 | 29.7k | let next_sibling_idx20.1k = match self.trie.next_sibling(self.node_index) { |
1410 | 20.1k | Some(ns) => ns, |
1411 | 9.63k | None => return Err(self), |
1412 | | }; |
1413 | | |
1414 | 20.1k | Ok(self.trie.node_by_index_inner(next_sibling_idx).unwrap()) |
1415 | 29.7k | } _RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE17into_next_siblingB9_ Line | Count | Source | 1408 | 29.7k | pub fn into_next_sibling(self) -> Result<NodeAccess<'a, TUd>, Self> { | 1409 | 29.7k | let next_sibling_idx20.1k = match self.trie.next_sibling(self.node_index) { | 1410 | 20.1k | Some(ns) => ns, | 1411 | 9.63k | None => return Err(self), | 1412 | | }; | 1413 | | | 1414 | 20.1k | Ok(self.trie.node_by_index_inner(next_sibling_idx).unwrap()) | 1415 | 29.7k | } |
Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE17into_next_siblingB9_ |
1416 | | |
1417 | | /// Returns the child of this node at the given index. |
1418 | 6.47M | pub fn child(&'_ mut self, index: Nibble) -> Option<NodeAccess<'_, TUd>> { |
1419 | 203k | let child_idx = |
1420 | 6.47M | self.trie.nodes.get(self.node_index).unwrap().children[usize::from(u8::from(index))]?6.27M ; |
1421 | 203k | Some(self.trie.node_by_index_inner(child_idx).unwrap()) |
1422 | 6.47M | } _RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE5childB9_ Line | Count | Source | 1418 | 80.4k | pub fn child(&'_ mut self, index: Nibble) -> Option<NodeAccess<'_, TUd>> { | 1419 | 2.86k | let child_idx = | 1420 | 80.4k | self.trie.nodes.get(self.node_index).unwrap().children[usize::from(u8::from(index))]?77.5k ; | 1421 | 2.86k | Some(self.trie.node_by_index_inner(child_idx).unwrap()) | 1422 | 80.4k | } |
_RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE5childB9_ Line | Count | Source | 1418 | 6.37M | pub fn child(&'_ mut self, index: Nibble) -> Option<NodeAccess<'_, TUd>> { | 1419 | 200k | let child_idx = | 1420 | 6.37M | self.trie.nodes.get(self.node_index).unwrap().children[usize::from(u8::from(index))]?6.17M ; | 1421 | 200k | Some(self.trie.node_by_index_inner(child_idx).unwrap()) | 1422 | 6.37M | } |
Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE5childCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccesspE5childB9_ _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE5childCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1418 | 2.24k | pub fn child(&'_ mut self, index: Nibble) -> Option<NodeAccess<'_, TUd>> { | 1419 | 0 | let child_idx = | 1420 | 2.24k | self.trie.nodes.get(self.node_index).unwrap().children[usize::from(u8::from(index))]?; | 1421 | 0 | Some(self.trie.node_by_index_inner(child_idx).unwrap()) | 1422 | 2.24k | } |
_RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE5childCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1418 | 21.2k | pub fn child(&'_ mut self, index: Nibble) -> Option<NodeAccess<'_, TUd>> { | 1419 | 0 | let child_idx = | 1420 | 21.2k | self.trie.nodes.get(self.node_index).unwrap().children[usize::from(u8::from(index))]?; | 1421 | 0 | Some(self.trie.node_by_index_inner(child_idx).unwrap()) | 1422 | 21.2k | } |
|
1423 | | |
1424 | | /// Returns the user data of the child at the given index. |
1425 | | /// |
1426 | | /// > **Note**: This method exists because it accepts `&self` rather than `&mut self`. A |
1427 | | /// > cleaner alternative would be to split the [`NodeAccess`] struct into |
1428 | | /// > `NodeAccessRef` and `NodeAccessMut`, but that's a lot of efforts compare to |
1429 | | /// > this single method. |
1430 | 859k | pub fn child_user_data(&self, index: Nibble) -> Option<&TUd> { |
1431 | 40.6k | let child_idx = |
1432 | 859k | self.trie.nodes.get(self.node_index).unwrap().children[usize::from(u8::from(index))]?818k ; |
1433 | 40.6k | Some(&self.trie.nodes.get(child_idx).unwrap().user_data) |
1434 | 859k | } _RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE15child_user_dataB9_ Line | Count | Source | 1430 | 475k | pub fn child_user_data(&self, index: Nibble) -> Option<&TUd> { | 1431 | 28.2k | let child_idx = | 1432 | 475k | self.trie.nodes.get(self.node_index).unwrap().children[usize::from(u8::from(index))]?447k ; | 1433 | 28.2k | Some(&self.trie.nodes.get(child_idx).unwrap().user_data) | 1434 | 475k | } |
_RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessuE15child_user_dataB9_ Line | Count | Source | 1430 | 383k | pub fn child_user_data(&self, index: Nibble) -> Option<&TUd> { | 1431 | 12.3k | let child_idx = | 1432 | 383k | self.trie.nodes.get(self.node_index).unwrap().children[usize::from(u8::from(index))]?371k ; | 1433 | 12.3k | Some(&self.trie.nodes.get(child_idx).unwrap().user_data) | 1434 | 383k | } |
Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE15child_user_dataB9_ |
1435 | | |
1436 | | /// Returns the child of this node given the given index. |
1437 | | /// |
1438 | | /// Returns back `self` if there is no such child at this index. |
1439 | 0 | pub fn into_child(self, index: Nibble) -> Result<NodeAccess<'a, TUd>, Self> { |
1440 | 0 | let child_idx = match self.trie.nodes.get(self.node_index).unwrap().children |
1441 | 0 | [usize::from(u8::from(index))] |
1442 | | { |
1443 | 0 | Some(c) => c, |
1444 | 0 | None => return Err(self), |
1445 | | }; |
1446 | | |
1447 | 0 | Ok(self.trie.node_by_index_inner(child_idx).unwrap()) |
1448 | 0 | } Unexecuted instantiation: _RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccesspE10into_childB9_ Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccesspE10into_childB9_ |
1449 | | |
1450 | | /// Returns true if this node is the root node of the trie. |
1451 | 401k | pub fn is_root_node(&self) -> bool { |
1452 | 401k | self.trie.root_index == Some(self.node_index) |
1453 | 401k | } _RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE12is_root_nodeB9_ Line | Count | Source | 1451 | 2.51k | pub fn is_root_node(&self) -> bool { | 1452 | 2.51k | self.trie.root_index == Some(self.node_index) | 1453 | 2.51k | } |
_RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE12is_root_nodeB9_ Line | Count | Source | 1451 | 398k | pub fn is_root_node(&self) -> bool { | 1452 | 398k | self.trie.root_index == Some(self.node_index) | 1453 | 398k | } |
Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE12is_root_nodeCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccesspE12is_root_nodeB9_ _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE12is_root_nodeCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1451 | 70 | pub fn is_root_node(&self) -> bool { | 1452 | 70 | self.trie.root_index == Some(self.node_index) | 1453 | 70 | } |
_RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE12is_root_nodeCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1451 | 665 | pub fn is_root_node(&self) -> bool { | 1452 | 665 | self.trie.root_index == Some(self.node_index) | 1453 | 665 | } |
|
1454 | | |
1455 | | /// Returns the full key of the node. |
1456 | 0 | pub fn full_key(&self) -> impl Iterator<Item = Nibble> { |
1457 | 0 | self.trie.node_full_key(self.node_index) |
1458 | 0 | } Unexecuted instantiation: _RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccesspE8full_keyB9_ Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccesspE8full_keyB9_ |
1459 | | |
1460 | | /// Returns the partial key of the node. |
1461 | 428k | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { |
1462 | 428k | self.trie |
1463 | 428k | .nodes |
1464 | 428k | .get(self.node_index) |
1465 | 428k | .unwrap() |
1466 | 428k | .partial_key |
1467 | 428k | .iter() |
1468 | 428k | .cloned() |
1469 | 428k | } _RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE11partial_keyB9_ Line | Count | Source | 1461 | 5.02k | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { | 1462 | 5.02k | self.trie | 1463 | 5.02k | .nodes | 1464 | 5.02k | .get(self.node_index) | 1465 | 5.02k | .unwrap() | 1466 | 5.02k | .partial_key | 1467 | 5.02k | .iter() | 1468 | 5.02k | .cloned() | 1469 | 5.02k | } |
_RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE11partial_keyB9_ Line | Count | Source | 1461 | 398k | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { | 1462 | 398k | self.trie | 1463 | 398k | .nodes | 1464 | 398k | .get(self.node_index) | 1465 | 398k | .unwrap() | 1466 | 398k | .partial_key | 1467 | 398k | .iter() | 1468 | 398k | .cloned() | 1469 | 398k | } |
_RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessuE11partial_keyB9_ Line | Count | Source | 1461 | 23.9k | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { | 1462 | 23.9k | self.trie | 1463 | 23.9k | .nodes | 1464 | 23.9k | .get(self.node_index) | 1465 | 23.9k | .unwrap() | 1466 | 23.9k | .partial_key | 1467 | 23.9k | .iter() | 1468 | 23.9k | .cloned() | 1469 | 23.9k | } |
Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE11partial_keyCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccesspE11partial_keyB9_ _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE11partial_keyCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1461 | 140 | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { | 1462 | 140 | self.trie | 1463 | 140 | .nodes | 1464 | 140 | .get(self.node_index) | 1465 | 140 | .unwrap() | 1466 | 140 | .partial_key | 1467 | 140 | .iter() | 1468 | 140 | .cloned() | 1469 | 140 | } |
_RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE11partial_keyCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1461 | 1.33k | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { | 1462 | 1.33k | self.trie | 1463 | 1.33k | .nodes | 1464 | 1.33k | .get(self.node_index) | 1465 | 1.33k | .unwrap() | 1466 | 1.33k | .partial_key | 1467 | 1.33k | .iter() | 1468 | 1.33k | .cloned() | 1469 | 1.33k | } |
|
1470 | | |
1471 | | /// Returns the user data associated to this node. |
1472 | 482k | pub fn into_user_data(self) -> &'a mut TUd { |
1473 | 482k | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data |
1474 | 482k | } _RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE14into_user_dataB9_ Line | Count | Source | 1472 | 2.51k | pub fn into_user_data(self) -> &'a mut TUd { | 1473 | 2.51k | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data | 1474 | 2.51k | } |
_RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE14into_user_dataB9_ Line | Count | Source | 1472 | 478k | pub fn into_user_data(self) -> &'a mut TUd { | 1473 | 478k | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data | 1474 | 478k | } |
Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE14into_user_dataCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccesspE14into_user_dataB9_ _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE14into_user_dataCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1472 | 70 | pub fn into_user_data(self) -> &'a mut TUd { | 1473 | 70 | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data | 1474 | 70 | } |
_RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE14into_user_dataCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1472 | 665 | pub fn into_user_data(self) -> &'a mut TUd { | 1473 | 665 | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data | 1474 | 665 | } |
|
1475 | | |
1476 | | /// Returns the user data associated to this node. |
1477 | 1.39M | pub fn user_data(&mut self) -> &mut TUd { |
1478 | 1.39M | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data |
1479 | 1.39M | } _RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE9user_dataB9_ Line | Count | Source | 1477 | 72.8k | pub fn user_data(&mut self) -> &mut TUd { | 1478 | 72.8k | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data | 1479 | 72.8k | } |
_RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE9user_dataB9_ Line | Count | Source | 1477 | 5.49k | pub fn user_data(&mut self) -> &mut TUd { | 1478 | 5.49k | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data | 1479 | 5.49k | } |
_RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE9user_dataB9_ Line | Count | Source | 1477 | 1.31M | pub fn user_data(&mut self) -> &mut TUd { | 1478 | 1.31M | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data | 1479 | 1.31M | } |
Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE9user_dataCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE9user_dataB9_ _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE9user_dataCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1477 | 280 | pub fn user_data(&mut self) -> &mut TUd { | 1478 | 280 | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data | 1479 | 280 | } |
_RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE9user_dataCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1477 | 2.66k | pub fn user_data(&mut self) -> &mut TUd { | 1478 | 2.66k | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data | 1479 | 2.66k | } |
|
1480 | | |
1481 | | /// Removes the storage value and returns what this changes in the trie structure. |
1482 | 135k | pub fn remove(self) -> Remove<'a, TUd> { |
1483 | | // If the removed node has 2 or more children, then the node continues as a branch node. |
1484 | | { |
1485 | 135k | let node = self.trie.nodes.get_mut(self.node_index).unwrap(); |
1486 | 2.16M | if node.children135k .iter135k ().filter135k (|c| c.is_some()).count135k () >= 2 { _RNCNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB9_16TrieEntryVersionEEIB1j_NtNtB9_9trie_node17MerkleValueOutputEEE6remove0Bb_ Line | Count | Source | 1486 | 1.37M | if node.children.iter().filter(|c| c.is_some()).count() >= 2 { |
_RNCNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_17StorageNodeAccessuE6remove0Bb_ Line | Count | Source | 1486 | 794k | if node.children.iter().filter(|c| c.is_some()).count() >= 2 { |
Unexecuted instantiation: _RNCNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB7_17StorageNodeAccesspE6remove0Bb_ |
1487 | 71.8k | node.has_storage_value = false; |
1488 | 71.8k | return Remove::StorageToBranch(BranchNodeAccess { |
1489 | 71.8k | trie: self.trie, |
1490 | 71.8k | node_index: self.node_index, |
1491 | 71.8k | }); |
1492 | 63.6k | } |
1493 | | } |
1494 | | |
1495 | 63.6k | let removed_node = self.trie.nodes.remove(self.node_index); |
1496 | 63.6k | debug_assert!(removed_node.has_storage_value); |
1497 | | |
1498 | | // We already know from above that the removed node has only 0 or 1 children. Let's |
1499 | | // determine which. |
1500 | 63.6k | let child_node_index: Option<usize> = removed_node.children.iter().find_map(|c| *c); |
1501 | | |
1502 | | // If relevant, update our single child's parent to point to `removed_node`'s parent. |
1503 | 63.6k | if let Some(child_node_index12.2k ) = child_node_index { |
1504 | 12.2k | let child = self.trie.nodes.get_mut(child_node_index).unwrap(); |
1505 | 12.2k | debug_assert_eq!(child.parent.as_ref().unwrap().0, self.node_index); |
1506 | 12.2k | insert_front( |
1507 | 12.2k | &mut child.partial_key, |
1508 | 12.2k | removed_node.partial_key, |
1509 | 12.2k | child.parent.unwrap().1, |
1510 | | ); |
1511 | 12.2k | child.parent = removed_node.parent; |
1512 | 51.4k | } |
1513 | | |
1514 | | // At this point, we're almost done with removing `removed_node` from `self.trie`. However |
1515 | | // there is potentially another change to make: maybe `parent` has to be removed from the |
1516 | | // trie as well. |
1517 | | |
1518 | | // Update `parent`'s child to point to `child_node_index`. |
1519 | | // `single_remove` is true if we can keep `parent` in the trie. |
1520 | 63.6k | let single_remove = if let Some((parent_index48.1k , parent_to_removed_child_index48.1k )) = |
1521 | 63.6k | removed_node.parent |
1522 | | { |
1523 | | // Update `removed_node`'s parent to point to the child. |
1524 | 48.1k | let parent = self.trie.nodes.get_mut(parent_index).unwrap(); |
1525 | 48.1k | debug_assert_eq!( |
1526 | 48.1k | parent.children[usize::from(u8::from(parent_to_removed_child_index))], |
1527 | 48.1k | Some(self.node_index) |
1528 | | ); |
1529 | 48.1k | parent.children[usize::from(u8::from(parent_to_removed_child_index))] = |
1530 | 48.1k | child_node_index; |
1531 | | |
1532 | | // If `parent` does *not* need to be removed, we can return early. |
1533 | 377k | parent.has_storage_value48.1k || parent.children23.5k .iter23.5k ().filter23.5k (|c| c.is_some()).count23.5k () >= 2 _RNCNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB9_16TrieEntryVersionEEIB1j_NtNtB9_9trie_node17MerkleValueOutputEEE6removes0_0Bb_ Line | Count | Source | 1533 | 2.04k | parent.has_storage_value || parent.children.iter().filter(|c| c.is_some()).count() >= 2 |
_RNCNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_17StorageNodeAccessuE6removes0_0Bb_ Line | Count | Source | 1533 | 374k | parent.has_storage_value || parent.children.iter().filter(|c| c.is_some()).count() >= 2 |
Unexecuted instantiation: _RNCNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB7_17StorageNodeAccesspE6removes0_0Bb_ |
1534 | | } else { |
1535 | 15.4k | debug_assert_eq!(self.trie.root_index, Some(self.node_index)); |
1536 | 15.4k | self.trie.root_index = child_node_index; |
1537 | 15.4k | true |
1538 | | }; |
1539 | | |
1540 | | // If we keep the parent in the trie, return early with a `SingleRemove`. |
1541 | 63.6k | if single_remove { |
1542 | 52.9k | return if let Some(child_node_index12.2k ) = child_node_index { |
1543 | 12.2k | Remove::SingleRemoveChild { |
1544 | 12.2k | user_data: removed_node.user_data, |
1545 | 12.2k | child: self.trie.node_by_index_inner(child_node_index).unwrap(), |
1546 | 12.2k | } |
1547 | 40.6k | } else if let Some((parent_index34.0k , _)) = removed_node.parent { |
1548 | 34.0k | Remove::SingleRemoveNoChild { |
1549 | 34.0k | user_data: removed_node.user_data, |
1550 | 34.0k | parent: self.trie.node_by_index_inner(parent_index).unwrap(), |
1551 | 34.0k | } |
1552 | | } else { |
1553 | 6.58k | debug_assert!(self.trie.nodes.is_empty()); |
1554 | 6.58k | debug_assert!(self.trie.root_index.is_none()); |
1555 | 6.58k | Remove::TrieNowEmpty { |
1556 | 6.58k | user_data: removed_node.user_data, |
1557 | 6.58k | } |
1558 | | }; |
1559 | 10.7k | } |
1560 | | |
1561 | | // If we reach here, then parent has to be removed from the trie as well. |
1562 | 10.7k | let parent_index = removed_node.parent.unwrap().0; |
1563 | 10.7k | debug_assert!(child_node_index.is_none()); |
1564 | 10.7k | let removed_branch = self.trie.nodes.remove(parent_index); |
1565 | 10.7k | debug_assert!(!removed_branch.has_storage_value); |
1566 | | |
1567 | | // We already know from above that the removed branch has exactly 1 sibling. Let's |
1568 | | // determine which. |
1569 | 10.7k | debug_assert_eq!( |
1570 | 10.7k | removed_branch |
1571 | 10.7k | .children |
1572 | 10.7k | .iter() |
1573 | 171k | .filter10.7k (|c| c.is_some()) _RNCNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB9_16TrieEntryVersionEEIB1j_NtNtB9_9trie_node17MerkleValueOutputEEE6removes2_0Bb_ Line | Count | Source | 1573 | 992 | .filter(|c| c.is_some()) |
_RNCNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_17StorageNodeAccessuE6removes2_0Bb_ Line | Count | Source | 1573 | 170k | .filter(|c| c.is_some()) |
Unexecuted instantiation: _RNCNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB7_17StorageNodeAccesspE6removes2_0Bb_ |
1574 | 10.7k | .count(), |
1575 | | 1 |
1576 | | ); |
1577 | 10.7k | let sibling_node_index: usize = removed_branch.children.iter().find_map(|c| *c).unwrap(); |
1578 | | |
1579 | | // Update the sibling to point to the parent's parent. |
1580 | | { |
1581 | 10.7k | let sibling = self.trie.nodes.get_mut(sibling_node_index).unwrap(); |
1582 | 10.7k | debug_assert_eq!(sibling.parent.as_ref().unwrap().0, parent_index); |
1583 | 10.7k | insert_front( |
1584 | 10.7k | &mut sibling.partial_key, |
1585 | 10.7k | removed_branch.partial_key, |
1586 | 10.7k | sibling.parent.unwrap().1, |
1587 | | ); |
1588 | 10.7k | sibling.parent = removed_branch.parent; |
1589 | | } |
1590 | | |
1591 | | // Update the parent's parent to point to the sibling. |
1592 | 10.7k | if let Some((parent_parent_index9.97k , parent_to_sibling_index9.97k )) = removed_branch.parent { |
1593 | | // Update the parent's parent to point to the sibling. |
1594 | 9.97k | let parent_parent = self.trie.nodes.get_mut(parent_parent_index).unwrap(); |
1595 | 9.97k | debug_assert_eq!( |
1596 | 9.97k | parent_parent.children[usize::from(u8::from(parent_to_sibling_index))], |
1597 | 9.97k | Some(parent_index) |
1598 | | ); |
1599 | 9.97k | parent_parent.children[usize::from(u8::from(parent_to_sibling_index))] = |
1600 | 9.97k | Some(sibling_node_index); |
1601 | | } else { |
1602 | 777 | debug_assert_eq!(self.trie.root_index, Some(parent_index)); |
1603 | 777 | self.trie.root_index = Some(sibling_node_index); |
1604 | | } |
1605 | | |
1606 | | // Success! |
1607 | 10.7k | Remove::BranchAlsoRemoved { |
1608 | 10.7k | sibling: self.trie.node_by_index_inner(sibling_node_index).unwrap(), |
1609 | 10.7k | storage_user_data: removed_node.user_data, |
1610 | 10.7k | branch_user_data: removed_branch.user_data, |
1611 | 10.7k | } |
1612 | 135k | } _RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1h_NtNtB7_9trie_node17MerkleValueOutputEEE6removeB9_ Line | Count | Source | 1482 | 85.8k | pub fn remove(self) -> Remove<'a, TUd> { | 1483 | | // If the removed node has 2 or more children, then the node continues as a branch node. | 1484 | | { | 1485 | 85.8k | let node = self.trie.nodes.get_mut(self.node_index).unwrap(); | 1486 | 85.8k | if node.children.iter().filter(|c| c.is_some()).count() >= 2 { | 1487 | 70.4k | node.has_storage_value = false; | 1488 | 70.4k | return Remove::StorageToBranch(BranchNodeAccess { | 1489 | 70.4k | trie: self.trie, | 1490 | 70.4k | node_index: self.node_index, | 1491 | 70.4k | }); | 1492 | 15.3k | } | 1493 | | } | 1494 | | | 1495 | 15.3k | let removed_node = self.trie.nodes.remove(self.node_index); | 1496 | 15.3k | debug_assert!(removed_node.has_storage_value); | 1497 | | | 1498 | | // We already know from above that the removed node has only 0 or 1 children. Let's | 1499 | | // determine which. | 1500 | 15.3k | let child_node_index: Option<usize> = removed_node.children.iter().find_map(|c| *c); | 1501 | | | 1502 | | // If relevant, update our single child's parent to point to `removed_node`'s parent. | 1503 | 15.3k | if let Some(child_node_index8.87k ) = child_node_index { | 1504 | 8.87k | let child = self.trie.nodes.get_mut(child_node_index).unwrap(); | 1505 | 8.87k | debug_assert_eq!(child.parent.as_ref().unwrap().0, self.node_index); | 1506 | 8.87k | insert_front( | 1507 | 8.87k | &mut child.partial_key, | 1508 | 8.87k | removed_node.partial_key, | 1509 | 8.87k | child.parent.unwrap().1, | 1510 | | ); | 1511 | 8.87k | child.parent = removed_node.parent; | 1512 | 6.47k | } | 1513 | | | 1514 | | // At this point, we're almost done with removing `removed_node` from `self.trie`. However | 1515 | | // there is potentially another change to make: maybe `parent` has to be removed from the | 1516 | | // trie as well. | 1517 | | | 1518 | | // Update `parent`'s child to point to `child_node_index`. | 1519 | | // `single_remove` is true if we can keep `parent` in the trie. | 1520 | 15.3k | let single_remove = if let Some((parent_index262 , parent_to_removed_child_index262 )) = | 1521 | 15.3k | removed_node.parent | 1522 | | { | 1523 | | // Update `removed_node`'s parent to point to the child. | 1524 | 262 | let parent = self.trie.nodes.get_mut(parent_index).unwrap(); | 1525 | 262 | debug_assert_eq!( | 1526 | 262 | parent.children[usize::from(u8::from(parent_to_removed_child_index))], | 1527 | 262 | Some(self.node_index) | 1528 | | ); | 1529 | 262 | parent.children[usize::from(u8::from(parent_to_removed_child_index))] = | 1530 | 262 | child_node_index; | 1531 | | | 1532 | | // If `parent` does *not* need to be removed, we can return early. | 1533 | 262 | parent.has_storage_value || parent.children128 .iter128 ().filter128 (|c| c.is_some()).count128 () >= 2 | 1534 | | } else { | 1535 | 15.0k | debug_assert_eq!(self.trie.root_index, Some(self.node_index)); | 1536 | 15.0k | self.trie.root_index = child_node_index; | 1537 | 15.0k | true | 1538 | | }; | 1539 | | | 1540 | | // If we keep the parent in the trie, return early with a `SingleRemove`. | 1541 | 15.3k | if single_remove { | 1542 | 15.2k | return if let Some(child_node_index8.87k ) = child_node_index { | 1543 | 8.87k | Remove::SingleRemoveChild { | 1544 | 8.87k | user_data: removed_node.user_data, | 1545 | 8.87k | child: self.trie.node_by_index_inner(child_node_index).unwrap(), | 1546 | 8.87k | } | 1547 | 6.41k | } else if let Some((parent_index199 , _)) = removed_node.parent { | 1548 | 199 | Remove::SingleRemoveNoChild { | 1549 | 199 | user_data: removed_node.user_data, | 1550 | 199 | parent: self.trie.node_by_index_inner(parent_index).unwrap(), | 1551 | 199 | } | 1552 | | } else { | 1553 | 6.21k | debug_assert!(self.trie.nodes.is_empty()); | 1554 | 6.21k | debug_assert!(self.trie.root_index.is_none()); | 1555 | 6.21k | Remove::TrieNowEmpty { | 1556 | 6.21k | user_data: removed_node.user_data, | 1557 | 6.21k | } | 1558 | | }; | 1559 | 62 | } | 1560 | | | 1561 | | // If we reach here, then parent has to be removed from the trie as well. | 1562 | 62 | let parent_index = removed_node.parent.unwrap().0; | 1563 | 62 | debug_assert!(child_node_index.is_none()); | 1564 | 62 | let removed_branch = self.trie.nodes.remove(parent_index); | 1565 | 62 | debug_assert!(!removed_branch.has_storage_value); | 1566 | | | 1567 | | // We already know from above that the removed branch has exactly 1 sibling. Let's | 1568 | | // determine which. | 1569 | 62 | debug_assert_eq!( | 1570 | 62 | removed_branch | 1571 | 62 | .children | 1572 | 62 | .iter() | 1573 | 62 | .filter(|c| c.is_some()) | 1574 | 62 | .count(), | 1575 | | 1 | 1576 | | ); | 1577 | 62 | let sibling_node_index: usize = removed_branch.children.iter().find_map(|c| *c).unwrap(); | 1578 | | | 1579 | | // Update the sibling to point to the parent's parent. | 1580 | | { | 1581 | 62 | let sibling = self.trie.nodes.get_mut(sibling_node_index).unwrap(); | 1582 | 62 | debug_assert_eq!(sibling.parent.as_ref().unwrap().0, parent_index); | 1583 | 62 | insert_front( | 1584 | 62 | &mut sibling.partial_key, | 1585 | 62 | removed_branch.partial_key, | 1586 | 62 | sibling.parent.unwrap().1, | 1587 | | ); | 1588 | 62 | sibling.parent = removed_branch.parent; | 1589 | | } | 1590 | | | 1591 | | // Update the parent's parent to point to the sibling. | 1592 | 62 | if let Some((parent_parent_index59 , parent_to_sibling_index59 )) = removed_branch.parent { | 1593 | | // Update the parent's parent to point to the sibling. | 1594 | 59 | let parent_parent = self.trie.nodes.get_mut(parent_parent_index).unwrap(); | 1595 | 59 | debug_assert_eq!( | 1596 | 59 | parent_parent.children[usize::from(u8::from(parent_to_sibling_index))], | 1597 | 59 | Some(parent_index) | 1598 | | ); | 1599 | 59 | parent_parent.children[usize::from(u8::from(parent_to_sibling_index))] = | 1600 | 59 | Some(sibling_node_index); | 1601 | | } else { | 1602 | 3 | debug_assert_eq!(self.trie.root_index, Some(parent_index)); | 1603 | 3 | self.trie.root_index = Some(sibling_node_index); | 1604 | | } | 1605 | | | 1606 | | // Success! | 1607 | 62 | Remove::BranchAlsoRemoved { | 1608 | 62 | sibling: self.trie.node_by_index_inner(sibling_node_index).unwrap(), | 1609 | 62 | storage_user_data: removed_node.user_data, | 1610 | 62 | branch_user_data: removed_branch.user_data, | 1611 | 62 | } | 1612 | 85.8k | } |
_RNvMs5_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_17StorageNodeAccessuE6removeB9_ Line | Count | Source | 1482 | 49.6k | pub fn remove(self) -> Remove<'a, TUd> { | 1483 | | // If the removed node has 2 or more children, then the node continues as a branch node. | 1484 | | { | 1485 | 49.6k | let node = self.trie.nodes.get_mut(self.node_index).unwrap(); | 1486 | 49.6k | if node.children.iter().filter(|c| c.is_some()).count() >= 2 { | 1487 | 1.38k | node.has_storage_value = false; | 1488 | 1.38k | return Remove::StorageToBranch(BranchNodeAccess { | 1489 | 1.38k | trie: self.trie, | 1490 | 1.38k | node_index: self.node_index, | 1491 | 1.38k | }); | 1492 | 48.2k | } | 1493 | | } | 1494 | | | 1495 | 48.2k | let removed_node = self.trie.nodes.remove(self.node_index); | 1496 | 48.2k | debug_assert!(removed_node.has_storage_value); | 1497 | | | 1498 | | // We already know from above that the removed node has only 0 or 1 children. Let's | 1499 | | // determine which. | 1500 | 48.2k | let child_node_index: Option<usize> = removed_node.children.iter().find_map(|c| *c); | 1501 | | | 1502 | | // If relevant, update our single child's parent to point to `removed_node`'s parent. | 1503 | 48.2k | if let Some(child_node_index3.36k ) = child_node_index { | 1504 | 3.36k | let child = self.trie.nodes.get_mut(child_node_index).unwrap(); | 1505 | 3.36k | debug_assert_eq!(child.parent.as_ref().unwrap().0, self.node_index); | 1506 | 3.36k | insert_front( | 1507 | 3.36k | &mut child.partial_key, | 1508 | 3.36k | removed_node.partial_key, | 1509 | 3.36k | child.parent.unwrap().1, | 1510 | | ); | 1511 | 3.36k | child.parent = removed_node.parent; | 1512 | 44.9k | } | 1513 | | | 1514 | | // At this point, we're almost done with removing `removed_node` from `self.trie`. However | 1515 | | // there is potentially another change to make: maybe `parent` has to be removed from the | 1516 | | // trie as well. | 1517 | | | 1518 | | // Update `parent`'s child to point to `child_node_index`. | 1519 | | // `single_remove` is true if we can keep `parent` in the trie. | 1520 | 48.2k | let single_remove = if let Some((parent_index47.9k , parent_to_removed_child_index47.9k )) = | 1521 | 48.2k | removed_node.parent | 1522 | | { | 1523 | | // Update `removed_node`'s parent to point to the child. | 1524 | 47.9k | let parent = self.trie.nodes.get_mut(parent_index).unwrap(); | 1525 | 47.9k | debug_assert_eq!( | 1526 | 47.9k | parent.children[usize::from(u8::from(parent_to_removed_child_index))], | 1527 | 47.9k | Some(self.node_index) | 1528 | | ); | 1529 | 47.9k | parent.children[usize::from(u8::from(parent_to_removed_child_index))] = | 1530 | 47.9k | child_node_index; | 1531 | | | 1532 | | // If `parent` does *not* need to be removed, we can return early. | 1533 | 47.9k | parent.has_storage_value || parent.children23.4k .iter23.4k ().filter23.4k (|c| c.is_some()).count23.4k () >= 2 | 1534 | | } else { | 1535 | 396 | debug_assert_eq!(self.trie.root_index, Some(self.node_index)); | 1536 | 396 | self.trie.root_index = child_node_index; | 1537 | 396 | true | 1538 | | }; | 1539 | | | 1540 | | // If we keep the parent in the trie, return early with a `SingleRemove`. | 1541 | 48.2k | if single_remove { | 1542 | 37.6k | return if let Some(child_node_index3.36k ) = child_node_index { | 1543 | 3.36k | Remove::SingleRemoveChild { | 1544 | 3.36k | user_data: removed_node.user_data, | 1545 | 3.36k | child: self.trie.node_by_index_inner(child_node_index).unwrap(), | 1546 | 3.36k | } | 1547 | 34.2k | } else if let Some((parent_index33.8k , _)) = removed_node.parent { | 1548 | 33.8k | Remove::SingleRemoveNoChild { | 1549 | 33.8k | user_data: removed_node.user_data, | 1550 | 33.8k | parent: self.trie.node_by_index_inner(parent_index).unwrap(), | 1551 | 33.8k | } | 1552 | | } else { | 1553 | 366 | debug_assert!(self.trie.nodes.is_empty()); | 1554 | 366 | debug_assert!(self.trie.root_index.is_none()); | 1555 | 366 | Remove::TrieNowEmpty { | 1556 | 366 | user_data: removed_node.user_data, | 1557 | 366 | } | 1558 | | }; | 1559 | 10.6k | } | 1560 | | | 1561 | | // If we reach here, then parent has to be removed from the trie as well. | 1562 | 10.6k | let parent_index = removed_node.parent.unwrap().0; | 1563 | 10.6k | debug_assert!(child_node_index.is_none()); | 1564 | 10.6k | let removed_branch = self.trie.nodes.remove(parent_index); | 1565 | 10.6k | debug_assert!(!removed_branch.has_storage_value); | 1566 | | | 1567 | | // We already know from above that the removed branch has exactly 1 sibling. Let's | 1568 | | // determine which. | 1569 | 10.6k | debug_assert_eq!( | 1570 | 10.6k | removed_branch | 1571 | 10.6k | .children | 1572 | 10.6k | .iter() | 1573 | 10.6k | .filter(|c| c.is_some()) | 1574 | 10.6k | .count(), | 1575 | | 1 | 1576 | | ); | 1577 | 10.6k | let sibling_node_index: usize = removed_branch.children.iter().find_map(|c| *c).unwrap(); | 1578 | | | 1579 | | // Update the sibling to point to the parent's parent. | 1580 | | { | 1581 | 10.6k | let sibling = self.trie.nodes.get_mut(sibling_node_index).unwrap(); | 1582 | 10.6k | debug_assert_eq!(sibling.parent.as_ref().unwrap().0, parent_index); | 1583 | 10.6k | insert_front( | 1584 | 10.6k | &mut sibling.partial_key, | 1585 | 10.6k | removed_branch.partial_key, | 1586 | 10.6k | sibling.parent.unwrap().1, | 1587 | | ); | 1588 | 10.6k | sibling.parent = removed_branch.parent; | 1589 | | } | 1590 | | | 1591 | | // Update the parent's parent to point to the sibling. | 1592 | 10.6k | if let Some((parent_parent_index9.91k , parent_to_sibling_index9.91k )) = removed_branch.parent { | 1593 | | // Update the parent's parent to point to the sibling. | 1594 | 9.91k | let parent_parent = self.trie.nodes.get_mut(parent_parent_index).unwrap(); | 1595 | 9.91k | debug_assert_eq!( | 1596 | 9.91k | parent_parent.children[usize::from(u8::from(parent_to_sibling_index))], | 1597 | 9.91k | Some(parent_index) | 1598 | | ); | 1599 | 9.91k | parent_parent.children[usize::from(u8::from(parent_to_sibling_index))] = | 1600 | 9.91k | Some(sibling_node_index); | 1601 | | } else { | 1602 | 774 | debug_assert_eq!(self.trie.root_index, Some(parent_index)); | 1603 | 774 | self.trie.root_index = Some(sibling_node_index); | 1604 | | } | 1605 | | | 1606 | | // Success! | 1607 | 10.6k | Remove::BranchAlsoRemoved { | 1608 | 10.6k | sibling: self.trie.node_by_index_inner(sibling_node_index).unwrap(), | 1609 | 10.6k | storage_user_data: removed_node.user_data, | 1610 | 10.6k | branch_user_data: removed_branch.user_data, | 1611 | 10.6k | } | 1612 | 49.6k | } |
Unexecuted instantiation: _RNvMs5_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_17StorageNodeAccesspE6removeB9_ |
1613 | | } |
1614 | | |
1615 | | /// Outcome of the removal of a storage value. |
1616 | | pub enum Remove<'a, TUd> { |
1617 | | /// Removing the storage value didn't change the structure of the trie. Contains a |
1618 | | /// [`BranchNodeAccess`] representing the same node as the [`StorageNodeAccess`] whose value |
1619 | | /// got removed. |
1620 | | StorageToBranch(BranchNodeAccess<'a, TUd>), |
1621 | | |
1622 | | /// Removing the storage value removed the node that contained the storage value. Apart from |
1623 | | /// this removal, the structure of the trie didn't change. |
1624 | | /// |
1625 | | /// The node that got removed had one single child. This child's parent becomes the parent |
1626 | | /// that the former node had. |
1627 | | /// |
1628 | | /// ```text |
1629 | | /// |
1630 | | /// |
1631 | | /// +-+ +-+ |
1632 | | /// +--> +-+ <--+ +--------> +-+ <--+ |
1633 | | /// | | | | |
1634 | | /// | + | + |
1635 | | /// | (0 or more other children) | (0 or more other children) |
1636 | | /// | | |
1637 | | /// +-+ | |
1638 | | /// +--> +-+ removed node | |
1639 | | /// | | |
1640 | | /// | | |
1641 | | /// | | |
1642 | | /// | | |
1643 | | /// +-+ +-+ |
1644 | | /// +-+ +-+ `child` |
1645 | | /// ^ ^ |
1646 | | /// ++ (0 or more other children) ++ (0 or more other children) |
1647 | | /// |
1648 | | /// ``` |
1649 | | /// |
1650 | | SingleRemoveChild { |
1651 | | /// Unique child that the removed node had. The parent and partial key of this child has |
1652 | | /// been modified. |
1653 | | child: NodeAccess<'a, TUd>, |
1654 | | |
1655 | | /// User data that was in the removed node. |
1656 | | user_data: TUd, |
1657 | | }, |
1658 | | |
1659 | | /// Removing the storage value removed the node that contained the storage value. Apart from |
1660 | | /// this removal, the structure of the trie didn't change. |
1661 | | /// |
1662 | | /// The node that got removed didn't have any children. |
1663 | | /// |
1664 | | /// ```text |
1665 | | /// |
1666 | | /// Before After |
1667 | | /// |
1668 | | /// `parent` |
1669 | | /// +-+ +-+ |
1670 | | /// +--> +-+ <--+ +-+ <--+ |
1671 | | /// | | | |
1672 | | /// | + + |
1673 | | /// | (0 or more other children) (0 or more other children) |
1674 | | /// | |
1675 | | /// +-+ |
1676 | | /// +-+ removed node |
1677 | | /// |
1678 | | /// ``` |
1679 | | /// |
1680 | | SingleRemoveNoChild { |
1681 | | /// Parent that the removed node had. |
1682 | | parent: NodeAccess<'a, TUd>, |
1683 | | |
1684 | | /// User data that was in the removed node. |
1685 | | user_data: TUd, |
1686 | | }, |
1687 | | |
1688 | | /// The trie was empty apart from this node. It is now completely empty. |
1689 | | TrieNowEmpty { |
1690 | | /// User data that was in the removed node. |
1691 | | user_data: TUd, |
1692 | | }, |
1693 | | |
1694 | | /// Removing the storage value removed two nodes from the trie: the one that contained the |
1695 | | /// storage value and its parent, which was a branch node. |
1696 | | /// |
1697 | | /// This can only happen if the removed node had no children and only one sibling. |
1698 | | /// |
1699 | | /// ```text |
1700 | | /// |
1701 | | /// Before After |
1702 | | /// |
1703 | | /// |
1704 | | /// + + |
1705 | | /// | | |
1706 | | /// +-+ | |
1707 | | /// +--> +-+ <--+ +-----+ |
1708 | | /// | | | |
1709 | | /// | | | |
1710 | | /// +-+ +-+ +-+ |
1711 | | /// +-+ +-+ +-+ `sibling` |
1712 | | /// ^ ^ |
1713 | | /// removed node | | |
1714 | | /// + + |
1715 | | /// (0 or more other nodes) (0 or more other nodes) |
1716 | | /// |
1717 | | /// ``` |
1718 | | /// |
1719 | | BranchAlsoRemoved { |
1720 | | /// Sibling of the removed node. The parent and partial key of this sibling have been |
1721 | | /// modified. |
1722 | | sibling: NodeAccess<'a, TUd>, |
1723 | | |
1724 | | /// User data that was in the removed storage node. |
1725 | | storage_user_data: TUd, |
1726 | | |
1727 | | /// User data that was in the removed branch node (former parent of `storage_user_data`). |
1728 | | branch_user_data: TUd, |
1729 | | }, |
1730 | | } |
1731 | | |
1732 | | /// Access to a node within the [`TrieStructure`] that is known to not have any storage value |
1733 | | /// associated to it. |
1734 | | pub struct BranchNodeAccess<'a, TUd> { |
1735 | | trie: &'a mut TrieStructure<TUd>, |
1736 | | node_index: usize, |
1737 | | } |
1738 | | |
1739 | | impl<'a, TUd> BranchNodeAccess<'a, TUd> { |
1740 | | /// Returns an opaque [`NodeIndex`] representing the node in the trie. |
1741 | | /// |
1742 | | /// It can later be used to retrieve this same node using [`TrieStructure::node_by_index`]. |
1743 | 0 | pub fn node_index(&self) -> NodeIndex { |
1744 | 0 | NodeIndex(self.node_index) |
1745 | 0 | } Unexecuted instantiation: _RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE10node_indexB9_ Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE10node_indexB9_ |
1746 | | |
1747 | | /// Returns the parent of this node, or `None` if this is the root node. |
1748 | 0 | pub fn into_parent(self) -> Option<NodeAccess<'a, TUd>> { |
1749 | 0 | let parent_idx = self.trie.nodes.get(self.node_index).unwrap().parent?.0; |
1750 | 0 | Some(self.trie.node_by_index_inner(parent_idx).unwrap()) |
1751 | 0 | } Unexecuted instantiation: _RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE11into_parentB9_ Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE11into_parentB9_ |
1752 | | |
1753 | | /// Returns the parent of this node, or `None` if this is the root node. |
1754 | 0 | pub fn parent(&'_ mut self) -> Option<NodeAccess<'_, TUd>> { |
1755 | 0 | let parent_idx = self.trie.nodes.get(self.node_index).unwrap().parent?.0; |
1756 | 0 | Some(self.trie.node_by_index_inner(parent_idx).unwrap()) |
1757 | 0 | } Unexecuted instantiation: _RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccesspE6parentB9_ Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccesspE6parentB9_ |
1758 | | |
1759 | | /// Returns the first child of this node. |
1760 | | /// |
1761 | | /// Returns back `self` if this node doesn't have any children. |
1762 | 0 | pub fn into_first_child(self) -> Result<NodeAccess<'a, TUd>, Self> { |
1763 | 0 | let first_child_idx = self |
1764 | 0 | .trie |
1765 | 0 | .nodes |
1766 | 0 | .get(self.node_index) |
1767 | 0 | .unwrap() |
1768 | 0 | .children |
1769 | 0 | .iter() |
1770 | 0 | .find_map(|c| *c); |
1771 | | |
1772 | 0 | let first_child_idx = match first_child_idx { |
1773 | 0 | Some(fc) => fc, |
1774 | 0 | None => return Err(self), |
1775 | | }; |
1776 | | |
1777 | 0 | Ok(self.trie.node_by_index_inner(first_child_idx).unwrap()) |
1778 | 0 | } Unexecuted instantiation: _RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE16into_first_childB9_ Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE16into_first_childB9_ |
1779 | | |
1780 | | /// Returns the next sibling of this node. |
1781 | | /// |
1782 | | /// Returns back `self` if this node is the last child of its parent. |
1783 | 0 | pub fn into_next_sibling(self) -> Result<NodeAccess<'a, TUd>, Self> { |
1784 | 0 | let next_sibling_idx = match self.trie.next_sibling(self.node_index) { |
1785 | 0 | Some(ns) => ns, |
1786 | 0 | None => return Err(self), |
1787 | | }; |
1788 | | |
1789 | 0 | Ok(self.trie.node_by_index_inner(next_sibling_idx).unwrap()) |
1790 | 0 | } Unexecuted instantiation: _RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE17into_next_siblingB9_ Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE17into_next_siblingB9_ |
1791 | | |
1792 | | /// Returns the child of this node at the given index. |
1793 | 1.12M | pub fn child(&'_ mut self, index: Nibble) -> Option<NodeAccess<'_, TUd>> { |
1794 | 204k | let child_idx = |
1795 | 1.12M | self.trie.nodes.get(self.node_index).unwrap().children[usize::from(u8::from(index))]?922k ; |
1796 | 204k | Some(self.trie.node_by_index_inner(child_idx).unwrap()) |
1797 | 1.12M | } _RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE5childB9_ Line | Count | Source | 1793 | 1.76k | pub fn child(&'_ mut self, index: Nibble) -> Option<NodeAccess<'_, TUd>> { | 1794 | 222 | let child_idx = | 1795 | 1.76k | self.trie.nodes.get(self.node_index).unwrap().children[usize::from(u8::from(index))]?1.53k ; | 1796 | 222 | Some(self.trie.node_by_index_inner(child_idx).unwrap()) | 1797 | 1.76k | } |
_RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE5childB9_ Line | Count | Source | 1793 | 1.11M | pub fn child(&'_ mut self, index: Nibble) -> Option<NodeAccess<'_, TUd>> { | 1794 | 202k | let child_idx = | 1795 | 1.11M | self.trie.nodes.get(self.node_index).unwrap().children[usize::from(u8::from(index))]?914k ; | 1796 | 202k | Some(self.trie.node_by_index_inner(child_idx).unwrap()) | 1797 | 1.11M | } |
Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE5childCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccesspE5childB9_ _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE5childCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1793 | 832 | pub fn child(&'_ mut self, index: Nibble) -> Option<NodeAccess<'_, TUd>> { | 1794 | 188 | let child_idx = | 1795 | 832 | self.trie.nodes.get(self.node_index).unwrap().children[usize::from(u8::from(index))]?644 ; | 1796 | 188 | Some(self.trie.node_by_index_inner(child_idx).unwrap()) | 1797 | 832 | } |
_RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE5childCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1793 | 7.90k | pub fn child(&'_ mut self, index: Nibble) -> Option<NodeAccess<'_, TUd>> { | 1794 | 1.78k | let child_idx = | 1795 | 7.90k | self.trie.nodes.get(self.node_index).unwrap().children[usize::from(u8::from(index))]?6.11k ; | 1796 | 1.78k | Some(self.trie.node_by_index_inner(child_idx).unwrap()) | 1797 | 7.90k | } |
|
1798 | | |
1799 | | /// Returns the user data of the child at the given index. |
1800 | | /// |
1801 | | /// > **Note**: This method exists because it accepts `&self` rather than `&mut self`. A |
1802 | | /// > cleaner alternative would be to split the [`NodeAccess`] struct into |
1803 | | /// > `NodeAccessRef` and `NodeAccessMut`, but that's a lot of efforts compare to |
1804 | | /// > this single method. |
1805 | 92.4k | pub fn child_user_data(&self, index: Nibble) -> Option<&TUd> { |
1806 | 15.8k | let child_idx = |
1807 | 92.4k | self.trie.nodes.get(self.node_index).unwrap().children[usize::from(u8::from(index))]?76.5k ; |
1808 | 15.8k | Some(&self.trie.nodes.get(child_idx).unwrap().user_data) |
1809 | 92.4k | } Unexecuted instantiation: _RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE15child_user_dataB9_ _RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessuE15child_user_dataB9_ Line | Count | Source | 1805 | 92.4k | pub fn child_user_data(&self, index: Nibble) -> Option<&TUd> { | 1806 | 15.8k | let child_idx = | 1807 | 92.4k | self.trie.nodes.get(self.node_index).unwrap().children[usize::from(u8::from(index))]?76.5k ; | 1808 | 15.8k | Some(&self.trie.nodes.get(child_idx).unwrap().user_data) | 1809 | 92.4k | } |
Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE15child_user_dataB9_ |
1810 | | |
1811 | | /// Returns the child of this node given the given index. |
1812 | | /// |
1813 | | /// Returns back `self` if there is no such child at this index. |
1814 | 0 | pub fn into_child(self, index: Nibble) -> Result<NodeAccess<'a, TUd>, Self> { |
1815 | 0 | let child_idx = match self.trie.nodes.get(self.node_index).unwrap().children |
1816 | 0 | [usize::from(u8::from(index))] |
1817 | | { |
1818 | 0 | Some(c) => c, |
1819 | 0 | None => return Err(self), |
1820 | | }; |
1821 | | |
1822 | 0 | Ok(self.trie.node_by_index_inner(child_idx).unwrap()) |
1823 | 0 | } Unexecuted instantiation: _RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccesspE10into_childB9_ Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccesspE10into_childB9_ |
1824 | | |
1825 | | /// Returns true if this node is the root node of the trie. |
1826 | 70.1k | pub fn is_root_node(&self) -> bool { |
1827 | 70.1k | self.trie.root_index == Some(self.node_index) |
1828 | 70.1k | } _RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE12is_root_nodeB9_ Line | Count | Source | 1826 | 55 | pub fn is_root_node(&self) -> bool { | 1827 | 55 | self.trie.root_index == Some(self.node_index) | 1828 | 55 | } |
_RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE12is_root_nodeB9_ Line | Count | Source | 1826 | 69.7k | pub fn is_root_node(&self) -> bool { | 1827 | 69.7k | self.trie.root_index == Some(self.node_index) | 1828 | 69.7k | } |
Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE12is_root_nodeCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccesspE12is_root_nodeB9_ _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE12is_root_nodeCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1826 | 26 | pub fn is_root_node(&self) -> bool { | 1827 | 26 | self.trie.root_index == Some(self.node_index) | 1828 | 26 | } |
_RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE12is_root_nodeCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1826 | 247 | pub fn is_root_node(&self) -> bool { | 1827 | 247 | self.trie.root_index == Some(self.node_index) | 1828 | 247 | } |
|
1829 | | |
1830 | | /// Returns the full key of the node. |
1831 | 0 | pub fn full_key(&self) -> impl Iterator<Item = Nibble> { |
1832 | 0 | self.trie.node_full_key(self.node_index) |
1833 | 0 | } Unexecuted instantiation: _RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccesspE8full_keyB9_ Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccesspE8full_keyB9_ |
1834 | | |
1835 | | /// Returns the partial key of the node. |
1836 | 76.2k | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { |
1837 | 76.2k | self.trie |
1838 | 76.2k | .nodes |
1839 | 76.2k | .get(self.node_index) |
1840 | 76.2k | .unwrap() |
1841 | 76.2k | .partial_key |
1842 | 76.2k | .iter() |
1843 | 76.2k | .copied() |
1844 | 76.2k | } _RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE11partial_keyB9_ Line | Count | Source | 1836 | 110 | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { | 1837 | 110 | self.trie | 1838 | 110 | .nodes | 1839 | 110 | .get(self.node_index) | 1840 | 110 | .unwrap() | 1841 | 110 | .partial_key | 1842 | 110 | .iter() | 1843 | 110 | .copied() | 1844 | 110 | } |
_RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE11partial_keyB9_ Line | Count | Source | 1836 | 69.7k | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { | 1837 | 69.7k | self.trie | 1838 | 69.7k | .nodes | 1839 | 69.7k | .get(self.node_index) | 1840 | 69.7k | .unwrap() | 1841 | 69.7k | .partial_key | 1842 | 69.7k | .iter() | 1843 | 69.7k | .copied() | 1844 | 69.7k | } |
_RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessuE11partial_keyB9_ Line | Count | Source | 1836 | 5.77k | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { | 1837 | 5.77k | self.trie | 1838 | 5.77k | .nodes | 1839 | 5.77k | .get(self.node_index) | 1840 | 5.77k | .unwrap() | 1841 | 5.77k | .partial_key | 1842 | 5.77k | .iter() | 1843 | 5.77k | .copied() | 1844 | 5.77k | } |
Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE11partial_keyCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccesspE11partial_keyB9_ _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE11partial_keyCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1836 | 52 | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { | 1837 | 52 | self.trie | 1838 | 52 | .nodes | 1839 | 52 | .get(self.node_index) | 1840 | 52 | .unwrap() | 1841 | 52 | .partial_key | 1842 | 52 | .iter() | 1843 | 52 | .copied() | 1844 | 52 | } |
_RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE11partial_keyCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1836 | 494 | pub fn partial_key(&self) -> impl ExactSizeIterator<Item = Nibble> + Clone { | 1837 | 494 | self.trie | 1838 | 494 | .nodes | 1839 | 494 | .get(self.node_index) | 1840 | 494 | .unwrap() | 1841 | 494 | .partial_key | 1842 | 494 | .iter() | 1843 | 494 | .copied() | 1844 | 494 | } |
|
1845 | | |
1846 | | /// Adds a storage value to this node, turning it into a [`StorageNodeAccess`]. |
1847 | | /// |
1848 | | /// The trie structure doesn't change. |
1849 | 165k | pub fn insert_storage_value(self) -> StorageNodeAccess<'a, TUd> { |
1850 | 165k | let node = self.trie.nodes.get_mut(self.node_index).unwrap(); |
1851 | 165k | debug_assert!(!node.has_storage_value); |
1852 | 165k | node.has_storage_value = true; |
1853 | | |
1854 | 165k | StorageNodeAccess { |
1855 | 165k | trie: self.trie, |
1856 | 165k | node_index: self.node_index, |
1857 | 165k | } |
1858 | 165k | } Unexecuted instantiation: _RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE20insert_storage_valueB9_ _RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE20insert_storage_valueB9_ Line | Count | Source | 1849 | 66.6k | pub fn insert_storage_value(self) -> StorageNodeAccess<'a, TUd> { | 1850 | 66.6k | let node = self.trie.nodes.get_mut(self.node_index).unwrap(); | 1851 | 66.6k | debug_assert!(!node.has_storage_value); | 1852 | 66.6k | node.has_storage_value = true; | 1853 | | | 1854 | 66.6k | StorageNodeAccess { | 1855 | 66.6k | trie: self.trie, | 1856 | 66.6k | node_index: self.node_index, | 1857 | 66.6k | } | 1858 | 66.6k | } |
_RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessuE20insert_storage_valueB9_ Line | Count | Source | 1849 | 98.5k | pub fn insert_storage_value(self) -> StorageNodeAccess<'a, TUd> { | 1850 | 98.5k | let node = self.trie.nodes.get_mut(self.node_index).unwrap(); | 1851 | 98.5k | debug_assert!(!node.has_storage_value); | 1852 | 98.5k | node.has_storage_value = true; | 1853 | | | 1854 | 98.5k | StorageNodeAccess { | 1855 | 98.5k | trie: self.trie, | 1856 | 98.5k | node_index: self.node_index, | 1857 | 98.5k | } | 1858 | 98.5k | } |
Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE20insert_storage_valueCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccesspE20insert_storage_valueB9_ Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE20insert_storage_valueCs2XuF9XSsPgw_14json_rpc_basic Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE20insert_storage_valueCs8se6o44HBaX_25json_rpc_general_requests |
1859 | | |
1860 | | /// Returns the user data associated to this node. |
1861 | 70.7k | pub fn into_user_data(self) -> &'a mut TUd { |
1862 | 70.7k | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data |
1863 | 70.7k | } _RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE14into_user_dataB9_ Line | Count | Source | 1861 | 55 | pub fn into_user_data(self) -> &'a mut TUd { | 1862 | 55 | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data | 1863 | 55 | } |
_RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE14into_user_dataB9_ Line | Count | Source | 1861 | 70.4k | pub fn into_user_data(self) -> &'a mut TUd { | 1862 | 70.4k | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data | 1863 | 70.4k | } |
Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE14into_user_dataCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccesspE14into_user_dataB9_ _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE14into_user_dataCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1861 | 26 | pub fn into_user_data(self) -> &'a mut TUd { | 1862 | 26 | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data | 1863 | 26 | } |
_RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE14into_user_dataCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1861 | 247 | pub fn into_user_data(self) -> &'a mut TUd { | 1862 | 247 | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data | 1863 | 247 | } |
|
1864 | | |
1865 | | /// Returns the user data associated to this node. |
1866 | 266k | pub fn user_data(&mut self) -> &mut TUd { |
1867 | 266k | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data |
1868 | 266k | } Unexecuted instantiation: _RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE9user_dataB9_ _RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE9user_dataB9_ Line | Count | Source | 1866 | 165 | pub fn user_data(&mut self) -> &mut TUd { | 1867 | 165 | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data | 1868 | 165 | } |
_RNvMs6_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE9user_dataB9_ Line | Count | Source | 1866 | 265k | pub fn user_data(&mut self) -> &mut TUd { | 1867 | 265k | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data | 1868 | 265k | } |
Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE9user_dataCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE9user_dataB9_ _RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE9user_dataCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1866 | 100 | pub fn user_data(&mut self) -> &mut TUd { | 1867 | 100 | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data | 1868 | 100 | } |
_RNvMs6_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16BranchNodeAccessTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE9user_dataCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1866 | 950 | pub fn user_data(&mut self) -> &mut TUd { | 1867 | 950 | &mut self.trie.nodes.get_mut(self.node_index).unwrap().user_data | 1868 | 950 | } |
|
1869 | | } |
1870 | | |
1871 | | /// Access to a non-existing node within the [`TrieStructure`]. |
1872 | | pub struct Vacant<'a, TUd, TKIter> { |
1873 | | trie: &'a mut TrieStructure<TUd>, |
1874 | | /// Full key of the node to insert. |
1875 | | key: TKIter, |
1876 | | /// Known closest ancestor that is in `trie`. Will become the parent of any newly-inserted |
1877 | | /// node. |
1878 | | closest_ancestor: Option<usize>, |
1879 | | } |
1880 | | |
1881 | | impl<'a, TUd, TKIter> Vacant<'a, TUd, TKIter> |
1882 | | where |
1883 | | TKIter: Iterator<Item = Nibble> + Clone, |
1884 | | { |
1885 | | /// Prepare the operation of creating the node in question. |
1886 | | /// |
1887 | | /// This method analyzes the trie to prepare for the operation, but doesn't actually perform |
1888 | | /// any insertion. To perform the insertion, use the returned [`PrepareInsert`]. |
1889 | 1.35M | pub fn insert_storage_value(mut self) -> PrepareInsert<'a, TUd> { |
1890 | | // Retrieve what will be the parent after we insert the new node, not taking branching |
1891 | | // into account yet. |
1892 | | // If `Some`, contains its index and number of nibbles in its key. |
1893 | 1.35M | let future_parent1.30M = match (self.closest_ancestor, self.trie.root_index) { |
1894 | 0 | (Some(_), None) => unreachable!(), |
1895 | 1.27M | (Some(ancestor), Some(_)) => { |
1896 | | // TODO: could be optimized by passing in the Vacant the key remainder |
1897 | 1.27M | let key_len = self.trie.node_full_key(ancestor).count(); |
1898 | 1.27M | debug_assert!(self.key.clone().count() > key_len); |
1899 | 1.27M | Some((ancestor, key_len)) |
1900 | | } |
1901 | 24.0k | (None, Some(_)) => None, |
1902 | | (None, None) => { |
1903 | | // Situation where the trie is empty. This is kind of a special case that we |
1904 | | // handle by returning early. |
1905 | 53.8k | return PrepareInsert::One(PrepareInsertOne { |
1906 | 53.8k | trie: self.trie, |
1907 | 53.8k | parent: None, |
1908 | 53.8k | partial_key: self.key.collect(), |
1909 | 53.8k | children: [None; 16], |
1910 | 53.8k | }); |
1911 | | } |
1912 | | }; |
1913 | | |
1914 | | // Get the existing child of `future_parent` that points towards the newly-inserted node, |
1915 | | // or a successful early-return if none. |
1916 | 341k | let existing_node_index = |
1917 | 1.30M | if let Some((future_parent_index1.27M , future_parent_key_len1.27M )) = future_parent { |
1918 | 1.27M | let new_child_index = self.key.clone().nth(future_parent_key_len).unwrap(); |
1919 | 1.27M | let future_parent = self.trie.nodes.get(future_parent_index).unwrap(); |
1920 | 1.27M | match future_parent.children[usize::from(u8::from(new_child_index))] { |
1921 | 317k | Some(i) => { |
1922 | 317k | debug_assert_eq!( |
1923 | 317k | self.trie.nodes.get(i).unwrap().parent.unwrap().0, |
1924 | | future_parent_index |
1925 | | ); |
1926 | 317k | i |
1927 | | } |
1928 | | None => { |
1929 | | // There is an empty slot in `future_parent` for our new node. |
1930 | | // |
1931 | | // |
1932 | | // `future_parent` |
1933 | | // +-+ |
1934 | | // +-> +-+ <---------+ |
1935 | | // | <----+ | |
1936 | | // | ^ | | |
1937 | | // +-+ | | | |
1938 | | // New node +-+ +-+-+ +-+ +-+ 0 or more existing children |
1939 | | // +-+ +-+ +-+ |
1940 | | // |
1941 | | // |
1942 | 960k | return PrepareInsert::One(PrepareInsertOne { |
1943 | 960k | trie: self.trie, |
1944 | 960k | parent: Some((future_parent_index, new_child_index)), |
1945 | 960k | partial_key: self.key.skip(future_parent_key_len + 1).collect(), |
1946 | 960k | children: [None; 16], |
1947 | 960k | }); |
1948 | | } |
1949 | | } |
1950 | | } else { |
1951 | 24.0k | self.trie.root_index.unwrap() |
1952 | | }; |
1953 | | |
1954 | | // `existing_node_idx` and the new node are known to either have the same parent and the |
1955 | | // same child index, or to both have no parent. Now let's compare their partial key. |
1956 | 341k | let existing_node_partial_key = &self |
1957 | 341k | .trie |
1958 | 341k | .nodes |
1959 | 341k | .get(existing_node_index) |
1960 | 341k | .unwrap() |
1961 | 341k | .partial_key; |
1962 | 341k | let new_node_partial_key = self |
1963 | 341k | .key |
1964 | 341k | .clone() |
1965 | 341k | .skip(future_parent.map_or(0, |(_, n)| n317k + 1)) _RNCNvMs7_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_6VacantINtNtCs66KPHxksi63_4core6option6OptionNtNtB9_12proof_encode4NodeEINtNtNtNtB1a_4iter8adapters6copied6CopiedINtNtNtB1a_5slice4iter4IterNtNtB9_6nibble6NibbleEEE20insert_storage_value0Bb_ Line | Count | Source | 1965 | 5.39k | .skip(future_parent.map_or(0, |(_, n)| n + 1)) |
_RNCNvMs7_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_6VacantTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB17_NtNtB9_9trie_node17MerkleValueOutputEEINtNtB9_6nibble14BytesToNibblesINtNtNtNtB1b_4iter8adapters6copied6CopiedINtNtNtB1b_5slice4iter4IterhEEEE20insert_storage_value0Bb_ Line | Count | Source | 1965 | 56 | .skip(future_parent.map_or(0, |(_, n)| n + 1)) |
_RNCNvMs7_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_6VacantTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB9_16TrieEntryVersionEEIB17_NtNtB9_9trie_node17MerkleValueOutputEEINtNtB9_6nibble14BytesToNibblesINtNtNtNtB1b_4iter8adapters6copied6CopiedINtNtNtB1b_5slice4iter4IterhEEEE20insert_storage_value0Bb_ Line | Count | Source | 1965 | 57.6k | .skip(future_parent.map_or(0, |(_, n)| n + 1)) |
_RNCNvMs7_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_6VacantuINtNtB9_6nibble14BytesToNibblesINtNtNtNtCs66KPHxksi63_4core4iter8adapters6copied6CopiedINtNtNtB1K_5slice4iter4IterhEEEE20insert_storage_value0Bb_ Line | Count | Source | 1965 | 148 | .skip(future_parent.map_or(0, |(_, n)| n + 1)) |
_RNCNvMs7_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_6VacantuINtNtNtCs8Ty2CzGA6U3_5alloc3vec9into_iter8IntoIterNtNtB9_6nibble6NibbleEE20insert_storage_value0Bb_ Line | Count | Source | 1965 | 241k | .skip(future_parent.map_or(0, |(_, n)| n + 1)) |
_RNCNvMs7_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_6VacantuINtNtNtNtCs66KPHxksi63_4core4iter8adapters6cloned6ClonedINtNtNtB1f_5slice4iter4IterNtNtB9_6nibble6NibbleEEE20insert_storage_value0Bb_ Line | Count | Source | 1965 | 4 | .skip(future_parent.map_or(0, |(_, n)| n + 1)) |
_RNCNvMs7_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_6VacantuINtNtNtNtCs66KPHxksi63_4core4iter8adapters6copied6CopiedINtNtNtB1f_5slice4iter4IterNtNtB9_6nibble6NibbleEEE20insert_storage_value0Bb_ Line | Count | Source | 1965 | 12.9k | .skip(future_parent.map_or(0, |(_, n)| n + 1)) |
Unexecuted instantiation: _RNCNvMs7_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB7_6VacantTINtNtCs66KPHxksi63_4core6option6OptionRShEIB17_NtNtB9_9trie_node17MerkleValueOutputEEINtNtB9_6nibble14BytesToNibblesINtNtNtNtB1b_4iter8adapters6copied6CopiedINtNtNtB1b_5slice4iter4IterhEEEE20insert_storage_value0Cs4ISLcsFEGeP_6author Unexecuted instantiation: _RNCNvMs7_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB7_6VacantINtNtCs66KPHxksi63_4core6option6OptionNtNtB9_12proof_encode4NodeEINtNtNtNtB1a_4iter8adapters6copied6CopiedINtNtNtB1a_5slice4iter4IterNtNtB9_6nibble6NibbleEEE20insert_storage_value0Bb_ _RNCNvMs7_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB7_6VacantTINtNtCs66KPHxksi63_4core6option6OptionRShEIB17_NtNtB9_9trie_node17MerkleValueOutputEEINtNtB9_6nibble14BytesToNibblesINtNtNtNtB1b_4iter8adapters6copied6CopiedINtNtNtB1b_5slice4iter4IterhEEEE20insert_storage_value0Cs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1965 | 24 | .skip(future_parent.map_or(0, |(_, n)| n + 1)) |
_RNCNvMs7_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB7_6VacantTINtNtCs66KPHxksi63_4core6option6OptionRShEIB17_NtNtB9_9trie_node17MerkleValueOutputEEINtNtB9_6nibble14BytesToNibblesINtNtNtNtB1b_4iter8adapters6copied6CopiedINtNtNtB1b_5slice4iter4IterhEEEE20insert_storage_value0Cs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1965 | 228 | .skip(future_parent.map_or(0, |(_, n)| n + 1)) |
|
1966 | 341k | .collect::<Vec<_>>(); |
1967 | 341k | debug_assert_ne!(*existing_node_partial_key, new_node_partial_key); |
1968 | 341k | debug_assert!(!new_node_partial_key.starts_with(existing_node_partial_key)); |
1969 | | |
1970 | | // If `existing_node_partial_key` starts with `new_node_partial_key`, then the new node |
1971 | | // will be inserted in-between the parent and the existing node. |
1972 | 341k | if existing_node_partial_key.starts_with(&new_node_partial_key) { |
1973 | | // The new node is to be inserted in-between `future_parent` and |
1974 | | // `existing_node_index`. |
1975 | | // |
1976 | | // If `future_parent` is `Some`: |
1977 | | // |
1978 | | // |
1979 | | // +-+ |
1980 | | // `future_parent` +-+ <---------+ |
1981 | | // ^ | |
1982 | | // | + |
1983 | | // +-+ (0 or more existing children) |
1984 | | // New node +-+ |
1985 | | // ^ |
1986 | | // | |
1987 | | // +-+ |
1988 | | // `existing_node_index` +-+ |
1989 | | // ^ |
1990 | | // | |
1991 | | // + |
1992 | | // (0 or more existing children) |
1993 | | // |
1994 | | // |
1995 | | // |
1996 | | // If `future_parent` is `None`: |
1997 | | // |
1998 | | // |
1999 | | // New node +-+ |
2000 | | // (becomes the root) +-+ |
2001 | | // ^ |
2002 | | // | |
2003 | | // `existing_node_index` +-+ |
2004 | | // (current root) +-+ |
2005 | | // ^ |
2006 | | // | |
2007 | | // + |
2008 | | // (0 or more existing children) |
2009 | | // |
2010 | | |
2011 | 100k | let mut new_node_children = [None; 16]; |
2012 | 100k | let existing_node_new_child_index = |
2013 | 100k | existing_node_partial_key[new_node_partial_key.len()]; |
2014 | 100k | new_node_children[usize::from(u8::from(existing_node_new_child_index))] = |
2015 | 100k | Some(existing_node_index); |
2016 | | |
2017 | | return PrepareInsert::One(PrepareInsertOne { |
2018 | 100k | trie: self.trie, |
2019 | 100k | parent: if let Some((future_parent_index92.3k , future_parent_key_len92.3k )) = future_parent { |
2020 | 92.3k | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); |
2021 | 92.3k | Some((future_parent_index, new_child_index)) |
2022 | | } else { |
2023 | 7.99k | None |
2024 | | }, |
2025 | 100k | partial_key: new_node_partial_key, |
2026 | 100k | children: new_node_children, |
2027 | | }); |
2028 | 241k | } |
2029 | | |
2030 | | // If we reach here, we know that we will need to create a new branch node in addition to |
2031 | | // the new storage node. |
2032 | | // |
2033 | | // If `future_parent` is `Some`: |
2034 | | // |
2035 | | // |
2036 | | // `future_parent` |
2037 | | // |
2038 | | // +-+ |
2039 | | // +-+ <--------+ (0 or more existing children) |
2040 | | // ^ |
2041 | | // | |
2042 | | // New branch node +-+ |
2043 | | // +-+ <-------+ |
2044 | | // ^ | |
2045 | | // | | |
2046 | | // +-+ +-+ |
2047 | | // `existing_node_index` +-+ +-+ New storage node |
2048 | | // ^ |
2049 | | // | |
2050 | | // |
2051 | | // (0 or more existing children) |
2052 | | // |
2053 | | // |
2054 | | // |
2055 | | // If `future_parent` is `None`: |
2056 | | // |
2057 | | // |
2058 | | // New branch node +-+ |
2059 | | // (becomes root) +-+ <-------+ |
2060 | | // ^ | |
2061 | | // | | |
2062 | | // `existing_node_index` +-+ +-+ |
2063 | | // (current root) +-+ +-+ New storage node |
2064 | | // ^ |
2065 | | // | |
2066 | | // |
2067 | | // (0 or more existing children) |
2068 | | // |
2069 | | // |
2070 | | |
2071 | | // Find the common ancestor between `new_node_partial_key` and `existing_node_partial_key`. |
2072 | 241k | let branch_partial_key_len = { |
2073 | 241k | debug_assert_ne!(new_node_partial_key, &**existing_node_partial_key); |
2074 | 241k | let mut len = 0; |
2075 | 241k | let mut k1 = new_node_partial_key.iter(); |
2076 | 241k | let mut k2 = existing_node_partial_key.iter(); |
2077 | | // Since `new_node_partial_key` is different from `existing_node_partial_key`, we know |
2078 | | // that `k1.next()` and `k2.next()` won't both be `None`. |
2079 | 365k | while k1.next() == k2.next() { |
2080 | 123k | len += 1; |
2081 | 123k | } |
2082 | 241k | debug_assert!(len < new_node_partial_key.len()); |
2083 | 241k | debug_assert!(len < existing_node_partial_key.len()); |
2084 | 241k | len |
2085 | | }; |
2086 | | |
2087 | | // Table of children for the new branch node, not including the new storage node. |
2088 | | // It therefore contains only one entry: `existing_node_index`. |
2089 | 241k | let branch_children = { |
2090 | 241k | let mut branch_children = [None; 16]; |
2091 | 241k | let existing_node_new_child_index = existing_node_partial_key[branch_partial_key_len]; |
2092 | 241k | debug_assert_ne!( |
2093 | | existing_node_new_child_index, |
2094 | 241k | new_node_partial_key[branch_partial_key_len] |
2095 | | ); |
2096 | 241k | branch_children[usize::from(u8::from(existing_node_new_child_index))] = |
2097 | 241k | Some(existing_node_index); |
2098 | 241k | branch_children |
2099 | | }; |
2100 | | |
2101 | | // Success! |
2102 | | PrepareInsert::Two(PrepareInsertTwo { |
2103 | 241k | trie: self.trie, |
2104 | | |
2105 | 241k | storage_child_index: new_node_partial_key[branch_partial_key_len], |
2106 | 241k | storage_partial_key: new_node_partial_key[branch_partial_key_len + 1..].to_owned(), |
2107 | | |
2108 | 241k | branch_parent: if let Some((future_parent_index225k , future_parent_key_len225k )) = future_parent |
2109 | | { |
2110 | 225k | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); |
2111 | 225k | Some((future_parent_index, new_child_index)) |
2112 | | } else { |
2113 | 16.0k | None |
2114 | | }, |
2115 | 241k | branch_partial_key: new_node_partial_key[..branch_partial_key_len].to_owned(), |
2116 | 241k | branch_children, |
2117 | | }) |
2118 | 1.35M | } _RNvMs7_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_6VacantINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEINtNtNtNtB18_4iter8adapters6copied6CopiedINtNtNtB18_5slice4iter4IterNtNtB7_6nibble6NibbleEEE20insert_storage_valueB9_ Line | Count | Source | 1889 | 29.7k | pub fn insert_storage_value(mut self) -> PrepareInsert<'a, TUd> { | 1890 | | // Retrieve what will be the parent after we insert the new node, not taking branching | 1891 | | // into account yet. | 1892 | | // If `Some`, contains its index and number of nibbles in its key. | 1893 | 29.7k | let future_parent28.2k = match (self.closest_ancestor, self.trie.root_index) { | 1894 | 0 | (Some(_), None) => unreachable!(), | 1895 | 26.1k | (Some(ancestor), Some(_)) => { | 1896 | | // TODO: could be optimized by passing in the Vacant the key remainder | 1897 | 26.1k | let key_len = self.trie.node_full_key(ancestor).count(); | 1898 | 26.1k | debug_assert!(self.key.clone().count() > key_len); | 1899 | 26.1k | Some((ancestor, key_len)) | 1900 | | } | 1901 | 2.06k | (None, Some(_)) => None, | 1902 | | (None, None) => { | 1903 | | // Situation where the trie is empty. This is kind of a special case that we | 1904 | | // handle by returning early. | 1905 | 1.50k | return PrepareInsert::One(PrepareInsertOne { | 1906 | 1.50k | trie: self.trie, | 1907 | 1.50k | parent: None, | 1908 | 1.50k | partial_key: self.key.collect(), | 1909 | 1.50k | children: [None; 16], | 1910 | 1.50k | }); | 1911 | | } | 1912 | | }; | 1913 | | | 1914 | | // Get the existing child of `future_parent` that points towards the newly-inserted node, | 1915 | | // or a successful early-return if none. | 1916 | 7.45k | let existing_node_index = | 1917 | 28.2k | if let Some((future_parent_index26.1k , future_parent_key_len26.1k )) = future_parent { | 1918 | 26.1k | let new_child_index = self.key.clone().nth(future_parent_key_len).unwrap(); | 1919 | 26.1k | let future_parent = self.trie.nodes.get(future_parent_index).unwrap(); | 1920 | 26.1k | match future_parent.children[usize::from(u8::from(new_child_index))] { | 1921 | 5.39k | Some(i) => { | 1922 | 5.39k | debug_assert_eq!( | 1923 | 5.39k | self.trie.nodes.get(i).unwrap().parent.unwrap().0, | 1924 | | future_parent_index | 1925 | | ); | 1926 | 5.39k | i | 1927 | | } | 1928 | | None => { | 1929 | | // There is an empty slot in `future_parent` for our new node. | 1930 | | // | 1931 | | // | 1932 | | // `future_parent` | 1933 | | // +-+ | 1934 | | // +-> +-+ <---------+ | 1935 | | // | <----+ | | 1936 | | // | ^ | | | 1937 | | // +-+ | | | | 1938 | | // New node +-+ +-+-+ +-+ +-+ 0 or more existing children | 1939 | | // +-+ +-+ +-+ | 1940 | | // | 1941 | | // | 1942 | 20.7k | return PrepareInsert::One(PrepareInsertOne { | 1943 | 20.7k | trie: self.trie, | 1944 | 20.7k | parent: Some((future_parent_index, new_child_index)), | 1945 | 20.7k | partial_key: self.key.skip(future_parent_key_len + 1).collect(), | 1946 | 20.7k | children: [None; 16], | 1947 | 20.7k | }); | 1948 | | } | 1949 | | } | 1950 | | } else { | 1951 | 2.06k | self.trie.root_index.unwrap() | 1952 | | }; | 1953 | | | 1954 | | // `existing_node_idx` and the new node are known to either have the same parent and the | 1955 | | // same child index, or to both have no parent. Now let's compare their partial key. | 1956 | 7.45k | let existing_node_partial_key = &self | 1957 | 7.45k | .trie | 1958 | 7.45k | .nodes | 1959 | 7.45k | .get(existing_node_index) | 1960 | 7.45k | .unwrap() | 1961 | 7.45k | .partial_key; | 1962 | 7.45k | let new_node_partial_key = self | 1963 | 7.45k | .key | 1964 | 7.45k | .clone() | 1965 | 7.45k | .skip(future_parent.map_or(0, |(_, n)| n + 1)) | 1966 | 7.45k | .collect::<Vec<_>>(); | 1967 | 7.45k | debug_assert_ne!(*existing_node_partial_key, new_node_partial_key); | 1968 | 7.45k | debug_assert!(!new_node_partial_key.starts_with(existing_node_partial_key)); | 1969 | | | 1970 | | // If `existing_node_partial_key` starts with `new_node_partial_key`, then the new node | 1971 | | // will be inserted in-between the parent and the existing node. | 1972 | 7.45k | if existing_node_partial_key.starts_with(&new_node_partial_key) { | 1973 | | // The new node is to be inserted in-between `future_parent` and | 1974 | | // `existing_node_index`. | 1975 | | // | 1976 | | // If `future_parent` is `Some`: | 1977 | | // | 1978 | | // | 1979 | | // +-+ | 1980 | | // `future_parent` +-+ <---------+ | 1981 | | // ^ | | 1982 | | // | + | 1983 | | // +-+ (0 or more existing children) | 1984 | | // New node +-+ | 1985 | | // ^ | 1986 | | // | | 1987 | | // +-+ | 1988 | | // `existing_node_index` +-+ | 1989 | | // ^ | 1990 | | // | | 1991 | | // + | 1992 | | // (0 or more existing children) | 1993 | | // | 1994 | | // | 1995 | | // | 1996 | | // If `future_parent` is `None`: | 1997 | | // | 1998 | | // | 1999 | | // New node +-+ | 2000 | | // (becomes the root) +-+ | 2001 | | // ^ | 2002 | | // | | 2003 | | // `existing_node_index` +-+ | 2004 | | // (current root) +-+ | 2005 | | // ^ | 2006 | | // | | 2007 | | // + | 2008 | | // (0 or more existing children) | 2009 | | // | 2010 | | | 2011 | 7.45k | let mut new_node_children = [None; 16]; | 2012 | 7.45k | let existing_node_new_child_index = | 2013 | 7.45k | existing_node_partial_key[new_node_partial_key.len()]; | 2014 | 7.45k | new_node_children[usize::from(u8::from(existing_node_new_child_index))] = | 2015 | 7.45k | Some(existing_node_index); | 2016 | | | 2017 | | return PrepareInsert::One(PrepareInsertOne { | 2018 | 7.45k | trie: self.trie, | 2019 | 7.45k | parent: if let Some((future_parent_index5.39k , future_parent_key_len5.39k )) = future_parent { | 2020 | 5.39k | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2021 | 5.39k | Some((future_parent_index, new_child_index)) | 2022 | | } else { | 2023 | 2.06k | None | 2024 | | }, | 2025 | 7.45k | partial_key: new_node_partial_key, | 2026 | 7.45k | children: new_node_children, | 2027 | | }); | 2028 | 0 | } | 2029 | | | 2030 | | // If we reach here, we know that we will need to create a new branch node in addition to | 2031 | | // the new storage node. | 2032 | | // | 2033 | | // If `future_parent` is `Some`: | 2034 | | // | 2035 | | // | 2036 | | // `future_parent` | 2037 | | // | 2038 | | // +-+ | 2039 | | // +-+ <--------+ (0 or more existing children) | 2040 | | // ^ | 2041 | | // | | 2042 | | // New branch node +-+ | 2043 | | // +-+ <-------+ | 2044 | | // ^ | | 2045 | | // | | | 2046 | | // +-+ +-+ | 2047 | | // `existing_node_index` +-+ +-+ New storage node | 2048 | | // ^ | 2049 | | // | | 2050 | | // | 2051 | | // (0 or more existing children) | 2052 | | // | 2053 | | // | 2054 | | // | 2055 | | // If `future_parent` is `None`: | 2056 | | // | 2057 | | // | 2058 | | // New branch node +-+ | 2059 | | // (becomes root) +-+ <-------+ | 2060 | | // ^ | | 2061 | | // | | | 2062 | | // `existing_node_index` +-+ +-+ | 2063 | | // (current root) +-+ +-+ New storage node | 2064 | | // ^ | 2065 | | // | | 2066 | | // | 2067 | | // (0 or more existing children) | 2068 | | // | 2069 | | // | 2070 | | | 2071 | | // Find the common ancestor between `new_node_partial_key` and `existing_node_partial_key`. | 2072 | 0 | let branch_partial_key_len = { | 2073 | 0 | debug_assert_ne!(new_node_partial_key, &**existing_node_partial_key); | 2074 | 0 | let mut len = 0; | 2075 | 0 | let mut k1 = new_node_partial_key.iter(); | 2076 | 0 | let mut k2 = existing_node_partial_key.iter(); | 2077 | | // Since `new_node_partial_key` is different from `existing_node_partial_key`, we know | 2078 | | // that `k1.next()` and `k2.next()` won't both be `None`. | 2079 | 0 | while k1.next() == k2.next() { | 2080 | 0 | len += 1; | 2081 | 0 | } | 2082 | 0 | debug_assert!(len < new_node_partial_key.len()); | 2083 | 0 | debug_assert!(len < existing_node_partial_key.len()); | 2084 | 0 | len | 2085 | | }; | 2086 | | | 2087 | | // Table of children for the new branch node, not including the new storage node. | 2088 | | // It therefore contains only one entry: `existing_node_index`. | 2089 | 0 | let branch_children = { | 2090 | 0 | let mut branch_children = [None; 16]; | 2091 | 0 | let existing_node_new_child_index = existing_node_partial_key[branch_partial_key_len]; | 2092 | 0 | debug_assert_ne!( | 2093 | | existing_node_new_child_index, | 2094 | 0 | new_node_partial_key[branch_partial_key_len] | 2095 | | ); | 2096 | 0 | branch_children[usize::from(u8::from(existing_node_new_child_index))] = | 2097 | 0 | Some(existing_node_index); | 2098 | 0 | branch_children | 2099 | | }; | 2100 | | | 2101 | | // Success! | 2102 | | PrepareInsert::Two(PrepareInsertTwo { | 2103 | 0 | trie: self.trie, | 2104 | | | 2105 | 0 | storage_child_index: new_node_partial_key[branch_partial_key_len], | 2106 | 0 | storage_partial_key: new_node_partial_key[branch_partial_key_len + 1..].to_owned(), | 2107 | | | 2108 | 0 | branch_parent: if let Some((future_parent_index, future_parent_key_len)) = future_parent | 2109 | | { | 2110 | 0 | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2111 | 0 | Some((future_parent_index, new_child_index)) | 2112 | | } else { | 2113 | 0 | None | 2114 | | }, | 2115 | 0 | branch_partial_key: new_node_partial_key[..branch_partial_key_len].to_owned(), | 2116 | 0 | branch_children, | 2117 | | }) | 2118 | 29.7k | } |
_RNvMs7_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_6VacantTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB15_NtNtB7_9trie_node17MerkleValueOutputEEINtNtB7_6nibble14BytesToNibblesINtNtNtNtB19_4iter8adapters6copied6CopiedINtNtNtB19_5slice4iter4IterhEEEE20insert_storage_valueB9_ Line | Count | Source | 1889 | 2.51k | pub fn insert_storage_value(mut self) -> PrepareInsert<'a, TUd> { | 1890 | | // Retrieve what will be the parent after we insert the new node, not taking branching | 1891 | | // into account yet. | 1892 | | // If `Some`, contains its index and number of nibbles in its key. | 1893 | 2.51k | let future_parent1.48k = match (self.closest_ancestor, self.trie.root_index) { | 1894 | 0 | (Some(_), None) => unreachable!(), | 1895 | 1.48k | (Some(ancestor), Some(_)) => { | 1896 | | // TODO: could be optimized by passing in the Vacant the key remainder | 1897 | 1.48k | let key_len = self.trie.node_full_key(ancestor).count(); | 1898 | 1.48k | debug_assert!(self.key.clone().count() > key_len); | 1899 | 1.48k | Some((ancestor, key_len)) | 1900 | | } | 1901 | 0 | (None, Some(_)) => None, | 1902 | | (None, None) => { | 1903 | | // Situation where the trie is empty. This is kind of a special case that we | 1904 | | // handle by returning early. | 1905 | 1.02k | return PrepareInsert::One(PrepareInsertOne { | 1906 | 1.02k | trie: self.trie, | 1907 | 1.02k | parent: None, | 1908 | 1.02k | partial_key: self.key.collect(), | 1909 | 1.02k | children: [None; 16], | 1910 | 1.02k | }); | 1911 | | } | 1912 | | }; | 1913 | | | 1914 | | // Get the existing child of `future_parent` that points towards the newly-inserted node, | 1915 | | // or a successful early-return if none. | 1916 | 56 | let existing_node_index = | 1917 | 1.48k | if let Some((future_parent_index, future_parent_key_len)) = future_parent { | 1918 | 1.48k | let new_child_index = self.key.clone().nth(future_parent_key_len).unwrap(); | 1919 | 1.48k | let future_parent = self.trie.nodes.get(future_parent_index).unwrap(); | 1920 | 1.48k | match future_parent.children[usize::from(u8::from(new_child_index))] { | 1921 | 56 | Some(i) => { | 1922 | 56 | debug_assert_eq!( | 1923 | 56 | self.trie.nodes.get(i).unwrap().parent.unwrap().0, | 1924 | | future_parent_index | 1925 | | ); | 1926 | 56 | i | 1927 | | } | 1928 | | None => { | 1929 | | // There is an empty slot in `future_parent` for our new node. | 1930 | | // | 1931 | | // | 1932 | | // `future_parent` | 1933 | | // +-+ | 1934 | | // +-> +-+ <---------+ | 1935 | | // | <----+ | | 1936 | | // | ^ | | | 1937 | | // +-+ | | | | 1938 | | // New node +-+ +-+-+ +-+ +-+ 0 or more existing children | 1939 | | // +-+ +-+ +-+ | 1940 | | // | 1941 | | // | 1942 | 1.43k | return PrepareInsert::One(PrepareInsertOne { | 1943 | 1.43k | trie: self.trie, | 1944 | 1.43k | parent: Some((future_parent_index, new_child_index)), | 1945 | 1.43k | partial_key: self.key.skip(future_parent_key_len + 1).collect(), | 1946 | 1.43k | children: [None; 16], | 1947 | 1.43k | }); | 1948 | | } | 1949 | | } | 1950 | | } else { | 1951 | 0 | self.trie.root_index.unwrap() | 1952 | | }; | 1953 | | | 1954 | | // `existing_node_idx` and the new node are known to either have the same parent and the | 1955 | | // same child index, or to both have no parent. Now let's compare their partial key. | 1956 | 56 | let existing_node_partial_key = &self | 1957 | 56 | .trie | 1958 | 56 | .nodes | 1959 | 56 | .get(existing_node_index) | 1960 | 56 | .unwrap() | 1961 | 56 | .partial_key; | 1962 | 56 | let new_node_partial_key = self | 1963 | 56 | .key | 1964 | 56 | .clone() | 1965 | 56 | .skip(future_parent.map_or(0, |(_, n)| n + 1)) | 1966 | 56 | .collect::<Vec<_>>(); | 1967 | 56 | debug_assert_ne!(*existing_node_partial_key, new_node_partial_key); | 1968 | 56 | debug_assert!(!new_node_partial_key.starts_with(existing_node_partial_key)); | 1969 | | | 1970 | | // If `existing_node_partial_key` starts with `new_node_partial_key`, then the new node | 1971 | | // will be inserted in-between the parent and the existing node. | 1972 | 56 | if existing_node_partial_key.starts_with(&new_node_partial_key) { | 1973 | | // The new node is to be inserted in-between `future_parent` and | 1974 | | // `existing_node_index`. | 1975 | | // | 1976 | | // If `future_parent` is `Some`: | 1977 | | // | 1978 | | // | 1979 | | // +-+ | 1980 | | // `future_parent` +-+ <---------+ | 1981 | | // ^ | | 1982 | | // | + | 1983 | | // +-+ (0 or more existing children) | 1984 | | // New node +-+ | 1985 | | // ^ | 1986 | | // | | 1987 | | // +-+ | 1988 | | // `existing_node_index` +-+ | 1989 | | // ^ | 1990 | | // | | 1991 | | // + | 1992 | | // (0 or more existing children) | 1993 | | // | 1994 | | // | 1995 | | // | 1996 | | // If `future_parent` is `None`: | 1997 | | // | 1998 | | // | 1999 | | // New node +-+ | 2000 | | // (becomes the root) +-+ | 2001 | | // ^ | 2002 | | // | | 2003 | | // `existing_node_index` +-+ | 2004 | | // (current root) +-+ | 2005 | | // ^ | 2006 | | // | | 2007 | | // + | 2008 | | // (0 or more existing children) | 2009 | | // | 2010 | | | 2011 | 1 | let mut new_node_children = [None; 16]; | 2012 | 1 | let existing_node_new_child_index = | 2013 | 1 | existing_node_partial_key[new_node_partial_key.len()]; | 2014 | 1 | new_node_children[usize::from(u8::from(existing_node_new_child_index))] = | 2015 | 1 | Some(existing_node_index); | 2016 | | | 2017 | | return PrepareInsert::One(PrepareInsertOne { | 2018 | 1 | trie: self.trie, | 2019 | 1 | parent: if let Some((future_parent_index, future_parent_key_len)) = future_parent { | 2020 | 1 | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2021 | 1 | Some((future_parent_index, new_child_index)) | 2022 | | } else { | 2023 | 0 | None | 2024 | | }, | 2025 | 1 | partial_key: new_node_partial_key, | 2026 | 1 | children: new_node_children, | 2027 | | }); | 2028 | 55 | } | 2029 | | | 2030 | | // If we reach here, we know that we will need to create a new branch node in addition to | 2031 | | // the new storage node. | 2032 | | // | 2033 | | // If `future_parent` is `Some`: | 2034 | | // | 2035 | | // | 2036 | | // `future_parent` | 2037 | | // | 2038 | | // +-+ | 2039 | | // +-+ <--------+ (0 or more existing children) | 2040 | | // ^ | 2041 | | // | | 2042 | | // New branch node +-+ | 2043 | | // +-+ <-------+ | 2044 | | // ^ | | 2045 | | // | | | 2046 | | // +-+ +-+ | 2047 | | // `existing_node_index` +-+ +-+ New storage node | 2048 | | // ^ | 2049 | | // | | 2050 | | // | 2051 | | // (0 or more existing children) | 2052 | | // | 2053 | | // | 2054 | | // | 2055 | | // If `future_parent` is `None`: | 2056 | | // | 2057 | | // | 2058 | | // New branch node +-+ | 2059 | | // (becomes root) +-+ <-------+ | 2060 | | // ^ | | 2061 | | // | | | 2062 | | // `existing_node_index` +-+ +-+ | 2063 | | // (current root) +-+ +-+ New storage node | 2064 | | // ^ | 2065 | | // | | 2066 | | // | 2067 | | // (0 or more existing children) | 2068 | | // | 2069 | | // | 2070 | | | 2071 | | // Find the common ancestor between `new_node_partial_key` and `existing_node_partial_key`. | 2072 | 55 | let branch_partial_key_len = { | 2073 | 55 | debug_assert_ne!(new_node_partial_key, &**existing_node_partial_key); | 2074 | 55 | let mut len = 0; | 2075 | 55 | let mut k1 = new_node_partial_key.iter(); | 2076 | 55 | let mut k2 = existing_node_partial_key.iter(); | 2077 | | // Since `new_node_partial_key` is different from `existing_node_partial_key`, we know | 2078 | | // that `k1.next()` and `k2.next()` won't both be `None`. | 2079 | 57 | while k1.next() == k2.next() { | 2080 | 2 | len += 1; | 2081 | 2 | } | 2082 | 55 | debug_assert!(len < new_node_partial_key.len()); | 2083 | 55 | debug_assert!(len < existing_node_partial_key.len()); | 2084 | 55 | len | 2085 | | }; | 2086 | | | 2087 | | // Table of children for the new branch node, not including the new storage node. | 2088 | | // It therefore contains only one entry: `existing_node_index`. | 2089 | 55 | let branch_children = { | 2090 | 55 | let mut branch_children = [None; 16]; | 2091 | 55 | let existing_node_new_child_index = existing_node_partial_key[branch_partial_key_len]; | 2092 | 55 | debug_assert_ne!( | 2093 | | existing_node_new_child_index, | 2094 | 55 | new_node_partial_key[branch_partial_key_len] | 2095 | | ); | 2096 | 55 | branch_children[usize::from(u8::from(existing_node_new_child_index))] = | 2097 | 55 | Some(existing_node_index); | 2098 | 55 | branch_children | 2099 | | }; | 2100 | | | 2101 | | // Success! | 2102 | | PrepareInsert::Two(PrepareInsertTwo { | 2103 | 55 | trie: self.trie, | 2104 | | | 2105 | 55 | storage_child_index: new_node_partial_key[branch_partial_key_len], | 2106 | 55 | storage_partial_key: new_node_partial_key[branch_partial_key_len + 1..].to_owned(), | 2107 | | | 2108 | 55 | branch_parent: if let Some((future_parent_index, future_parent_key_len)) = future_parent | 2109 | | { | 2110 | 55 | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2111 | 55 | Some((future_parent_index, new_child_index)) | 2112 | | } else { | 2113 | 0 | None | 2114 | | }, | 2115 | 55 | branch_partial_key: new_node_partial_key[..branch_partial_key_len].to_owned(), | 2116 | 55 | branch_children, | 2117 | | }) | 2118 | 2.51k | } |
_RNvMs7_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_6VacantTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB15_NtNtB7_9trie_node17MerkleValueOutputEEINtNtB7_6nibble14BytesToNibblesINtNtNtNtB19_4iter8adapters6copied6CopiedINtNtNtB19_5slice4iter4IterhEEEE20insert_storage_valueB9_ Line | Count | Source | 1889 | 335k | pub fn insert_storage_value(mut self) -> PrepareInsert<'a, TUd> { | 1890 | | // Retrieve what will be the parent after we insert the new node, not taking branching | 1891 | | // into account yet. | 1892 | | // If `Some`, contains its index and number of nibbles in its key. | 1893 | 335k | let future_parent296k = match (self.closest_ancestor, self.trie.root_index) { | 1894 | 0 | (Some(_), None) => unreachable!(), | 1895 | 283k | (Some(ancestor), Some(_)) => { | 1896 | | // TODO: could be optimized by passing in the Vacant the key remainder | 1897 | 283k | let key_len = self.trie.node_full_key(ancestor).count(); | 1898 | 283k | debug_assert!(self.key.clone().count() > key_len); | 1899 | 283k | Some((ancestor, key_len)) | 1900 | | } | 1901 | 12.9k | (None, Some(_)) => None, | 1902 | | (None, None) => { | 1903 | | // Situation where the trie is empty. This is kind of a special case that we | 1904 | | // handle by returning early. | 1905 | 38.9k | return PrepareInsert::One(PrepareInsertOne { | 1906 | 38.9k | trie: self.trie, | 1907 | 38.9k | parent: None, | 1908 | 38.9k | partial_key: self.key.collect(), | 1909 | 38.9k | children: [None; 16], | 1910 | 38.9k | }); | 1911 | | } | 1912 | | }; | 1913 | | | 1914 | | // Get the existing child of `future_parent` that points towards the newly-inserted node, | 1915 | | // or a successful early-return if none. | 1916 | 70.6k | let existing_node_index = | 1917 | 296k | if let Some((future_parent_index283k , future_parent_key_len283k )) = future_parent { | 1918 | 283k | let new_child_index = self.key.clone().nth(future_parent_key_len).unwrap(); | 1919 | 283k | let future_parent = self.trie.nodes.get(future_parent_index).unwrap(); | 1920 | 283k | match future_parent.children[usize::from(u8::from(new_child_index))] { | 1921 | 57.6k | Some(i) => { | 1922 | 57.6k | debug_assert_eq!( | 1923 | 57.6k | self.trie.nodes.get(i).unwrap().parent.unwrap().0, | 1924 | | future_parent_index | 1925 | | ); | 1926 | 57.6k | i | 1927 | | } | 1928 | | None => { | 1929 | | // There is an empty slot in `future_parent` for our new node. | 1930 | | // | 1931 | | // | 1932 | | // `future_parent` | 1933 | | // +-+ | 1934 | | // +-> +-+ <---------+ | 1935 | | // | <----+ | | 1936 | | // | ^ | | | 1937 | | // +-+ | | | | 1938 | | // New node +-+ +-+-+ +-+ +-+ 0 or more existing children | 1939 | | // +-+ +-+ +-+ | 1940 | | // | 1941 | | // | 1942 | 226k | return PrepareInsert::One(PrepareInsertOne { | 1943 | 226k | trie: self.trie, | 1944 | 226k | parent: Some((future_parent_index, new_child_index)), | 1945 | 226k | partial_key: self.key.skip(future_parent_key_len + 1).collect(), | 1946 | 226k | children: [None; 16], | 1947 | 226k | }); | 1948 | | } | 1949 | | } | 1950 | | } else { | 1951 | 12.9k | self.trie.root_index.unwrap() | 1952 | | }; | 1953 | | | 1954 | | // `existing_node_idx` and the new node are known to either have the same parent and the | 1955 | | // same child index, or to both have no parent. Now let's compare their partial key. | 1956 | 70.6k | let existing_node_partial_key = &self | 1957 | 70.6k | .trie | 1958 | 70.6k | .nodes | 1959 | 70.6k | .get(existing_node_index) | 1960 | 70.6k | .unwrap() | 1961 | 70.6k | .partial_key; | 1962 | 70.6k | let new_node_partial_key = self | 1963 | 70.6k | .key | 1964 | 70.6k | .clone() | 1965 | 70.6k | .skip(future_parent.map_or(0, |(_, n)| n + 1)) | 1966 | 70.6k | .collect::<Vec<_>>(); | 1967 | 70.6k | debug_assert_ne!(*existing_node_partial_key, new_node_partial_key); | 1968 | 70.6k | debug_assert!(!new_node_partial_key.starts_with(existing_node_partial_key)); | 1969 | | | 1970 | | // If `existing_node_partial_key` starts with `new_node_partial_key`, then the new node | 1971 | | // will be inserted in-between the parent and the existing node. | 1972 | 70.6k | if existing_node_partial_key.starts_with(&new_node_partial_key) { | 1973 | | // The new node is to be inserted in-between `future_parent` and | 1974 | | // `existing_node_index`. | 1975 | | // | 1976 | | // If `future_parent` is `Some`: | 1977 | | // | 1978 | | // | 1979 | | // +-+ | 1980 | | // `future_parent` +-+ <---------+ | 1981 | | // ^ | | 1982 | | // | + | 1983 | | // +-+ (0 or more existing children) | 1984 | | // New node +-+ | 1985 | | // ^ | 1986 | | // | | 1987 | | // +-+ | 1988 | | // `existing_node_index` +-+ | 1989 | | // ^ | 1990 | | // | | 1991 | | // + | 1992 | | // (0 or more existing children) | 1993 | | // | 1994 | | // | 1995 | | // | 1996 | | // If `future_parent` is `None`: | 1997 | | // | 1998 | | // | 1999 | | // New node +-+ | 2000 | | // (becomes the root) +-+ | 2001 | | // ^ | 2002 | | // | | 2003 | | // `existing_node_index` +-+ | 2004 | | // (current root) +-+ | 2005 | | // ^ | 2006 | | // | | 2007 | | // + | 2008 | | // (0 or more existing children) | 2009 | | // | 2010 | | | 2011 | 6.74k | let mut new_node_children = [None; 16]; | 2012 | 6.74k | let existing_node_new_child_index = | 2013 | 6.74k | existing_node_partial_key[new_node_partial_key.len()]; | 2014 | 6.74k | new_node_children[usize::from(u8::from(existing_node_new_child_index))] = | 2015 | 6.74k | Some(existing_node_index); | 2016 | | | 2017 | | return PrepareInsert::One(PrepareInsertOne { | 2018 | 6.74k | trie: self.trie, | 2019 | 6.74k | parent: if let Some((future_parent_index1.11k , future_parent_key_len1.11k )) = future_parent { | 2020 | 1.11k | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2021 | 1.11k | Some((future_parent_index, new_child_index)) | 2022 | | } else { | 2023 | 5.63k | None | 2024 | | }, | 2025 | 6.74k | partial_key: new_node_partial_key, | 2026 | 6.74k | children: new_node_children, | 2027 | | }); | 2028 | 63.8k | } | 2029 | | | 2030 | | // If we reach here, we know that we will need to create a new branch node in addition to | 2031 | | // the new storage node. | 2032 | | // | 2033 | | // If `future_parent` is `Some`: | 2034 | | // | 2035 | | // | 2036 | | // `future_parent` | 2037 | | // | 2038 | | // +-+ | 2039 | | // +-+ <--------+ (0 or more existing children) | 2040 | | // ^ | 2041 | | // | | 2042 | | // New branch node +-+ | 2043 | | // +-+ <-------+ | 2044 | | // ^ | | 2045 | | // | | | 2046 | | // +-+ +-+ | 2047 | | // `existing_node_index` +-+ +-+ New storage node | 2048 | | // ^ | 2049 | | // | | 2050 | | // | 2051 | | // (0 or more existing children) | 2052 | | // | 2053 | | // | 2054 | | // | 2055 | | // If `future_parent` is `None`: | 2056 | | // | 2057 | | // | 2058 | | // New branch node +-+ | 2059 | | // (becomes root) +-+ <-------+ | 2060 | | // ^ | | 2061 | | // | | | 2062 | | // `existing_node_index` +-+ +-+ | 2063 | | // (current root) +-+ +-+ New storage node | 2064 | | // ^ | 2065 | | // | | 2066 | | // | 2067 | | // (0 or more existing children) | 2068 | | // | 2069 | | // | 2070 | | | 2071 | | // Find the common ancestor between `new_node_partial_key` and `existing_node_partial_key`. | 2072 | 63.8k | let branch_partial_key_len = { | 2073 | 63.8k | debug_assert_ne!(new_node_partial_key, &**existing_node_partial_key); | 2074 | 63.8k | let mut len = 0; | 2075 | 63.8k | let mut k1 = new_node_partial_key.iter(); | 2076 | 63.8k | let mut k2 = existing_node_partial_key.iter(); | 2077 | | // Since `new_node_partial_key` is different from `existing_node_partial_key`, we know | 2078 | | // that `k1.next()` and `k2.next()` won't both be `None`. | 2079 | 66.0k | while k1.next() == k2.next() { | 2080 | 2.17k | len += 1; | 2081 | 2.17k | } | 2082 | 63.8k | debug_assert!(len < new_node_partial_key.len()); | 2083 | 63.8k | debug_assert!(len < existing_node_partial_key.len()); | 2084 | 63.8k | len | 2085 | | }; | 2086 | | | 2087 | | // Table of children for the new branch node, not including the new storage node. | 2088 | | // It therefore contains only one entry: `existing_node_index`. | 2089 | 63.8k | let branch_children = { | 2090 | 63.8k | let mut branch_children = [None; 16]; | 2091 | 63.8k | let existing_node_new_child_index = existing_node_partial_key[branch_partial_key_len]; | 2092 | 63.8k | debug_assert_ne!( | 2093 | | existing_node_new_child_index, | 2094 | 63.8k | new_node_partial_key[branch_partial_key_len] | 2095 | | ); | 2096 | 63.8k | branch_children[usize::from(u8::from(existing_node_new_child_index))] = | 2097 | 63.8k | Some(existing_node_index); | 2098 | 63.8k | branch_children | 2099 | | }; | 2100 | | | 2101 | | // Success! | 2102 | | PrepareInsert::Two(PrepareInsertTwo { | 2103 | 63.8k | trie: self.trie, | 2104 | | | 2105 | 63.8k | storage_child_index: new_node_partial_key[branch_partial_key_len], | 2106 | 63.8k | storage_partial_key: new_node_partial_key[branch_partial_key_len + 1..].to_owned(), | 2107 | | | 2108 | 63.8k | branch_parent: if let Some((future_parent_index56.5k , future_parent_key_len56.5k )) = future_parent | 2109 | | { | 2110 | 56.5k | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2111 | 56.5k | Some((future_parent_index, new_child_index)) | 2112 | | } else { | 2113 | 7.31k | None | 2114 | | }, | 2115 | 63.8k | branch_partial_key: new_node_partial_key[..branch_partial_key_len].to_owned(), | 2116 | 63.8k | branch_children, | 2117 | | }) | 2118 | 335k | } |
_RNvMs7_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_6VacantuINtNtB7_6nibble14BytesToNibblesINtNtNtNtCs66KPHxksi63_4core4iter8adapters6copied6CopiedINtNtNtB1I_5slice4iter4IterhEEEE20insert_storage_valueB9_ Line | Count | Source | 1889 | 5.04k | pub fn insert_storage_value(mut self) -> PrepareInsert<'a, TUd> { | 1890 | | // Retrieve what will be the parent after we insert the new node, not taking branching | 1891 | | // into account yet. | 1892 | | // If `Some`, contains its index and number of nibbles in its key. | 1893 | 5.04k | let future_parent2.99k = match (self.closest_ancestor, self.trie.root_index) { | 1894 | 0 | (Some(_), None) => unreachable!(), | 1895 | 2.99k | (Some(ancestor), Some(_)) => { | 1896 | | // TODO: could be optimized by passing in the Vacant the key remainder | 1897 | 2.99k | let key_len = self.trie.node_full_key(ancestor).count(); | 1898 | 2.99k | debug_assert!(self.key.clone().count() > key_len); | 1899 | 2.99k | Some((ancestor, key_len)) | 1900 | | } | 1901 | 0 | (None, Some(_)) => None, | 1902 | | (None, None) => { | 1903 | | // Situation where the trie is empty. This is kind of a special case that we | 1904 | | // handle by returning early. | 1905 | 2.04k | return PrepareInsert::One(PrepareInsertOne { | 1906 | 2.04k | trie: self.trie, | 1907 | 2.04k | parent: None, | 1908 | 2.04k | partial_key: self.key.collect(), | 1909 | 2.04k | children: [None; 16], | 1910 | 2.04k | }); | 1911 | | } | 1912 | | }; | 1913 | | | 1914 | | // Get the existing child of `future_parent` that points towards the newly-inserted node, | 1915 | | // or a successful early-return if none. | 1916 | 148 | let existing_node_index = | 1917 | 2.99k | if let Some((future_parent_index, future_parent_key_len)) = future_parent { | 1918 | 2.99k | let new_child_index = self.key.clone().nth(future_parent_key_len).unwrap(); | 1919 | 2.99k | let future_parent = self.trie.nodes.get(future_parent_index).unwrap(); | 1920 | 2.99k | match future_parent.children[usize::from(u8::from(new_child_index))] { | 1921 | 148 | Some(i) => { | 1922 | 148 | debug_assert_eq!( | 1923 | 148 | self.trie.nodes.get(i).unwrap().parent.unwrap().0, | 1924 | | future_parent_index | 1925 | | ); | 1926 | 148 | i | 1927 | | } | 1928 | | None => { | 1929 | | // There is an empty slot in `future_parent` for our new node. | 1930 | | // | 1931 | | // | 1932 | | // `future_parent` | 1933 | | // +-+ | 1934 | | // +-> +-+ <---------+ | 1935 | | // | <----+ | | 1936 | | // | ^ | | | 1937 | | // +-+ | | | | 1938 | | // New node +-+ +-+-+ +-+ +-+ 0 or more existing children | 1939 | | // +-+ +-+ +-+ | 1940 | | // | 1941 | | // | 1942 | 2.85k | return PrepareInsert::One(PrepareInsertOne { | 1943 | 2.85k | trie: self.trie, | 1944 | 2.85k | parent: Some((future_parent_index, new_child_index)), | 1945 | 2.85k | partial_key: self.key.skip(future_parent_key_len + 1).collect(), | 1946 | 2.85k | children: [None; 16], | 1947 | 2.85k | }); | 1948 | | } | 1949 | | } | 1950 | | } else { | 1951 | 0 | self.trie.root_index.unwrap() | 1952 | | }; | 1953 | | | 1954 | | // `existing_node_idx` and the new node are known to either have the same parent and the | 1955 | | // same child index, or to both have no parent. Now let's compare their partial key. | 1956 | 148 | let existing_node_partial_key = &self | 1957 | 148 | .trie | 1958 | 148 | .nodes | 1959 | 148 | .get(existing_node_index) | 1960 | 148 | .unwrap() | 1961 | 148 | .partial_key; | 1962 | 148 | let new_node_partial_key = self | 1963 | 148 | .key | 1964 | 148 | .clone() | 1965 | 148 | .skip(future_parent.map_or(0, |(_, n)| n + 1)) | 1966 | 148 | .collect::<Vec<_>>(); | 1967 | 148 | debug_assert_ne!(*existing_node_partial_key, new_node_partial_key); | 1968 | 148 | debug_assert!(!new_node_partial_key.starts_with(existing_node_partial_key)); | 1969 | | | 1970 | | // If `existing_node_partial_key` starts with `new_node_partial_key`, then the new node | 1971 | | // will be inserted in-between the parent and the existing node. | 1972 | 148 | if existing_node_partial_key.starts_with(&new_node_partial_key) { | 1973 | | // The new node is to be inserted in-between `future_parent` and | 1974 | | // `existing_node_index`. | 1975 | | // | 1976 | | // If `future_parent` is `Some`: | 1977 | | // | 1978 | | // | 1979 | | // +-+ | 1980 | | // `future_parent` +-+ <---------+ | 1981 | | // ^ | | 1982 | | // | + | 1983 | | // +-+ (0 or more existing children) | 1984 | | // New node +-+ | 1985 | | // ^ | 1986 | | // | | 1987 | | // +-+ | 1988 | | // `existing_node_index` +-+ | 1989 | | // ^ | 1990 | | // | | 1991 | | // + | 1992 | | // (0 or more existing children) | 1993 | | // | 1994 | | // | 1995 | | // | 1996 | | // If `future_parent` is `None`: | 1997 | | // | 1998 | | // | 1999 | | // New node +-+ | 2000 | | // (becomes the root) +-+ | 2001 | | // ^ | 2002 | | // | | 2003 | | // `existing_node_index` +-+ | 2004 | | // (current root) +-+ | 2005 | | // ^ | 2006 | | // | | 2007 | | // + | 2008 | | // (0 or more existing children) | 2009 | | // | 2010 | | | 2011 | 1 | let mut new_node_children = [None; 16]; | 2012 | 1 | let existing_node_new_child_index = | 2013 | 1 | existing_node_partial_key[new_node_partial_key.len()]; | 2014 | 1 | new_node_children[usize::from(u8::from(existing_node_new_child_index))] = | 2015 | 1 | Some(existing_node_index); | 2016 | | | 2017 | | return PrepareInsert::One(PrepareInsertOne { | 2018 | 1 | trie: self.trie, | 2019 | 1 | parent: if let Some((future_parent_index, future_parent_key_len)) = future_parent { | 2020 | 1 | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2021 | 1 | Some((future_parent_index, new_child_index)) | 2022 | | } else { | 2023 | 0 | None | 2024 | | }, | 2025 | 1 | partial_key: new_node_partial_key, | 2026 | 1 | children: new_node_children, | 2027 | | }); | 2028 | 147 | } | 2029 | | | 2030 | | // If we reach here, we know that we will need to create a new branch node in addition to | 2031 | | // the new storage node. | 2032 | | // | 2033 | | // If `future_parent` is `Some`: | 2034 | | // | 2035 | | // | 2036 | | // `future_parent` | 2037 | | // | 2038 | | // +-+ | 2039 | | // +-+ <--------+ (0 or more existing children) | 2040 | | // ^ | 2041 | | // | | 2042 | | // New branch node +-+ | 2043 | | // +-+ <-------+ | 2044 | | // ^ | | 2045 | | // | | | 2046 | | // +-+ +-+ | 2047 | | // `existing_node_index` +-+ +-+ New storage node | 2048 | | // ^ | 2049 | | // | | 2050 | | // | 2051 | | // (0 or more existing children) | 2052 | | // | 2053 | | // | 2054 | | // | 2055 | | // If `future_parent` is `None`: | 2056 | | // | 2057 | | // | 2058 | | // New branch node +-+ | 2059 | | // (becomes root) +-+ <-------+ | 2060 | | // ^ | | 2061 | | // | | | 2062 | | // `existing_node_index` +-+ +-+ | 2063 | | // (current root) +-+ +-+ New storage node | 2064 | | // ^ | 2065 | | // | | 2066 | | // | 2067 | | // (0 or more existing children) | 2068 | | // | 2069 | | // | 2070 | | | 2071 | | // Find the common ancestor between `new_node_partial_key` and `existing_node_partial_key`. | 2072 | 147 | let branch_partial_key_len = { | 2073 | 147 | debug_assert_ne!(new_node_partial_key, &**existing_node_partial_key); | 2074 | 147 | let mut len = 0; | 2075 | 147 | let mut k1 = new_node_partial_key.iter(); | 2076 | 147 | let mut k2 = existing_node_partial_key.iter(); | 2077 | | // Since `new_node_partial_key` is different from `existing_node_partial_key`, we know | 2078 | | // that `k1.next()` and `k2.next()` won't both be `None`. | 2079 | 154 | while k1.next() == k2.next() { | 2080 | 7 | len += 1; | 2081 | 7 | } | 2082 | 147 | debug_assert!(len < new_node_partial_key.len()); | 2083 | 147 | debug_assert!(len < existing_node_partial_key.len()); | 2084 | 147 | len | 2085 | | }; | 2086 | | | 2087 | | // Table of children for the new branch node, not including the new storage node. | 2088 | | // It therefore contains only one entry: `existing_node_index`. | 2089 | 147 | let branch_children = { | 2090 | 147 | let mut branch_children = [None; 16]; | 2091 | 147 | let existing_node_new_child_index = existing_node_partial_key[branch_partial_key_len]; | 2092 | 147 | debug_assert_ne!( | 2093 | | existing_node_new_child_index, | 2094 | 147 | new_node_partial_key[branch_partial_key_len] | 2095 | | ); | 2096 | 147 | branch_children[usize::from(u8::from(existing_node_new_child_index))] = | 2097 | 147 | Some(existing_node_index); | 2098 | 147 | branch_children | 2099 | | }; | 2100 | | | 2101 | | // Success! | 2102 | | PrepareInsert::Two(PrepareInsertTwo { | 2103 | 147 | trie: self.trie, | 2104 | | | 2105 | 147 | storage_child_index: new_node_partial_key[branch_partial_key_len], | 2106 | 147 | storage_partial_key: new_node_partial_key[branch_partial_key_len + 1..].to_owned(), | 2107 | | | 2108 | 147 | branch_parent: if let Some((future_parent_index, future_parent_key_len)) = future_parent | 2109 | | { | 2110 | 147 | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2111 | 147 | Some((future_parent_index, new_child_index)) | 2112 | | } else { | 2113 | 0 | None | 2114 | | }, | 2115 | 147 | branch_partial_key: new_node_partial_key[..branch_partial_key_len].to_owned(), | 2116 | 147 | branch_children, | 2117 | | }) | 2118 | 5.04k | } |
_RNvMs7_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_6VacantuINtNtNtCs8Ty2CzGA6U3_5alloc3vec9into_iter8IntoIterNtNtB7_6nibble6NibbleEE20insert_storage_valueB9_ Line | Count | Source | 1889 | 740k | pub fn insert_storage_value(mut self) -> PrepareInsert<'a, TUd> { | 1890 | | // Retrieve what will be the parent after we insert the new node, not taking branching | 1891 | | // into account yet. | 1892 | | // If `Some`, contains its index and number of nibbles in its key. | 1893 | 740k | let future_parent734k = match (self.closest_ancestor, self.trie.root_index) { | 1894 | 0 | (Some(_), None) => unreachable!(), | 1895 | 725k | (Some(ancestor), Some(_)) => { | 1896 | | // TODO: could be optimized by passing in the Vacant the key remainder | 1897 | 725k | let key_len = self.trie.node_full_key(ancestor).count(); | 1898 | 725k | debug_assert!(self.key.clone().count() > key_len); | 1899 | 725k | Some((ancestor, key_len)) | 1900 | | } | 1901 | 8.45k | (None, Some(_)) => None, | 1902 | | (None, None) => { | 1903 | | // Situation where the trie is empty. This is kind of a special case that we | 1904 | | // handle by returning early. | 1905 | 6.17k | return PrepareInsert::One(PrepareInsertOne { | 1906 | 6.17k | trie: self.trie, | 1907 | 6.17k | parent: None, | 1908 | 6.17k | partial_key: self.key.collect(), | 1909 | 6.17k | children: [None; 16], | 1910 | 6.17k | }); | 1911 | | } | 1912 | | }; | 1913 | | | 1914 | | // Get the existing child of `future_parent` that points towards the newly-inserted node, | 1915 | | // or a successful early-return if none. | 1916 | 249k | let existing_node_index = | 1917 | 734k | if let Some((future_parent_index725k , future_parent_key_len725k )) = future_parent { | 1918 | 725k | let new_child_index = self.key.clone().nth(future_parent_key_len).unwrap(); | 1919 | 725k | let future_parent = self.trie.nodes.get(future_parent_index).unwrap(); | 1920 | 725k | match future_parent.children[usize::from(u8::from(new_child_index))] { | 1921 | 241k | Some(i) => { | 1922 | 241k | debug_assert_eq!( | 1923 | 241k | self.trie.nodes.get(i).unwrap().parent.unwrap().0, | 1924 | | future_parent_index | 1925 | | ); | 1926 | 241k | i | 1927 | | } | 1928 | | None => { | 1929 | | // There is an empty slot in `future_parent` for our new node. | 1930 | | // | 1931 | | // | 1932 | | // `future_parent` | 1933 | | // +-+ | 1934 | | // +-> +-+ <---------+ | 1935 | | // | <----+ | | 1936 | | // | ^ | | | 1937 | | // +-+ | | | | 1938 | | // New node +-+ +-+-+ +-+ +-+ 0 or more existing children | 1939 | | // +-+ +-+ +-+ | 1940 | | // | 1941 | | // | 1942 | 484k | return PrepareInsert::One(PrepareInsertOne { | 1943 | 484k | trie: self.trie, | 1944 | 484k | parent: Some((future_parent_index, new_child_index)), | 1945 | 484k | partial_key: self.key.skip(future_parent_key_len + 1).collect(), | 1946 | 484k | children: [None; 16], | 1947 | 484k | }); | 1948 | | } | 1949 | | } | 1950 | | } else { | 1951 | 8.45k | self.trie.root_index.unwrap() | 1952 | | }; | 1953 | | | 1954 | | // `existing_node_idx` and the new node are known to either have the same parent and the | 1955 | | // same child index, or to both have no parent. Now let's compare their partial key. | 1956 | 249k | let existing_node_partial_key = &self | 1957 | 249k | .trie | 1958 | 249k | .nodes | 1959 | 249k | .get(existing_node_index) | 1960 | 249k | .unwrap() | 1961 | 249k | .partial_key; | 1962 | 249k | let new_node_partial_key = self | 1963 | 249k | .key | 1964 | 249k | .clone() | 1965 | 249k | .skip(future_parent.map_or(0, |(_, n)| n + 1)) | 1966 | 249k | .collect::<Vec<_>>(); | 1967 | 249k | debug_assert_ne!(*existing_node_partial_key, new_node_partial_key); | 1968 | 249k | debug_assert!(!new_node_partial_key.starts_with(existing_node_partial_key)); | 1969 | | | 1970 | | // If `existing_node_partial_key` starts with `new_node_partial_key`, then the new node | 1971 | | // will be inserted in-between the parent and the existing node. | 1972 | 249k | if existing_node_partial_key.starts_with(&new_node_partial_key) { | 1973 | | // The new node is to be inserted in-between `future_parent` and | 1974 | | // `existing_node_index`. | 1975 | | // | 1976 | | // If `future_parent` is `Some`: | 1977 | | // | 1978 | | // | 1979 | | // +-+ | 1980 | | // `future_parent` +-+ <---------+ | 1981 | | // ^ | | 1982 | | // | + | 1983 | | // +-+ (0 or more existing children) | 1984 | | // New node +-+ | 1985 | | // ^ | 1986 | | // | | 1987 | | // +-+ | 1988 | | // `existing_node_index` +-+ | 1989 | | // ^ | 1990 | | // | | 1991 | | // + | 1992 | | // (0 or more existing children) | 1993 | | // | 1994 | | // | 1995 | | // | 1996 | | // If `future_parent` is `None`: | 1997 | | // | 1998 | | // | 1999 | | // New node +-+ | 2000 | | // (becomes the root) +-+ | 2001 | | // ^ | 2002 | | // | | 2003 | | // `existing_node_index` +-+ | 2004 | | // (current root) +-+ | 2005 | | // ^ | 2006 | | // | | 2007 | | // + | 2008 | | // (0 or more existing children) | 2009 | | // | 2010 | | | 2011 | 86.1k | let mut new_node_children = [None; 16]; | 2012 | 86.1k | let existing_node_new_child_index = | 2013 | 86.1k | existing_node_partial_key[new_node_partial_key.len()]; | 2014 | 86.1k | new_node_children[usize::from(u8::from(existing_node_new_child_index))] = | 2015 | 86.1k | Some(existing_node_index); | 2016 | | | 2017 | | return PrepareInsert::One(PrepareInsertOne { | 2018 | 86.1k | trie: self.trie, | 2019 | 86.1k | parent: if let Some((future_parent_index85.8k , future_parent_key_len85.8k )) = future_parent { | 2020 | 85.8k | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2021 | 85.8k | Some((future_parent_index, new_child_index)) | 2022 | | } else { | 2023 | 301 | None | 2024 | | }, | 2025 | 86.1k | partial_key: new_node_partial_key, | 2026 | 86.1k | children: new_node_children, | 2027 | | }); | 2028 | 163k | } | 2029 | | | 2030 | | // If we reach here, we know that we will need to create a new branch node in addition to | 2031 | | // the new storage node. | 2032 | | // | 2033 | | // If `future_parent` is `Some`: | 2034 | | // | 2035 | | // | 2036 | | // `future_parent` | 2037 | | // | 2038 | | // +-+ | 2039 | | // +-+ <--------+ (0 or more existing children) | 2040 | | // ^ | 2041 | | // | | 2042 | | // New branch node +-+ | 2043 | | // +-+ <-------+ | 2044 | | // ^ | | 2045 | | // | | | 2046 | | // +-+ +-+ | 2047 | | // `existing_node_index` +-+ +-+ New storage node | 2048 | | // ^ | 2049 | | // | | 2050 | | // | 2051 | | // (0 or more existing children) | 2052 | | // | 2053 | | // | 2054 | | // | 2055 | | // If `future_parent` is `None`: | 2056 | | // | 2057 | | // | 2058 | | // New branch node +-+ | 2059 | | // (becomes root) +-+ <-------+ | 2060 | | // ^ | | 2061 | | // | | | 2062 | | // `existing_node_index` +-+ +-+ | 2063 | | // (current root) +-+ +-+ New storage node | 2064 | | // ^ | 2065 | | // | | 2066 | | // | 2067 | | // (0 or more existing children) | 2068 | | // | 2069 | | // | 2070 | | | 2071 | | // Find the common ancestor between `new_node_partial_key` and `existing_node_partial_key`. | 2072 | 163k | let branch_partial_key_len = { | 2073 | 163k | debug_assert_ne!(new_node_partial_key, &**existing_node_partial_key); | 2074 | 163k | let mut len = 0; | 2075 | 163k | let mut k1 = new_node_partial_key.iter(); | 2076 | 163k | let mut k2 = existing_node_partial_key.iter(); | 2077 | | // Since `new_node_partial_key` is different from `existing_node_partial_key`, we know | 2078 | | // that `k1.next()` and `k2.next()` won't both be `None`. | 2079 | 281k | while k1.next() == k2.next() { | 2080 | 117k | len += 1; | 2081 | 117k | } | 2082 | 163k | debug_assert!(len < new_node_partial_key.len()); | 2083 | 163k | debug_assert!(len < existing_node_partial_key.len()); | 2084 | 163k | len | 2085 | | }; | 2086 | | | 2087 | | // Table of children for the new branch node, not including the new storage node. | 2088 | | // It therefore contains only one entry: `existing_node_index`. | 2089 | 163k | let branch_children = { | 2090 | 163k | let mut branch_children = [None; 16]; | 2091 | 163k | let existing_node_new_child_index = existing_node_partial_key[branch_partial_key_len]; | 2092 | 163k | debug_assert_ne!( | 2093 | | existing_node_new_child_index, | 2094 | 163k | new_node_partial_key[branch_partial_key_len] | 2095 | | ); | 2096 | 163k | branch_children[usize::from(u8::from(existing_node_new_child_index))] = | 2097 | 163k | Some(existing_node_index); | 2098 | 163k | branch_children | 2099 | | }; | 2100 | | | 2101 | | // Success! | 2102 | | PrepareInsert::Two(PrepareInsertTwo { | 2103 | 163k | trie: self.trie, | 2104 | | | 2105 | 163k | storage_child_index: new_node_partial_key[branch_partial_key_len], | 2106 | 163k | storage_partial_key: new_node_partial_key[branch_partial_key_len + 1..].to_owned(), | 2107 | | | 2108 | 163k | branch_parent: if let Some((future_parent_index155k , future_parent_key_len155k )) = future_parent | 2109 | | { | 2110 | 155k | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2111 | 155k | Some((future_parent_index, new_child_index)) | 2112 | | } else { | 2113 | 8.15k | None | 2114 | | }, | 2115 | 163k | branch_partial_key: new_node_partial_key[..branch_partial_key_len].to_owned(), | 2116 | 163k | branch_children, | 2117 | | }) | 2118 | 740k | } |
_RNvMs7_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_6VacantuINtNtNtNtCs66KPHxksi63_4core4iter8adapters6cloned6ClonedINtNtNtB1d_5slice4iter4IterNtNtB7_6nibble6NibbleEEE20insert_storage_valueB9_ Line | Count | Source | 1889 | 30 | pub fn insert_storage_value(mut self) -> PrepareInsert<'a, TUd> { | 1890 | | // Retrieve what will be the parent after we insert the new node, not taking branching | 1891 | | // into account yet. | 1892 | | // If `Some`, contains its index and number of nibbles in its key. | 1893 | 30 | let future_parent19 = match (self.closest_ancestor, self.trie.root_index) { | 1894 | 0 | (Some(_), None) => unreachable!(), | 1895 | 14 | (Some(ancestor), Some(_)) => { | 1896 | | // TODO: could be optimized by passing in the Vacant the key remainder | 1897 | 14 | let key_len = self.trie.node_full_key(ancestor).count(); | 1898 | 14 | debug_assert!(self.key.clone().count() > key_len); | 1899 | 14 | Some((ancestor, key_len)) | 1900 | | } | 1901 | 5 | (None, Some(_)) => None, | 1902 | | (None, None) => { | 1903 | | // Situation where the trie is empty. This is kind of a special case that we | 1904 | | // handle by returning early. | 1905 | 11 | return PrepareInsert::One(PrepareInsertOne { | 1906 | 11 | trie: self.trie, | 1907 | 11 | parent: None, | 1908 | 11 | partial_key: self.key.collect(), | 1909 | 11 | children: [None; 16], | 1910 | 11 | }); | 1911 | | } | 1912 | | }; | 1913 | | | 1914 | | // Get the existing child of `future_parent` that points towards the newly-inserted node, | 1915 | | // or a successful early-return if none. | 1916 | 9 | let existing_node_index = | 1917 | 19 | if let Some((future_parent_index14 , future_parent_key_len14 )) = future_parent { | 1918 | 14 | let new_child_index = self.key.clone().nth(future_parent_key_len).unwrap(); | 1919 | 14 | let future_parent = self.trie.nodes.get(future_parent_index).unwrap(); | 1920 | 14 | match future_parent.children[usize::from(u8::from(new_child_index))] { | 1921 | 4 | Some(i) => { | 1922 | 4 | debug_assert_eq!( | 1923 | 4 | self.trie.nodes.get(i).unwrap().parent.unwrap().0, | 1924 | | future_parent_index | 1925 | | ); | 1926 | 4 | i | 1927 | | } | 1928 | | None => { | 1929 | | // There is an empty slot in `future_parent` for our new node. | 1930 | | // | 1931 | | // | 1932 | | // `future_parent` | 1933 | | // +-+ | 1934 | | // +-> +-+ <---------+ | 1935 | | // | <----+ | | 1936 | | // | ^ | | | 1937 | | // +-+ | | | | 1938 | | // New node +-+ +-+-+ +-+ +-+ 0 or more existing children | 1939 | | // +-+ +-+ +-+ | 1940 | | // | 1941 | | // | 1942 | 10 | return PrepareInsert::One(PrepareInsertOne { | 1943 | 10 | trie: self.trie, | 1944 | 10 | parent: Some((future_parent_index, new_child_index)), | 1945 | 10 | partial_key: self.key.skip(future_parent_key_len + 1).collect(), | 1946 | 10 | children: [None; 16], | 1947 | 10 | }); | 1948 | | } | 1949 | | } | 1950 | | } else { | 1951 | 5 | self.trie.root_index.unwrap() | 1952 | | }; | 1953 | | | 1954 | | // `existing_node_idx` and the new node are known to either have the same parent and the | 1955 | | // same child index, or to both have no parent. Now let's compare their partial key. | 1956 | 9 | let existing_node_partial_key = &self | 1957 | 9 | .trie | 1958 | 9 | .nodes | 1959 | 9 | .get(existing_node_index) | 1960 | 9 | .unwrap() | 1961 | 9 | .partial_key; | 1962 | 9 | let new_node_partial_key = self | 1963 | 9 | .key | 1964 | 9 | .clone() | 1965 | 9 | .skip(future_parent.map_or(0, |(_, n)| n + 1)) | 1966 | 9 | .collect::<Vec<_>>(); | 1967 | 9 | debug_assert_ne!(*existing_node_partial_key, new_node_partial_key); | 1968 | 9 | debug_assert!(!new_node_partial_key.starts_with(existing_node_partial_key)); | 1969 | | | 1970 | | // If `existing_node_partial_key` starts with `new_node_partial_key`, then the new node | 1971 | | // will be inserted in-between the parent and the existing node. | 1972 | 9 | if existing_node_partial_key.starts_with(&new_node_partial_key) { | 1973 | | // The new node is to be inserted in-between `future_parent` and | 1974 | | // `existing_node_index`. | 1975 | | // | 1976 | | // If `future_parent` is `Some`: | 1977 | | // | 1978 | | // | 1979 | | // +-+ | 1980 | | // `future_parent` +-+ <---------+ | 1981 | | // ^ | | 1982 | | // | + | 1983 | | // +-+ (0 or more existing children) | 1984 | | // New node +-+ | 1985 | | // ^ | 1986 | | // | | 1987 | | // +-+ | 1988 | | // `existing_node_index` +-+ | 1989 | | // ^ | 1990 | | // | | 1991 | | // + | 1992 | | // (0 or more existing children) | 1993 | | // | 1994 | | // | 1995 | | // | 1996 | | // If `future_parent` is `None`: | 1997 | | // | 1998 | | // | 1999 | | // New node +-+ | 2000 | | // (becomes the root) +-+ | 2001 | | // ^ | 2002 | | // | | 2003 | | // `existing_node_index` +-+ | 2004 | | // (current root) +-+ | 2005 | | // ^ | 2006 | | // | | 2007 | | // + | 2008 | | // (0 or more existing children) | 2009 | | // | 2010 | | | 2011 | 4 | let mut new_node_children = [None; 16]; | 2012 | 4 | let existing_node_new_child_index = | 2013 | 4 | existing_node_partial_key[new_node_partial_key.len()]; | 2014 | 4 | new_node_children[usize::from(u8::from(existing_node_new_child_index))] = | 2015 | 4 | Some(existing_node_index); | 2016 | | | 2017 | | return PrepareInsert::One(PrepareInsertOne { | 2018 | 4 | trie: self.trie, | 2019 | 4 | parent: if let Some((future_parent_index1 , future_parent_key_len1 )) = future_parent { | 2020 | 1 | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2021 | 1 | Some((future_parent_index, new_child_index)) | 2022 | | } else { | 2023 | 3 | None | 2024 | | }, | 2025 | 4 | partial_key: new_node_partial_key, | 2026 | 4 | children: new_node_children, | 2027 | | }); | 2028 | 5 | } | 2029 | | | 2030 | | // If we reach here, we know that we will need to create a new branch node in addition to | 2031 | | // the new storage node. | 2032 | | // | 2033 | | // If `future_parent` is `Some`: | 2034 | | // | 2035 | | // | 2036 | | // `future_parent` | 2037 | | // | 2038 | | // +-+ | 2039 | | // +-+ <--------+ (0 or more existing children) | 2040 | | // ^ | 2041 | | // | | 2042 | | // New branch node +-+ | 2043 | | // +-+ <-------+ | 2044 | | // ^ | | 2045 | | // | | | 2046 | | // +-+ +-+ | 2047 | | // `existing_node_index` +-+ +-+ New storage node | 2048 | | // ^ | 2049 | | // | | 2050 | | // | 2051 | | // (0 or more existing children) | 2052 | | // | 2053 | | // | 2054 | | // | 2055 | | // If `future_parent` is `None`: | 2056 | | // | 2057 | | // | 2058 | | // New branch node +-+ | 2059 | | // (becomes root) +-+ <-------+ | 2060 | | // ^ | | 2061 | | // | | | 2062 | | // `existing_node_index` +-+ +-+ | 2063 | | // (current root) +-+ +-+ New storage node | 2064 | | // ^ | 2065 | | // | | 2066 | | // | 2067 | | // (0 or more existing children) | 2068 | | // | 2069 | | // | 2070 | | | 2071 | | // Find the common ancestor between `new_node_partial_key` and `existing_node_partial_key`. | 2072 | 5 | let branch_partial_key_len = { | 2073 | 5 | debug_assert_ne!(new_node_partial_key, &**existing_node_partial_key); | 2074 | 5 | let mut len = 0; | 2075 | 5 | let mut k1 = new_node_partial_key.iter(); | 2076 | 5 | let mut k2 = existing_node_partial_key.iter(); | 2077 | | // Since `new_node_partial_key` is different from `existing_node_partial_key`, we know | 2078 | | // that `k1.next()` and `k2.next()` won't both be `None`. | 2079 | 11 | while k1.next() == k2.next() { | 2080 | 6 | len += 1; | 2081 | 6 | } | 2082 | 5 | debug_assert!(len < new_node_partial_key.len()); | 2083 | 5 | debug_assert!(len < existing_node_partial_key.len()); | 2084 | 5 | len | 2085 | | }; | 2086 | | | 2087 | | // Table of children for the new branch node, not including the new storage node. | 2088 | | // It therefore contains only one entry: `existing_node_index`. | 2089 | 5 | let branch_children = { | 2090 | 5 | let mut branch_children = [None; 16]; | 2091 | 5 | let existing_node_new_child_index = existing_node_partial_key[branch_partial_key_len]; | 2092 | 5 | debug_assert_ne!( | 2093 | | existing_node_new_child_index, | 2094 | 5 | new_node_partial_key[branch_partial_key_len] | 2095 | | ); | 2096 | 5 | branch_children[usize::from(u8::from(existing_node_new_child_index))] = | 2097 | 5 | Some(existing_node_index); | 2098 | 5 | branch_children | 2099 | | }; | 2100 | | | 2101 | | // Success! | 2102 | | PrepareInsert::Two(PrepareInsertTwo { | 2103 | 5 | trie: self.trie, | 2104 | | | 2105 | 5 | storage_child_index: new_node_partial_key[branch_partial_key_len], | 2106 | 5 | storage_partial_key: new_node_partial_key[branch_partial_key_len + 1..].to_owned(), | 2107 | | | 2108 | 5 | branch_parent: if let Some((future_parent_index3 , future_parent_key_len3 )) = future_parent | 2109 | | { | 2110 | 3 | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2111 | 3 | Some((future_parent_index, new_child_index)) | 2112 | | } else { | 2113 | 2 | None | 2114 | | }, | 2115 | 5 | branch_partial_key: new_node_partial_key[..branch_partial_key_len].to_owned(), | 2116 | 5 | branch_children, | 2117 | | }) | 2118 | 30 | } |
_RNvMs7_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_6VacantuINtNtNtNtCs66KPHxksi63_4core4iter8adapters6copied6CopiedINtNtNtB1d_5slice4iter4IterNtNtB7_6nibble6NibbleEEE20insert_storage_valueB9_ Line | Count | Source | 1889 | 241k | pub fn insert_storage_value(mut self) -> PrepareInsert<'a, TUd> { | 1890 | | // Retrieve what will be the parent after we insert the new node, not taking branching | 1891 | | // into account yet. | 1892 | | // If `Some`, contains its index and number of nibbles in its key. | 1893 | 241k | let future_parent237k = match (self.closest_ancestor, self.trie.root_index) { | 1894 | 0 | (Some(_), None) => unreachable!(), | 1895 | 237k | (Some(ancestor), Some(_)) => { | 1896 | | // TODO: could be optimized by passing in the Vacant the key remainder | 1897 | 237k | let key_len = self.trie.node_full_key(ancestor).count(); | 1898 | 237k | debug_assert!(self.key.clone().count() > key_len); | 1899 | 237k | Some((ancestor, key_len)) | 1900 | | } | 1901 | 601 | (None, Some(_)) => None, | 1902 | | (None, None) => { | 1903 | | // Situation where the trie is empty. This is kind of a special case that we | 1904 | | // handle by returning early. | 1905 | 4.09k | return PrepareInsert::One(PrepareInsertOne { | 1906 | 4.09k | trie: self.trie, | 1907 | 4.09k | parent: None, | 1908 | 4.09k | partial_key: self.key.collect(), | 1909 | 4.09k | children: [None; 16], | 1910 | 4.09k | }); | 1911 | | } | 1912 | | }; | 1913 | | | 1914 | | // Get the existing child of `future_parent` that points towards the newly-inserted node, | 1915 | | // or a successful early-return if none. | 1916 | 13.5k | let existing_node_index = | 1917 | 237k | if let Some((future_parent_index237k , future_parent_key_len237k )) = future_parent { | 1918 | 237k | let new_child_index = self.key.clone().nth(future_parent_key_len).unwrap(); | 1919 | 237k | let future_parent = self.trie.nodes.get(future_parent_index).unwrap(); | 1920 | 237k | match future_parent.children[usize::from(u8::from(new_child_index))] { | 1921 | 12.9k | Some(i) => { | 1922 | 12.9k | debug_assert_eq!( | 1923 | 12.9k | self.trie.nodes.get(i).unwrap().parent.unwrap().0, | 1924 | | future_parent_index | 1925 | | ); | 1926 | 12.9k | i | 1927 | | } | 1928 | | None => { | 1929 | | // There is an empty slot in `future_parent` for our new node. | 1930 | | // | 1931 | | // | 1932 | | // `future_parent` | 1933 | | // +-+ | 1934 | | // +-> +-+ <---------+ | 1935 | | // | <----+ | | 1936 | | // | ^ | | | 1937 | | // +-+ | | | | 1938 | | // New node +-+ +-+-+ +-+ +-+ 0 or more existing children | 1939 | | // +-+ +-+ +-+ | 1940 | | // | 1941 | | // | 1942 | 224k | return PrepareInsert::One(PrepareInsertOne { | 1943 | 224k | trie: self.trie, | 1944 | 224k | parent: Some((future_parent_index, new_child_index)), | 1945 | 224k | partial_key: self.key.skip(future_parent_key_len + 1).collect(), | 1946 | 224k | children: [None; 16], | 1947 | 224k | }); | 1948 | | } | 1949 | | } | 1950 | | } else { | 1951 | 601 | self.trie.root_index.unwrap() | 1952 | | }; | 1953 | | | 1954 | | // `existing_node_idx` and the new node are known to either have the same parent and the | 1955 | | // same child index, or to both have no parent. Now let's compare their partial key. | 1956 | 13.5k | let existing_node_partial_key = &self | 1957 | 13.5k | .trie | 1958 | 13.5k | .nodes | 1959 | 13.5k | .get(existing_node_index) | 1960 | 13.5k | .unwrap() | 1961 | 13.5k | .partial_key; | 1962 | 13.5k | let new_node_partial_key = self | 1963 | 13.5k | .key | 1964 | 13.5k | .clone() | 1965 | 13.5k | .skip(future_parent.map_or(0, |(_, n)| n + 1)) | 1966 | 13.5k | .collect::<Vec<_>>(); | 1967 | 13.5k | debug_assert_ne!(*existing_node_partial_key, new_node_partial_key); | 1968 | 13.5k | debug_assert!(!new_node_partial_key.starts_with(existing_node_partial_key)); | 1969 | | | 1970 | | // If `existing_node_partial_key` starts with `new_node_partial_key`, then the new node | 1971 | | // will be inserted in-between the parent and the existing node. | 1972 | 13.5k | if existing_node_partial_key.starts_with(&new_node_partial_key) { | 1973 | | // The new node is to be inserted in-between `future_parent` and | 1974 | | // `existing_node_index`. | 1975 | | // | 1976 | | // If `future_parent` is `Some`: | 1977 | | // | 1978 | | // | 1979 | | // +-+ | 1980 | | // `future_parent` +-+ <---------+ | 1981 | | // ^ | | 1982 | | // | + | 1983 | | // +-+ (0 or more existing children) | 1984 | | // New node +-+ | 1985 | | // ^ | 1986 | | // | | 1987 | | // +-+ | 1988 | | // `existing_node_index` +-+ | 1989 | | // ^ | 1990 | | // | | 1991 | | // + | 1992 | | // (0 or more existing children) | 1993 | | // | 1994 | | // | 1995 | | // | 1996 | | // If `future_parent` is `None`: | 1997 | | // | 1998 | | // | 1999 | | // New node +-+ | 2000 | | // (becomes the root) +-+ | 2001 | | // ^ | 2002 | | // | | 2003 | | // `existing_node_index` +-+ | 2004 | | // (current root) +-+ | 2005 | | // ^ | 2006 | | // | | 2007 | | // + | 2008 | | // (0 or more existing children) | 2009 | | // | 2010 | | | 2011 | 0 | let mut new_node_children = [None; 16]; | 2012 | 0 | let existing_node_new_child_index = | 2013 | 0 | existing_node_partial_key[new_node_partial_key.len()]; | 2014 | 0 | new_node_children[usize::from(u8::from(existing_node_new_child_index))] = | 2015 | 0 | Some(existing_node_index); | 2016 | | | 2017 | | return PrepareInsert::One(PrepareInsertOne { | 2018 | 0 | trie: self.trie, | 2019 | 0 | parent: if let Some((future_parent_index, future_parent_key_len)) = future_parent { | 2020 | 0 | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2021 | 0 | Some((future_parent_index, new_child_index)) | 2022 | | } else { | 2023 | 0 | None | 2024 | | }, | 2025 | 0 | partial_key: new_node_partial_key, | 2026 | 0 | children: new_node_children, | 2027 | | }); | 2028 | 13.5k | } | 2029 | | | 2030 | | // If we reach here, we know that we will need to create a new branch node in addition to | 2031 | | // the new storage node. | 2032 | | // | 2033 | | // If `future_parent` is `Some`: | 2034 | | // | 2035 | | // | 2036 | | // `future_parent` | 2037 | | // | 2038 | | // +-+ | 2039 | | // +-+ <--------+ (0 or more existing children) | 2040 | | // ^ | 2041 | | // | | 2042 | | // New branch node +-+ | 2043 | | // +-+ <-------+ | 2044 | | // ^ | | 2045 | | // | | | 2046 | | // +-+ +-+ | 2047 | | // `existing_node_index` +-+ +-+ New storage node | 2048 | | // ^ | 2049 | | // | | 2050 | | // | 2051 | | // (0 or more existing children) | 2052 | | // | 2053 | | // | 2054 | | // | 2055 | | // If `future_parent` is `None`: | 2056 | | // | 2057 | | // | 2058 | | // New branch node +-+ | 2059 | | // (becomes root) +-+ <-------+ | 2060 | | // ^ | | 2061 | | // | | | 2062 | | // `existing_node_index` +-+ +-+ | 2063 | | // (current root) +-+ +-+ New storage node | 2064 | | // ^ | 2065 | | // | | 2066 | | // | 2067 | | // (0 or more existing children) | 2068 | | // | 2069 | | // | 2070 | | | 2071 | | // Find the common ancestor between `new_node_partial_key` and `existing_node_partial_key`. | 2072 | 13.5k | let branch_partial_key_len = { | 2073 | 13.5k | debug_assert_ne!(new_node_partial_key, &**existing_node_partial_key); | 2074 | 13.5k | let mut len = 0; | 2075 | 13.5k | let mut k1 = new_node_partial_key.iter(); | 2076 | 13.5k | let mut k2 = existing_node_partial_key.iter(); | 2077 | | // Since `new_node_partial_key` is different from `existing_node_partial_key`, we know | 2078 | | // that `k1.next()` and `k2.next()` won't both be `None`. | 2079 | 13.7k | while k1.next() == k2.next() { | 2080 | 266 | len += 1; | 2081 | 266 | } | 2082 | 13.5k | debug_assert!(len < new_node_partial_key.len()); | 2083 | 13.5k | debug_assert!(len < existing_node_partial_key.len()); | 2084 | 13.5k | len | 2085 | | }; | 2086 | | | 2087 | | // Table of children for the new branch node, not including the new storage node. | 2088 | | // It therefore contains only one entry: `existing_node_index`. | 2089 | 13.5k | let branch_children = { | 2090 | 13.5k | let mut branch_children = [None; 16]; | 2091 | 13.5k | let existing_node_new_child_index = existing_node_partial_key[branch_partial_key_len]; | 2092 | 13.5k | debug_assert_ne!( | 2093 | | existing_node_new_child_index, | 2094 | 13.5k | new_node_partial_key[branch_partial_key_len] | 2095 | | ); | 2096 | 13.5k | branch_children[usize::from(u8::from(existing_node_new_child_index))] = | 2097 | 13.5k | Some(existing_node_index); | 2098 | 13.5k | branch_children | 2099 | | }; | 2100 | | | 2101 | | // Success! | 2102 | | PrepareInsert::Two(PrepareInsertTwo { | 2103 | 13.5k | trie: self.trie, | 2104 | | | 2105 | 13.5k | storage_child_index: new_node_partial_key[branch_partial_key_len], | 2106 | 13.5k | storage_partial_key: new_node_partial_key[branch_partial_key_len + 1..].to_owned(), | 2107 | | | 2108 | 13.5k | branch_parent: if let Some((future_parent_index12.9k , future_parent_key_len12.9k )) = future_parent | 2109 | | { | 2110 | 12.9k | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2111 | 12.9k | Some((future_parent_index, new_child_index)) | 2112 | | } else { | 2113 | 601 | None | 2114 | | }, | 2115 | 13.5k | branch_partial_key: new_node_partial_key[..branch_partial_key_len].to_owned(), | 2116 | 13.5k | branch_children, | 2117 | | }) | 2118 | 241k | } |
Unexecuted instantiation: _RNvMs7_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_6VacantTINtNtCs66KPHxksi63_4core6option6OptionRShEIB15_NtNtB7_9trie_node17MerkleValueOutputEEINtNtB7_6nibble14BytesToNibblesINtNtNtNtB19_4iter8adapters6copied6CopiedINtNtNtB19_5slice4iter4IterhEEEE20insert_storage_valueCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs7_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_6VacantINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEINtNtNtNtB18_4iter8adapters6copied6CopiedINtNtNtB18_5slice4iter4IterNtNtB7_6nibble6NibbleEEE20insert_storage_valueB9_ _RNvMs7_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_6VacantTINtNtCs66KPHxksi63_4core6option6OptionRShEIB15_NtNtB7_9trie_node17MerkleValueOutputEEINtNtB7_6nibble14BytesToNibblesINtNtNtNtB19_4iter8adapters6copied6CopiedINtNtNtB19_5slice4iter4IterhEEEE20insert_storage_valueCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 1889 | 70 | pub fn insert_storage_value(mut self) -> PrepareInsert<'a, TUd> { | 1890 | | // Retrieve what will be the parent after we insert the new node, not taking branching | 1891 | | // into account yet. | 1892 | | // If `Some`, contains its index and number of nibbles in its key. | 1893 | 70 | let future_parent68 = match (self.closest_ancestor, self.trie.root_index) { | 1894 | 0 | (Some(_), None) => unreachable!(), | 1895 | 66 | (Some(ancestor), Some(_)) => { | 1896 | | // TODO: could be optimized by passing in the Vacant the key remainder | 1897 | 66 | let key_len = self.trie.node_full_key(ancestor).count(); | 1898 | 66 | debug_assert!(self.key.clone().count() > key_len); | 1899 | 66 | Some((ancestor, key_len)) | 1900 | | } | 1901 | 2 | (None, Some(_)) => None, | 1902 | | (None, None) => { | 1903 | | // Situation where the trie is empty. This is kind of a special case that we | 1904 | | // handle by returning early. | 1905 | 2 | return PrepareInsert::One(PrepareInsertOne { | 1906 | 2 | trie: self.trie, | 1907 | 2 | parent: None, | 1908 | 2 | partial_key: self.key.collect(), | 1909 | 2 | children: [None; 16], | 1910 | 2 | }); | 1911 | | } | 1912 | | }; | 1913 | | | 1914 | | // Get the existing child of `future_parent` that points towards the newly-inserted node, | 1915 | | // or a successful early-return if none. | 1916 | 26 | let existing_node_index = | 1917 | 68 | if let Some((future_parent_index66 , future_parent_key_len66 )) = future_parent { | 1918 | 66 | let new_child_index = self.key.clone().nth(future_parent_key_len).unwrap(); | 1919 | 66 | let future_parent = self.trie.nodes.get(future_parent_index).unwrap(); | 1920 | 66 | match future_parent.children[usize::from(u8::from(new_child_index))] { | 1921 | 24 | Some(i) => { | 1922 | 24 | debug_assert_eq!( | 1923 | 24 | self.trie.nodes.get(i).unwrap().parent.unwrap().0, | 1924 | | future_parent_index | 1925 | | ); | 1926 | 24 | i | 1927 | | } | 1928 | | None => { | 1929 | | // There is an empty slot in `future_parent` for our new node. | 1930 | | // | 1931 | | // | 1932 | | // `future_parent` | 1933 | | // +-+ | 1934 | | // +-> +-+ <---------+ | 1935 | | // | <----+ | | 1936 | | // | ^ | | | 1937 | | // +-+ | | | | 1938 | | // New node +-+ +-+-+ +-+ +-+ 0 or more existing children | 1939 | | // +-+ +-+ +-+ | 1940 | | // | 1941 | | // | 1942 | 42 | return PrepareInsert::One(PrepareInsertOne { | 1943 | 42 | trie: self.trie, | 1944 | 42 | parent: Some((future_parent_index, new_child_index)), | 1945 | 42 | partial_key: self.key.skip(future_parent_key_len + 1).collect(), | 1946 | 42 | children: [None; 16], | 1947 | 42 | }); | 1948 | | } | 1949 | | } | 1950 | | } else { | 1951 | 2 | self.trie.root_index.unwrap() | 1952 | | }; | 1953 | | | 1954 | | // `existing_node_idx` and the new node are known to either have the same parent and the | 1955 | | // same child index, or to both have no parent. Now let's compare their partial key. | 1956 | 26 | let existing_node_partial_key = &self | 1957 | 26 | .trie | 1958 | 26 | .nodes | 1959 | 26 | .get(existing_node_index) | 1960 | 26 | .unwrap() | 1961 | 26 | .partial_key; | 1962 | 26 | let new_node_partial_key = self | 1963 | 26 | .key | 1964 | 26 | .clone() | 1965 | 26 | .skip(future_parent.map_or(0, |(_, n)| n + 1)) | 1966 | 26 | .collect::<Vec<_>>(); | 1967 | 26 | debug_assert_ne!(*existing_node_partial_key, new_node_partial_key); | 1968 | 26 | debug_assert!(!new_node_partial_key.starts_with(existing_node_partial_key)); | 1969 | | | 1970 | | // If `existing_node_partial_key` starts with `new_node_partial_key`, then the new node | 1971 | | // will be inserted in-between the parent and the existing node. | 1972 | 26 | if existing_node_partial_key.starts_with(&new_node_partial_key) { | 1973 | | // The new node is to be inserted in-between `future_parent` and | 1974 | | // `existing_node_index`. | 1975 | | // | 1976 | | // If `future_parent` is `Some`: | 1977 | | // | 1978 | | // | 1979 | | // +-+ | 1980 | | // `future_parent` +-+ <---------+ | 1981 | | // ^ | | 1982 | | // | + | 1983 | | // +-+ (0 or more existing children) | 1984 | | // New node +-+ | 1985 | | // ^ | 1986 | | // | | 1987 | | // +-+ | 1988 | | // `existing_node_index` +-+ | 1989 | | // ^ | 1990 | | // | | 1991 | | // + | 1992 | | // (0 or more existing children) | 1993 | | // | 1994 | | // | 1995 | | // | 1996 | | // If `future_parent` is `None`: | 1997 | | // | 1998 | | // | 1999 | | // New node +-+ | 2000 | | // (becomes the root) +-+ | 2001 | | // ^ | 2002 | | // | | 2003 | | // `existing_node_index` +-+ | 2004 | | // (current root) +-+ | 2005 | | // ^ | 2006 | | // | | 2007 | | // + | 2008 | | // (0 or more existing children) | 2009 | | // | 2010 | | | 2011 | 0 | let mut new_node_children = [None; 16]; | 2012 | 0 | let existing_node_new_child_index = | 2013 | 0 | existing_node_partial_key[new_node_partial_key.len()]; | 2014 | 0 | new_node_children[usize::from(u8::from(existing_node_new_child_index))] = | 2015 | 0 | Some(existing_node_index); | 2016 | | | 2017 | | return PrepareInsert::One(PrepareInsertOne { | 2018 | 0 | trie: self.trie, | 2019 | 0 | parent: if let Some((future_parent_index, future_parent_key_len)) = future_parent { | 2020 | 0 | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2021 | 0 | Some((future_parent_index, new_child_index)) | 2022 | | } else { | 2023 | 0 | None | 2024 | | }, | 2025 | 0 | partial_key: new_node_partial_key, | 2026 | 0 | children: new_node_children, | 2027 | | }); | 2028 | 26 | } | 2029 | | | 2030 | | // If we reach here, we know that we will need to create a new branch node in addition to | 2031 | | // the new storage node. | 2032 | | // | 2033 | | // If `future_parent` is `Some`: | 2034 | | // | 2035 | | // | 2036 | | // `future_parent` | 2037 | | // | 2038 | | // +-+ | 2039 | | // +-+ <--------+ (0 or more existing children) | 2040 | | // ^ | 2041 | | // | | 2042 | | // New branch node +-+ | 2043 | | // +-+ <-------+ | 2044 | | // ^ | | 2045 | | // | | | 2046 | | // +-+ +-+ | 2047 | | // `existing_node_index` +-+ +-+ New storage node | 2048 | | // ^ | 2049 | | // | | 2050 | | // | 2051 | | // (0 or more existing children) | 2052 | | // | 2053 | | // | 2054 | | // | 2055 | | // If `future_parent` is `None`: | 2056 | | // | 2057 | | // | 2058 | | // New branch node +-+ | 2059 | | // (becomes root) +-+ <-------+ | 2060 | | // ^ | | 2061 | | // | | | 2062 | | // `existing_node_index` +-+ +-+ | 2063 | | // (current root) +-+ +-+ New storage node | 2064 | | // ^ | 2065 | | // | | 2066 | | // | 2067 | | // (0 or more existing children) | 2068 | | // | 2069 | | // | 2070 | | | 2071 | | // Find the common ancestor between `new_node_partial_key` and `existing_node_partial_key`. | 2072 | 26 | let branch_partial_key_len = { | 2073 | 26 | debug_assert_ne!(new_node_partial_key, &**existing_node_partial_key); | 2074 | 26 | let mut len = 0; | 2075 | 26 | let mut k1 = new_node_partial_key.iter(); | 2076 | 26 | let mut k2 = existing_node_partial_key.iter(); | 2077 | | // Since `new_node_partial_key` is different from `existing_node_partial_key`, we know | 2078 | | // that `k1.next()` and `k2.next()` won't both be `None`. | 2079 | 398 | while k1.next() == k2.next() { | 2080 | 372 | len += 1; | 2081 | 372 | } | 2082 | 26 | debug_assert!(len < new_node_partial_key.len()); | 2083 | 26 | debug_assert!(len < existing_node_partial_key.len()); | 2084 | 26 | len | 2085 | | }; | 2086 | | | 2087 | | // Table of children for the new branch node, not including the new storage node. | 2088 | | // It therefore contains only one entry: `existing_node_index`. | 2089 | 26 | let branch_children = { | 2090 | 26 | let mut branch_children = [None; 16]; | 2091 | 26 | let existing_node_new_child_index = existing_node_partial_key[branch_partial_key_len]; | 2092 | 26 | debug_assert_ne!( | 2093 | | existing_node_new_child_index, | 2094 | 26 | new_node_partial_key[branch_partial_key_len] | 2095 | | ); | 2096 | 26 | branch_children[usize::from(u8::from(existing_node_new_child_index))] = | 2097 | 26 | Some(existing_node_index); | 2098 | 26 | branch_children | 2099 | | }; | 2100 | | | 2101 | | // Success! | 2102 | | PrepareInsert::Two(PrepareInsertTwo { | 2103 | 26 | trie: self.trie, | 2104 | | | 2105 | 26 | storage_child_index: new_node_partial_key[branch_partial_key_len], | 2106 | 26 | storage_partial_key: new_node_partial_key[branch_partial_key_len + 1..].to_owned(), | 2107 | | | 2108 | 26 | branch_parent: if let Some((future_parent_index24 , future_parent_key_len24 )) = future_parent | 2109 | | { | 2110 | 24 | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2111 | 24 | Some((future_parent_index, new_child_index)) | 2112 | | } else { | 2113 | 2 | None | 2114 | | }, | 2115 | 26 | branch_partial_key: new_node_partial_key[..branch_partial_key_len].to_owned(), | 2116 | 26 | branch_children, | 2117 | | }) | 2118 | 70 | } |
_RNvMs7_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_6VacantTINtNtCs66KPHxksi63_4core6option6OptionRShEIB15_NtNtB7_9trie_node17MerkleValueOutputEEINtNtB7_6nibble14BytesToNibblesINtNtNtNtB19_4iter8adapters6copied6CopiedINtNtNtB19_5slice4iter4IterhEEEE20insert_storage_valueCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 1889 | 665 | pub fn insert_storage_value(mut self) -> PrepareInsert<'a, TUd> { | 1890 | | // Retrieve what will be the parent after we insert the new node, not taking branching | 1891 | | // into account yet. | 1892 | | // If `Some`, contains its index and number of nibbles in its key. | 1893 | 665 | let future_parent646 = match (self.closest_ancestor, self.trie.root_index) { | 1894 | 0 | (Some(_), None) => unreachable!(), | 1895 | 627 | (Some(ancestor), Some(_)) => { | 1896 | | // TODO: could be optimized by passing in the Vacant the key remainder | 1897 | 627 | let key_len = self.trie.node_full_key(ancestor).count(); | 1898 | 627 | debug_assert!(self.key.clone().count() > key_len); | 1899 | 627 | Some((ancestor, key_len)) | 1900 | | } | 1901 | 19 | (None, Some(_)) => None, | 1902 | | (None, None) => { | 1903 | | // Situation where the trie is empty. This is kind of a special case that we | 1904 | | // handle by returning early. | 1905 | 19 | return PrepareInsert::One(PrepareInsertOne { | 1906 | 19 | trie: self.trie, | 1907 | 19 | parent: None, | 1908 | 19 | partial_key: self.key.collect(), | 1909 | 19 | children: [None; 16], | 1910 | 19 | }); | 1911 | | } | 1912 | | }; | 1913 | | | 1914 | | // Get the existing child of `future_parent` that points towards the newly-inserted node, | 1915 | | // or a successful early-return if none. | 1916 | 247 | let existing_node_index = | 1917 | 646 | if let Some((future_parent_index627 , future_parent_key_len627 )) = future_parent { | 1918 | 627 | let new_child_index = self.key.clone().nth(future_parent_key_len).unwrap(); | 1919 | 627 | let future_parent = self.trie.nodes.get(future_parent_index).unwrap(); | 1920 | 627 | match future_parent.children[usize::from(u8::from(new_child_index))] { | 1921 | 228 | Some(i) => { | 1922 | 228 | debug_assert_eq!( | 1923 | 228 | self.trie.nodes.get(i).unwrap().parent.unwrap().0, | 1924 | | future_parent_index | 1925 | | ); | 1926 | 228 | i | 1927 | | } | 1928 | | None => { | 1929 | | // There is an empty slot in `future_parent` for our new node. | 1930 | | // | 1931 | | // | 1932 | | // `future_parent` | 1933 | | // +-+ | 1934 | | // +-> +-+ <---------+ | 1935 | | // | <----+ | | 1936 | | // | ^ | | | 1937 | | // +-+ | | | | 1938 | | // New node +-+ +-+-+ +-+ +-+ 0 or more existing children | 1939 | | // +-+ +-+ +-+ | 1940 | | // | 1941 | | // | 1942 | 399 | return PrepareInsert::One(PrepareInsertOne { | 1943 | 399 | trie: self.trie, | 1944 | 399 | parent: Some((future_parent_index, new_child_index)), | 1945 | 399 | partial_key: self.key.skip(future_parent_key_len + 1).collect(), | 1946 | 399 | children: [None; 16], | 1947 | 399 | }); | 1948 | | } | 1949 | | } | 1950 | | } else { | 1951 | 19 | self.trie.root_index.unwrap() | 1952 | | }; | 1953 | | | 1954 | | // `existing_node_idx` and the new node are known to either have the same parent and the | 1955 | | // same child index, or to both have no parent. Now let's compare their partial key. | 1956 | 247 | let existing_node_partial_key = &self | 1957 | 247 | .trie | 1958 | 247 | .nodes | 1959 | 247 | .get(existing_node_index) | 1960 | 247 | .unwrap() | 1961 | 247 | .partial_key; | 1962 | 247 | let new_node_partial_key = self | 1963 | 247 | .key | 1964 | 247 | .clone() | 1965 | 247 | .skip(future_parent.map_or(0, |(_, n)| n + 1)) | 1966 | 247 | .collect::<Vec<_>>(); | 1967 | 247 | debug_assert_ne!(*existing_node_partial_key, new_node_partial_key); | 1968 | 247 | debug_assert!(!new_node_partial_key.starts_with(existing_node_partial_key)); | 1969 | | | 1970 | | // If `existing_node_partial_key` starts with `new_node_partial_key`, then the new node | 1971 | | // will be inserted in-between the parent and the existing node. | 1972 | 247 | if existing_node_partial_key.starts_with(&new_node_partial_key) { | 1973 | | // The new node is to be inserted in-between `future_parent` and | 1974 | | // `existing_node_index`. | 1975 | | // | 1976 | | // If `future_parent` is `Some`: | 1977 | | // | 1978 | | // | 1979 | | // +-+ | 1980 | | // `future_parent` +-+ <---------+ | 1981 | | // ^ | | 1982 | | // | + | 1983 | | // +-+ (0 or more existing children) | 1984 | | // New node +-+ | 1985 | | // ^ | 1986 | | // | | 1987 | | // +-+ | 1988 | | // `existing_node_index` +-+ | 1989 | | // ^ | 1990 | | // | | 1991 | | // + | 1992 | | // (0 or more existing children) | 1993 | | // | 1994 | | // | 1995 | | // | 1996 | | // If `future_parent` is `None`: | 1997 | | // | 1998 | | // | 1999 | | // New node +-+ | 2000 | | // (becomes the root) +-+ | 2001 | | // ^ | 2002 | | // | | 2003 | | // `existing_node_index` +-+ | 2004 | | // (current root) +-+ | 2005 | | // ^ | 2006 | | // | | 2007 | | // + | 2008 | | // (0 or more existing children) | 2009 | | // | 2010 | | | 2011 | 0 | let mut new_node_children = [None; 16]; | 2012 | 0 | let existing_node_new_child_index = | 2013 | 0 | existing_node_partial_key[new_node_partial_key.len()]; | 2014 | 0 | new_node_children[usize::from(u8::from(existing_node_new_child_index))] = | 2015 | 0 | Some(existing_node_index); | 2016 | | | 2017 | | return PrepareInsert::One(PrepareInsertOne { | 2018 | 0 | trie: self.trie, | 2019 | 0 | parent: if let Some((future_parent_index, future_parent_key_len)) = future_parent { | 2020 | 0 | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2021 | 0 | Some((future_parent_index, new_child_index)) | 2022 | | } else { | 2023 | 0 | None | 2024 | | }, | 2025 | 0 | partial_key: new_node_partial_key, | 2026 | 0 | children: new_node_children, | 2027 | | }); | 2028 | 247 | } | 2029 | | | 2030 | | // If we reach here, we know that we will need to create a new branch node in addition to | 2031 | | // the new storage node. | 2032 | | // | 2033 | | // If `future_parent` is `Some`: | 2034 | | // | 2035 | | // | 2036 | | // `future_parent` | 2037 | | // | 2038 | | // +-+ | 2039 | | // +-+ <--------+ (0 or more existing children) | 2040 | | // ^ | 2041 | | // | | 2042 | | // New branch node +-+ | 2043 | | // +-+ <-------+ | 2044 | | // ^ | | 2045 | | // | | | 2046 | | // +-+ +-+ | 2047 | | // `existing_node_index` +-+ +-+ New storage node | 2048 | | // ^ | 2049 | | // | | 2050 | | // | 2051 | | // (0 or more existing children) | 2052 | | // | 2053 | | // | 2054 | | // | 2055 | | // If `future_parent` is `None`: | 2056 | | // | 2057 | | // | 2058 | | // New branch node +-+ | 2059 | | // (becomes root) +-+ <-------+ | 2060 | | // ^ | | 2061 | | // | | | 2062 | | // `existing_node_index` +-+ +-+ | 2063 | | // (current root) +-+ +-+ New storage node | 2064 | | // ^ | 2065 | | // | | 2066 | | // | 2067 | | // (0 or more existing children) | 2068 | | // | 2069 | | // | 2070 | | | 2071 | | // Find the common ancestor between `new_node_partial_key` and `existing_node_partial_key`. | 2072 | 247 | let branch_partial_key_len = { | 2073 | 247 | debug_assert_ne!(new_node_partial_key, &**existing_node_partial_key); | 2074 | 247 | let mut len = 0; | 2075 | 247 | let mut k1 = new_node_partial_key.iter(); | 2076 | 247 | let mut k2 = existing_node_partial_key.iter(); | 2077 | | // Since `new_node_partial_key` is different from `existing_node_partial_key`, we know | 2078 | | // that `k1.next()` and `k2.next()` won't both be `None`. | 2079 | 3.78k | while k1.next() == k2.next() { | 2080 | 3.53k | len += 1; | 2081 | 3.53k | } | 2082 | 247 | debug_assert!(len < new_node_partial_key.len()); | 2083 | 247 | debug_assert!(len < existing_node_partial_key.len()); | 2084 | 247 | len | 2085 | | }; | 2086 | | | 2087 | | // Table of children for the new branch node, not including the new storage node. | 2088 | | // It therefore contains only one entry: `existing_node_index`. | 2089 | 247 | let branch_children = { | 2090 | 247 | let mut branch_children = [None; 16]; | 2091 | 247 | let existing_node_new_child_index = existing_node_partial_key[branch_partial_key_len]; | 2092 | 247 | debug_assert_ne!( | 2093 | | existing_node_new_child_index, | 2094 | 247 | new_node_partial_key[branch_partial_key_len] | 2095 | | ); | 2096 | 247 | branch_children[usize::from(u8::from(existing_node_new_child_index))] = | 2097 | 247 | Some(existing_node_index); | 2098 | 247 | branch_children | 2099 | | }; | 2100 | | | 2101 | | // Success! | 2102 | | PrepareInsert::Two(PrepareInsertTwo { | 2103 | 247 | trie: self.trie, | 2104 | | | 2105 | 247 | storage_child_index: new_node_partial_key[branch_partial_key_len], | 2106 | 247 | storage_partial_key: new_node_partial_key[branch_partial_key_len + 1..].to_owned(), | 2107 | | | 2108 | 247 | branch_parent: if let Some((future_parent_index228 , future_parent_key_len228 )) = future_parent | 2109 | | { | 2110 | 228 | let new_child_index = self.key.nth(future_parent_key_len).unwrap(); | 2111 | 228 | Some((future_parent_index, new_child_index)) | 2112 | | } else { | 2113 | 19 | None | 2114 | | }, | 2115 | 247 | branch_partial_key: new_node_partial_key[..branch_partial_key_len].to_owned(), | 2116 | 247 | branch_children, | 2117 | | }) | 2118 | 665 | } |
|
2119 | | } |
2120 | | |
2121 | | /// Preparation for a new node insertion. |
2122 | | /// |
2123 | | /// The trie hasn't been modified yet and you can safely drop this object. |
2124 | | #[must_use] |
2125 | | pub enum PrepareInsert<'a, TUd> { |
2126 | | /// One node will be inserted in the trie. |
2127 | | One(PrepareInsertOne<'a, TUd>), |
2128 | | /// Two nodes will be inserted in the trie. |
2129 | | Two(PrepareInsertTwo<'a, TUd>), |
2130 | | } |
2131 | | |
2132 | | impl<'a, TUd> PrepareInsert<'a, TUd> { |
2133 | | /// Insert the new node. `branch_node_user_data` is discarded if `self` is |
2134 | | /// a [`PrepareInsert::One`]. |
2135 | 1.32M | pub fn insert( |
2136 | 1.32M | self, |
2137 | 1.32M | storage_node_user_data: TUd, |
2138 | 1.32M | branch_node_user_data: TUd, |
2139 | 1.32M | ) -> StorageNodeAccess<'a, TUd> { |
2140 | 1.32M | match self { |
2141 | 1.08M | PrepareInsert::One(n) => n.insert(storage_node_user_data), |
2142 | 241k | PrepareInsert::Two(n) => n.insert(storage_node_user_data, branch_node_user_data), |
2143 | | } |
2144 | 1.32M | } _RNvMs8_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13PrepareInsertTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1d_NtNtB7_9trie_node17MerkleValueOutputEEE6insertB9_ Line | Count | Source | 2135 | 2.51k | pub fn insert( | 2136 | 2.51k | self, | 2137 | 2.51k | storage_node_user_data: TUd, | 2138 | 2.51k | branch_node_user_data: TUd, | 2139 | 2.51k | ) -> StorageNodeAccess<'a, TUd> { | 2140 | 2.51k | match self { | 2141 | 2.45k | PrepareInsert::One(n) => n.insert(storage_node_user_data), | 2142 | 55 | PrepareInsert::Two(n) => n.insert(storage_node_user_data, branch_node_user_data), | 2143 | | } | 2144 | 2.51k | } |
_RNvMs8_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13PrepareInsertTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1d_NtNtB7_9trie_node17MerkleValueOutputEEE6insertB9_ Line | Count | Source | 2135 | 335k | pub fn insert( | 2136 | 335k | self, | 2137 | 335k | storage_node_user_data: TUd, | 2138 | 335k | branch_node_user_data: TUd, | 2139 | 335k | ) -> StorageNodeAccess<'a, TUd> { | 2140 | 335k | match self { | 2141 | 271k | PrepareInsert::One(n) => n.insert(storage_node_user_data), | 2142 | 63.8k | PrepareInsert::Two(n) => n.insert(storage_node_user_data, branch_node_user_data), | 2143 | | } | 2144 | 335k | } |
_RNvMs8_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_13PrepareInsertuE6insertB9_ Line | Count | Source | 2135 | 987k | pub fn insert( | 2136 | 987k | self, | 2137 | 987k | storage_node_user_data: TUd, | 2138 | 987k | branch_node_user_data: TUd, | 2139 | 987k | ) -> StorageNodeAccess<'a, TUd> { | 2140 | 987k | match self { | 2141 | 810k | PrepareInsert::One(n) => n.insert(storage_node_user_data), | 2142 | 177k | PrepareInsert::Two(n) => n.insert(storage_node_user_data, branch_node_user_data), | 2143 | | } | 2144 | 987k | } |
Unexecuted instantiation: _RNvMs8_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13PrepareInsertTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1d_NtNtB7_9trie_node17MerkleValueOutputEEE6insertCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs8_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13PrepareInsertpE6insertB9_ _RNvMs8_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13PrepareInsertTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1d_NtNtB7_9trie_node17MerkleValueOutputEEE6insertCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 2135 | 70 | pub fn insert( | 2136 | 70 | self, | 2137 | 70 | storage_node_user_data: TUd, | 2138 | 70 | branch_node_user_data: TUd, | 2139 | 70 | ) -> StorageNodeAccess<'a, TUd> { | 2140 | 70 | match self { | 2141 | 44 | PrepareInsert::One(n) => n.insert(storage_node_user_data), | 2142 | 26 | PrepareInsert::Two(n) => n.insert(storage_node_user_data, branch_node_user_data), | 2143 | | } | 2144 | 70 | } |
_RNvMs8_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_13PrepareInsertTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1d_NtNtB7_9trie_node17MerkleValueOutputEEE6insertCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 2135 | 665 | pub fn insert( | 2136 | 665 | self, | 2137 | 665 | storage_node_user_data: TUd, | 2138 | 665 | branch_node_user_data: TUd, | 2139 | 665 | ) -> StorageNodeAccess<'a, TUd> { | 2140 | 665 | match self { | 2141 | 418 | PrepareInsert::One(n) => n.insert(storage_node_user_data), | 2142 | 247 | PrepareInsert::Two(n) => n.insert(storage_node_user_data, branch_node_user_data), | 2143 | | } | 2144 | 665 | } |
|
2145 | | } |
2146 | | |
2147 | | /// One node will be inserted in the trie. |
2148 | | pub struct PrepareInsertOne<'a, TUd> { |
2149 | | trie: &'a mut TrieStructure<TUd>, |
2150 | | |
2151 | | /// Value of [`Node::parent`] for the newly-created node. |
2152 | | /// If `None`, we also set the root of the trie to the new node. |
2153 | | parent: Option<(usize, Nibble)>, |
2154 | | /// Value of [`Node::partial_key`] for the newly-created node. |
2155 | | partial_key: Vec<Nibble>, |
2156 | | /// Value of [`Node::children`] for the newly-created node. |
2157 | | children: [Option<usize>; 16], |
2158 | | } |
2159 | | |
2160 | | impl<'a, TUd> PrepareInsertOne<'a, TUd> { |
2161 | | /// Insert the new node. |
2162 | 1.11M | pub fn insert(self, user_data: TUd) -> StorageNodeAccess<'a, TUd> { |
2163 | 1.11M | let new_node_partial_key_len = self.partial_key.len(); |
2164 | | |
2165 | 1.11M | let new_node_index = self.trie.nodes.insert(Node { |
2166 | 1.11M | parent: self.parent, |
2167 | 1.11M | partial_key: self.partial_key, |
2168 | 1.11M | children: self.children, |
2169 | 1.11M | has_storage_value: true, |
2170 | 1.11M | user_data, |
2171 | 1.11M | }); |
2172 | | |
2173 | | // Update the children node to point to their new parent. |
2174 | 17.8M | for (child_index, child) in self.children1.11M .iter1.11M ().enumerate1.11M () { |
2175 | 17.8M | let child100k = match child { |
2176 | 100k | Some(c) => self.trie.nodes.get_mut(*c).unwrap(), |
2177 | 17.7M | None => continue, |
2178 | | }; |
2179 | | |
2180 | 100k | let child_index = Nibble::try_from(u8::try_from(child_index).unwrap()).unwrap(); |
2181 | 100k | child.parent = Some((new_node_index, child_index)); |
2182 | 100k | truncate_first_elems(&mut child.partial_key, new_node_partial_key_len + 1); |
2183 | | } |
2184 | | |
2185 | | // Update the parent to point to its new child. |
2186 | 1.11M | if let Some((parent_index1.05M , child_index1.05M )) = self.parent { |
2187 | 1.05M | let parent = self.trie.nodes.get_mut(parent_index).unwrap(); |
2188 | 1.05M | parent.children[usize::from(u8::from(child_index))] = Some(new_node_index); |
2189 | 1.05M | } else { |
2190 | 61.8k | self.trie.root_index = Some(new_node_index); |
2191 | 61.8k | } |
2192 | | |
2193 | | // Success! |
2194 | 1.11M | StorageNodeAccess { |
2195 | 1.11M | trie: self.trie, |
2196 | 1.11M | node_index: new_node_index, |
2197 | 1.11M | } |
2198 | 1.11M | } _RNvMs9_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16PrepareInsertOneINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE6insertB9_ Line | Count | Source | 2162 | 29.7k | pub fn insert(self, user_data: TUd) -> StorageNodeAccess<'a, TUd> { | 2163 | 29.7k | let new_node_partial_key_len = self.partial_key.len(); | 2164 | | | 2165 | 29.7k | let new_node_index = self.trie.nodes.insert(Node { | 2166 | 29.7k | parent: self.parent, | 2167 | 29.7k | partial_key: self.partial_key, | 2168 | 29.7k | children: self.children, | 2169 | 29.7k | has_storage_value: true, | 2170 | 29.7k | user_data, | 2171 | 29.7k | }); | 2172 | | | 2173 | | // Update the children node to point to their new parent. | 2174 | 476k | for (child_index, child) in self.children29.7k .iter29.7k ().enumerate29.7k () { | 2175 | 476k | let child7.45k = match child { | 2176 | 7.45k | Some(c) => self.trie.nodes.get_mut(*c).unwrap(), | 2177 | 468k | None => continue, | 2178 | | }; | 2179 | | | 2180 | 7.45k | let child_index = Nibble::try_from(u8::try_from(child_index).unwrap()).unwrap(); | 2181 | 7.45k | child.parent = Some((new_node_index, child_index)); | 2182 | 7.45k | truncate_first_elems(&mut child.partial_key, new_node_partial_key_len + 1); | 2183 | | } | 2184 | | | 2185 | | // Update the parent to point to its new child. | 2186 | 29.7k | if let Some((parent_index26.1k , child_index26.1k )) = self.parent { | 2187 | 26.1k | let parent = self.trie.nodes.get_mut(parent_index).unwrap(); | 2188 | 26.1k | parent.children[usize::from(u8::from(child_index))] = Some(new_node_index); | 2189 | 26.1k | } else { | 2190 | 3.56k | self.trie.root_index = Some(new_node_index); | 2191 | 3.56k | } | 2192 | | | 2193 | | // Success! | 2194 | 29.7k | StorageNodeAccess { | 2195 | 29.7k | trie: self.trie, | 2196 | 29.7k | node_index: new_node_index, | 2197 | 29.7k | } | 2198 | 29.7k | } |
_RNvMs9_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16PrepareInsertOneTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE6insertB9_ Line | Count | Source | 2162 | 2.45k | pub fn insert(self, user_data: TUd) -> StorageNodeAccess<'a, TUd> { | 2163 | 2.45k | let new_node_partial_key_len = self.partial_key.len(); | 2164 | | | 2165 | 2.45k | let new_node_index = self.trie.nodes.insert(Node { | 2166 | 2.45k | parent: self.parent, | 2167 | 2.45k | partial_key: self.partial_key, | 2168 | 2.45k | children: self.children, | 2169 | 2.45k | has_storage_value: true, | 2170 | 2.45k | user_data, | 2171 | 2.45k | }); | 2172 | | | 2173 | | // Update the children node to point to their new parent. | 2174 | 39.3k | for (child_index, child) in self.children2.45k .iter2.45k ().enumerate2.45k () { | 2175 | 39.3k | let child1 = match child { | 2176 | 1 | Some(c) => self.trie.nodes.get_mut(*c).unwrap(), | 2177 | 39.3k | None => continue, | 2178 | | }; | 2179 | | | 2180 | 1 | let child_index = Nibble::try_from(u8::try_from(child_index).unwrap()).unwrap(); | 2181 | 1 | child.parent = Some((new_node_index, child_index)); | 2182 | 1 | truncate_first_elems(&mut child.partial_key, new_node_partial_key_len + 1); | 2183 | | } | 2184 | | | 2185 | | // Update the parent to point to its new child. | 2186 | 2.45k | if let Some((parent_index1.43k , child_index1.43k )) = self.parent { | 2187 | 1.43k | let parent = self.trie.nodes.get_mut(parent_index).unwrap(); | 2188 | 1.43k | parent.children[usize::from(u8::from(child_index))] = Some(new_node_index); | 2189 | 1.43k | } else { | 2190 | 1.02k | self.trie.root_index = Some(new_node_index); | 2191 | 1.02k | } | 2192 | | | 2193 | | // Success! | 2194 | 2.45k | StorageNodeAccess { | 2195 | 2.45k | trie: self.trie, | 2196 | 2.45k | node_index: new_node_index, | 2197 | 2.45k | } | 2198 | 2.45k | } |
_RNvMs9_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16PrepareInsertOneTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE6insertB9_ Line | Count | Source | 2162 | 271k | pub fn insert(self, user_data: TUd) -> StorageNodeAccess<'a, TUd> { | 2163 | 271k | let new_node_partial_key_len = self.partial_key.len(); | 2164 | | | 2165 | 271k | let new_node_index = self.trie.nodes.insert(Node { | 2166 | 271k | parent: self.parent, | 2167 | 271k | partial_key: self.partial_key, | 2168 | 271k | children: self.children, | 2169 | 271k | has_storage_value: true, | 2170 | 271k | user_data, | 2171 | 271k | }); | 2172 | | | 2173 | | // Update the children node to point to their new parent. | 2174 | 4.34M | for (child_index, child) in self.children271k .iter271k ().enumerate271k () { | 2175 | 4.34M | let child6.74k = match child { | 2176 | 6.74k | Some(c) => self.trie.nodes.get_mut(*c).unwrap(), | 2177 | 4.34M | None => continue, | 2178 | | }; | 2179 | | | 2180 | 6.74k | let child_index = Nibble::try_from(u8::try_from(child_index).unwrap()).unwrap(); | 2181 | 6.74k | child.parent = Some((new_node_index, child_index)); | 2182 | 6.74k | truncate_first_elems(&mut child.partial_key, new_node_partial_key_len + 1); | 2183 | | } | 2184 | | | 2185 | | // Update the parent to point to its new child. | 2186 | 271k | if let Some((parent_index227k , child_index227k )) = self.parent { | 2187 | 227k | let parent = self.trie.nodes.get_mut(parent_index).unwrap(); | 2188 | 227k | parent.children[usize::from(u8::from(child_index))] = Some(new_node_index); | 2189 | 227k | } else { | 2190 | 44.6k | self.trie.root_index = Some(new_node_index); | 2191 | 44.6k | } | 2192 | | | 2193 | | // Success! | 2194 | 271k | StorageNodeAccess { | 2195 | 271k | trie: self.trie, | 2196 | 271k | node_index: new_node_index, | 2197 | 271k | } | 2198 | 271k | } |
_RNvMs9_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16PrepareInsertOneuE6insertB9_ Line | Count | Source | 2162 | 810k | pub fn insert(self, user_data: TUd) -> StorageNodeAccess<'a, TUd> { | 2163 | 810k | let new_node_partial_key_len = self.partial_key.len(); | 2164 | | | 2165 | 810k | let new_node_index = self.trie.nodes.insert(Node { | 2166 | 810k | parent: self.parent, | 2167 | 810k | partial_key: self.partial_key, | 2168 | 810k | children: self.children, | 2169 | 810k | has_storage_value: true, | 2170 | 810k | user_data, | 2171 | 810k | }); | 2172 | | | 2173 | | // Update the children node to point to their new parent. | 2174 | 12.9M | for (child_index, child) in self.children810k .iter810k ().enumerate810k () { | 2175 | 12.9M | let child86.1k = match child { | 2176 | 86.1k | Some(c) => self.trie.nodes.get_mut(*c).unwrap(), | 2177 | 12.8M | None => continue, | 2178 | | }; | 2179 | | | 2180 | 86.1k | let child_index = Nibble::try_from(u8::try_from(child_index).unwrap()).unwrap(); | 2181 | 86.1k | child.parent = Some((new_node_index, child_index)); | 2182 | 86.1k | truncate_first_elems(&mut child.partial_key, new_node_partial_key_len + 1); | 2183 | | } | 2184 | | | 2185 | | // Update the parent to point to its new child. | 2186 | 810k | if let Some((parent_index797k , child_index797k )) = self.parent { | 2187 | 797k | let parent = self.trie.nodes.get_mut(parent_index).unwrap(); | 2188 | 797k | parent.children[usize::from(u8::from(child_index))] = Some(new_node_index); | 2189 | 797k | } else { | 2190 | 12.6k | self.trie.root_index = Some(new_node_index); | 2191 | 12.6k | } | 2192 | | | 2193 | | // Success! | 2194 | 810k | StorageNodeAccess { | 2195 | 810k | trie: self.trie, | 2196 | 810k | node_index: new_node_index, | 2197 | 810k | } | 2198 | 810k | } |
Unexecuted instantiation: _RNvMs9_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16PrepareInsertOneTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE6insertCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMs9_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16PrepareInsertOneINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE6insertB9_ _RNvMs9_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16PrepareInsertOneTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE6insertCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 2162 | 44 | pub fn insert(self, user_data: TUd) -> StorageNodeAccess<'a, TUd> { | 2163 | 44 | let new_node_partial_key_len = self.partial_key.len(); | 2164 | | | 2165 | 44 | let new_node_index = self.trie.nodes.insert(Node { | 2166 | 44 | parent: self.parent, | 2167 | 44 | partial_key: self.partial_key, | 2168 | 44 | children: self.children, | 2169 | 44 | has_storage_value: true, | 2170 | 44 | user_data, | 2171 | 44 | }); | 2172 | | | 2173 | | // Update the children node to point to their new parent. | 2174 | 704 | for (child_index, child) in self.children44 .iter44 ().enumerate44 () { | 2175 | 704 | let child0 = match child { | 2176 | 0 | Some(c) => self.trie.nodes.get_mut(*c).unwrap(), | 2177 | 704 | None => continue, | 2178 | | }; | 2179 | | | 2180 | 0 | let child_index = Nibble::try_from(u8::try_from(child_index).unwrap()).unwrap(); | 2181 | 0 | child.parent = Some((new_node_index, child_index)); | 2182 | 0 | truncate_first_elems(&mut child.partial_key, new_node_partial_key_len + 1); | 2183 | | } | 2184 | | | 2185 | | // Update the parent to point to its new child. | 2186 | 44 | if let Some((parent_index42 , child_index42 )) = self.parent { | 2187 | 42 | let parent = self.trie.nodes.get_mut(parent_index).unwrap(); | 2188 | 42 | parent.children[usize::from(u8::from(child_index))] = Some(new_node_index); | 2189 | 42 | } else { | 2190 | 2 | self.trie.root_index = Some(new_node_index); | 2191 | 2 | } | 2192 | | | 2193 | | // Success! | 2194 | 44 | StorageNodeAccess { | 2195 | 44 | trie: self.trie, | 2196 | 44 | node_index: new_node_index, | 2197 | 44 | } | 2198 | 44 | } |
_RNvMs9_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16PrepareInsertOneTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE6insertCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 2162 | 418 | pub fn insert(self, user_data: TUd) -> StorageNodeAccess<'a, TUd> { | 2163 | 418 | let new_node_partial_key_len = self.partial_key.len(); | 2164 | | | 2165 | 418 | let new_node_index = self.trie.nodes.insert(Node { | 2166 | 418 | parent: self.parent, | 2167 | 418 | partial_key: self.partial_key, | 2168 | 418 | children: self.children, | 2169 | 418 | has_storage_value: true, | 2170 | 418 | user_data, | 2171 | 418 | }); | 2172 | | | 2173 | | // Update the children node to point to their new parent. | 2174 | 6.68k | for (child_index, child) in self.children418 .iter418 ().enumerate418 () { | 2175 | 6.68k | let child0 = match child { | 2176 | 0 | Some(c) => self.trie.nodes.get_mut(*c).unwrap(), | 2177 | 6.68k | None => continue, | 2178 | | }; | 2179 | | | 2180 | 0 | let child_index = Nibble::try_from(u8::try_from(child_index).unwrap()).unwrap(); | 2181 | 0 | child.parent = Some((new_node_index, child_index)); | 2182 | 0 | truncate_first_elems(&mut child.partial_key, new_node_partial_key_len + 1); | 2183 | | } | 2184 | | | 2185 | | // Update the parent to point to its new child. | 2186 | 418 | if let Some((parent_index399 , child_index399 )) = self.parent { | 2187 | 399 | let parent = self.trie.nodes.get_mut(parent_index).unwrap(); | 2188 | 399 | parent.children[usize::from(u8::from(child_index))] = Some(new_node_index); | 2189 | 399 | } else { | 2190 | 19 | self.trie.root_index = Some(new_node_index); | 2191 | 19 | } | 2192 | | | 2193 | | // Success! | 2194 | 418 | StorageNodeAccess { | 2195 | 418 | trie: self.trie, | 2196 | 418 | node_index: new_node_index, | 2197 | 418 | } | 2198 | 418 | } |
|
2199 | | } |
2200 | | |
2201 | | /// Two nodes will be inserted in the trie. |
2202 | | pub struct PrepareInsertTwo<'a, TUd> { |
2203 | | trie: &'a mut TrieStructure<TUd>, |
2204 | | |
2205 | | /// Value of the child index in [`Node::parent`] for the newly-created storage node. |
2206 | | storage_child_index: Nibble, |
2207 | | /// Value of [`Node::partial_key`] for the newly-created storage node. |
2208 | | storage_partial_key: Vec<Nibble>, |
2209 | | |
2210 | | /// Value of [`Node::parent`] for the newly-created branch node. |
2211 | | /// If `None`, we also set the root of the trie to the new branch node. |
2212 | | branch_parent: Option<(usize, Nibble)>, |
2213 | | /// Value of [`Node::partial_key`] for the newly-created branch node. |
2214 | | branch_partial_key: Vec<Nibble>, |
2215 | | /// Value of [`Node::children`] for the newly-created branch node. Does not include the entry |
2216 | | /// that must be filled with the new storage node. |
2217 | | branch_children: [Option<usize>; 16], |
2218 | | } |
2219 | | |
2220 | | impl<'a, TUd> PrepareInsertTwo<'a, TUd> { |
2221 | | /// Key of the branch node that will be inserted. |
2222 | 0 | pub fn branch_node_key(&self) -> impl Iterator<Item = Nibble> { |
2223 | 0 | if let Some((parent_index, child_index)) = self.branch_parent { |
2224 | 0 | let parent = self.trie.node_full_key(parent_index); |
2225 | 0 | let iter = parent |
2226 | 0 | .chain(iter::once(child_index)) |
2227 | 0 | .chain(self.branch_partial_key.iter().cloned()); |
2228 | 0 | Either::Left(iter) |
2229 | | } else { |
2230 | 0 | Either::Right(self.branch_partial_key.iter().cloned()) |
2231 | | } |
2232 | 0 | } Unexecuted instantiation: _RNvMsa_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16PrepareInsertTwoINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE15branch_node_keyB9_ Unexecuted instantiation: _RNvMsa_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16PrepareInsertTwoINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE15branch_node_keyB9_ |
2233 | | |
2234 | | /// Insert the new node. |
2235 | 241k | pub fn insert( |
2236 | 241k | self, |
2237 | 241k | storage_node_user_data: TUd, |
2238 | 241k | branch_node_user_data: TUd, |
2239 | 241k | ) -> StorageNodeAccess<'a, TUd> { |
2240 | 241k | let new_branch_node_partial_key_len = self.branch_partial_key.len(); |
2241 | | |
2242 | 241k | debug_assert_eq!( |
2243 | 3.86M | self.branch_children241k .iter241k ().filter241k (|c| c.is_some()).count241k (), Unexecuted instantiation: _RNCNvMsa_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_16PrepareInsertTwoINtNtCs66KPHxksi63_4core6option6OptionNtNtB9_12proof_encode4NodeEE6insert0Bb_ _RNCNvMsa_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_16PrepareInsertTwoTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1i_NtNtB9_9trie_node17MerkleValueOutputEEE6insert0Bb_ Line | Count | Source | 2243 | 880 | self.branch_children.iter().filter(|c| c.is_some()).count(), |
_RNCNvMsa_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_16PrepareInsertTwoTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB9_16TrieEntryVersionEEIB1i_NtNtB9_9trie_node17MerkleValueOutputEEE6insert0Bb_ Line | Count | Source | 2243 | 1.02M | self.branch_children.iter().filter(|c| c.is_some()).count(), |
_RNCNvMsa_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB7_16PrepareInsertTwouE6insert0Bb_ Line | Count | Source | 2243 | 2.83M | self.branch_children.iter().filter(|c| c.is_some()).count(), |
Unexecuted instantiation: _RNCNvMsa_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB7_16PrepareInsertTwoTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1i_NtNtB9_9trie_node17MerkleValueOutputEEE6insert0Cs4ISLcsFEGeP_6author Unexecuted instantiation: _RNCNvMsa_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB7_16PrepareInsertTwoINtNtCs66KPHxksi63_4core6option6OptionNtNtB9_12proof_encode4NodeEE6insert0Bb_ _RNCNvMsa_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB7_16PrepareInsertTwoTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1i_NtNtB9_9trie_node17MerkleValueOutputEEE6insert0Cs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 2243 | 416 | self.branch_children.iter().filter(|c| c.is_some()).count(), |
_RNCNvMsa_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB7_16PrepareInsertTwoTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1i_NtNtB9_9trie_node17MerkleValueOutputEEE6insert0Cs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 2243 | 3.95k | self.branch_children.iter().filter(|c| c.is_some()).count(), |
|
2244 | | 1 |
2245 | | ); |
2246 | | |
2247 | 241k | let new_branch_node_index = self.trie.nodes.insert(Node { |
2248 | 241k | parent: self.branch_parent, |
2249 | 241k | partial_key: self.branch_partial_key, |
2250 | 241k | children: self.branch_children, |
2251 | 241k | has_storage_value: false, |
2252 | 241k | user_data: branch_node_user_data, |
2253 | 241k | }); |
2254 | | |
2255 | 241k | let new_storage_node_index = self.trie.nodes.insert(Node { |
2256 | 241k | parent: Some((new_branch_node_index, self.storage_child_index)), |
2257 | 241k | partial_key: self.storage_partial_key, |
2258 | 241k | children: [None; 16], |
2259 | 241k | has_storage_value: true, |
2260 | 241k | user_data: storage_node_user_data, |
2261 | 241k | }); |
2262 | | |
2263 | 241k | self.trie |
2264 | 241k | .nodes |
2265 | 241k | .get_mut(new_branch_node_index) |
2266 | 241k | .unwrap() |
2267 | 241k | .children[usize::from(u8::from(self.storage_child_index))] = |
2268 | 241k | Some(new_storage_node_index); |
2269 | | |
2270 | | // Update the branch node's children to point to their new parent. |
2271 | 3.86M | for (child_index, child) in self.branch_children241k .iter241k ().enumerate241k () { |
2272 | 3.86M | let child241k = match child { |
2273 | 241k | Some(c) => self.trie.nodes.get_mut(*c).unwrap(), |
2274 | 3.62M | None => continue, |
2275 | | }; |
2276 | | |
2277 | 241k | let child_index = Nibble::try_from(u8::try_from(child_index).unwrap()).unwrap(); |
2278 | 241k | child.parent = Some((new_branch_node_index, child_index)); |
2279 | 241k | truncate_first_elems(&mut child.partial_key, new_branch_node_partial_key_len + 1); |
2280 | | } |
2281 | | |
2282 | | // Update the branch node's parent to point to its new child. |
2283 | 241k | if let Some((parent_index225k , child_index225k )) = self.branch_parent { |
2284 | 225k | let parent = self.trie.nodes.get_mut(parent_index).unwrap(); |
2285 | 225k | parent.children[usize::from(u8::from(child_index))] = Some(new_branch_node_index); |
2286 | 225k | } else { |
2287 | 16.0k | self.trie.root_index = Some(new_branch_node_index); |
2288 | 16.0k | } |
2289 | | |
2290 | | // Success! |
2291 | 241k | StorageNodeAccess { |
2292 | 241k | trie: self.trie, |
2293 | 241k | node_index: new_storage_node_index, |
2294 | 241k | } |
2295 | 241k | } Unexecuted instantiation: _RNvMsa_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16PrepareInsertTwoINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE6insertB9_ _RNvMsa_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16PrepareInsertTwoTINtNtCs66KPHxksi63_4core6option6OptionINtNtCs8Ty2CzGA6U3_5alloc3vec3VechEEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE6insertB9_ Line | Count | Source | 2235 | 55 | pub fn insert( | 2236 | 55 | self, | 2237 | 55 | storage_node_user_data: TUd, | 2238 | 55 | branch_node_user_data: TUd, | 2239 | 55 | ) -> StorageNodeAccess<'a, TUd> { | 2240 | 55 | let new_branch_node_partial_key_len = self.branch_partial_key.len(); | 2241 | | | 2242 | 55 | debug_assert_eq!( | 2243 | 55 | self.branch_children.iter().filter(|c| c.is_some()).count(), | 2244 | | 1 | 2245 | | ); | 2246 | | | 2247 | 55 | let new_branch_node_index = self.trie.nodes.insert(Node { | 2248 | 55 | parent: self.branch_parent, | 2249 | 55 | partial_key: self.branch_partial_key, | 2250 | 55 | children: self.branch_children, | 2251 | 55 | has_storage_value: false, | 2252 | 55 | user_data: branch_node_user_data, | 2253 | 55 | }); | 2254 | | | 2255 | 55 | let new_storage_node_index = self.trie.nodes.insert(Node { | 2256 | 55 | parent: Some((new_branch_node_index, self.storage_child_index)), | 2257 | 55 | partial_key: self.storage_partial_key, | 2258 | 55 | children: [None; 16], | 2259 | 55 | has_storage_value: true, | 2260 | 55 | user_data: storage_node_user_data, | 2261 | 55 | }); | 2262 | | | 2263 | 55 | self.trie | 2264 | 55 | .nodes | 2265 | 55 | .get_mut(new_branch_node_index) | 2266 | 55 | .unwrap() | 2267 | 55 | .children[usize::from(u8::from(self.storage_child_index))] = | 2268 | 55 | Some(new_storage_node_index); | 2269 | | | 2270 | | // Update the branch node's children to point to their new parent. | 2271 | 880 | for (child_index, child) in self.branch_children55 .iter55 ().enumerate55 () { | 2272 | 880 | let child55 = match child { | 2273 | 55 | Some(c) => self.trie.nodes.get_mut(*c).unwrap(), | 2274 | 825 | None => continue, | 2275 | | }; | 2276 | | | 2277 | 55 | let child_index = Nibble::try_from(u8::try_from(child_index).unwrap()).unwrap(); | 2278 | 55 | child.parent = Some((new_branch_node_index, child_index)); | 2279 | 55 | truncate_first_elems(&mut child.partial_key, new_branch_node_partial_key_len + 1); | 2280 | | } | 2281 | | | 2282 | | // Update the branch node's parent to point to its new child. | 2283 | 55 | if let Some((parent_index, child_index)) = self.branch_parent { | 2284 | 55 | let parent = self.trie.nodes.get_mut(parent_index).unwrap(); | 2285 | 55 | parent.children[usize::from(u8::from(child_index))] = Some(new_branch_node_index); | 2286 | 55 | } else { | 2287 | 0 | self.trie.root_index = Some(new_branch_node_index); | 2288 | 0 | } | 2289 | | | 2290 | | // Success! | 2291 | 55 | StorageNodeAccess { | 2292 | 55 | trie: self.trie, | 2293 | 55 | node_index: new_storage_node_index, | 2294 | 55 | } | 2295 | 55 | } |
_RNvMsa_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16PrepareInsertTwoTINtNtCs66KPHxksi63_4core6option6OptionTINtNtCs8Ty2CzGA6U3_5alloc3vec3VechENtB7_16TrieEntryVersionEEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE6insertB9_ Line | Count | Source | 2235 | 63.8k | pub fn insert( | 2236 | 63.8k | self, | 2237 | 63.8k | storage_node_user_data: TUd, | 2238 | 63.8k | branch_node_user_data: TUd, | 2239 | 63.8k | ) -> StorageNodeAccess<'a, TUd> { | 2240 | 63.8k | let new_branch_node_partial_key_len = self.branch_partial_key.len(); | 2241 | | | 2242 | 63.8k | debug_assert_eq!( | 2243 | 63.8k | self.branch_children.iter().filter(|c| c.is_some()).count(), | 2244 | | 1 | 2245 | | ); | 2246 | | | 2247 | 63.8k | let new_branch_node_index = self.trie.nodes.insert(Node { | 2248 | 63.8k | parent: self.branch_parent, | 2249 | 63.8k | partial_key: self.branch_partial_key, | 2250 | 63.8k | children: self.branch_children, | 2251 | 63.8k | has_storage_value: false, | 2252 | 63.8k | user_data: branch_node_user_data, | 2253 | 63.8k | }); | 2254 | | | 2255 | 63.8k | let new_storage_node_index = self.trie.nodes.insert(Node { | 2256 | 63.8k | parent: Some((new_branch_node_index, self.storage_child_index)), | 2257 | 63.8k | partial_key: self.storage_partial_key, | 2258 | 63.8k | children: [None; 16], | 2259 | 63.8k | has_storage_value: true, | 2260 | 63.8k | user_data: storage_node_user_data, | 2261 | 63.8k | }); | 2262 | | | 2263 | 63.8k | self.trie | 2264 | 63.8k | .nodes | 2265 | 63.8k | .get_mut(new_branch_node_index) | 2266 | 63.8k | .unwrap() | 2267 | 63.8k | .children[usize::from(u8::from(self.storage_child_index))] = | 2268 | 63.8k | Some(new_storage_node_index); | 2269 | | | 2270 | | // Update the branch node's children to point to their new parent. | 2271 | 1.02M | for (child_index, child) in self.branch_children63.8k .iter63.8k ().enumerate63.8k () { | 2272 | 1.02M | let child63.8k = match child { | 2273 | 63.8k | Some(c) => self.trie.nodes.get_mut(*c).unwrap(), | 2274 | 958k | None => continue, | 2275 | | }; | 2276 | | | 2277 | 63.8k | let child_index = Nibble::try_from(u8::try_from(child_index).unwrap()).unwrap(); | 2278 | 63.8k | child.parent = Some((new_branch_node_index, child_index)); | 2279 | 63.8k | truncate_first_elems(&mut child.partial_key, new_branch_node_partial_key_len + 1); | 2280 | | } | 2281 | | | 2282 | | // Update the branch node's parent to point to its new child. | 2283 | 63.8k | if let Some((parent_index56.5k , child_index56.5k )) = self.branch_parent { | 2284 | 56.5k | let parent = self.trie.nodes.get_mut(parent_index).unwrap(); | 2285 | 56.5k | parent.children[usize::from(u8::from(child_index))] = Some(new_branch_node_index); | 2286 | 56.5k | } else { | 2287 | 7.31k | self.trie.root_index = Some(new_branch_node_index); | 2288 | 7.31k | } | 2289 | | | 2290 | | // Success! | 2291 | 63.8k | StorageNodeAccess { | 2292 | 63.8k | trie: self.trie, | 2293 | 63.8k | node_index: new_storage_node_index, | 2294 | 63.8k | } | 2295 | 63.8k | } |
_RNvMsa_NtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structureINtB5_16PrepareInsertTwouE6insertB9_ Line | Count | Source | 2235 | 177k | pub fn insert( | 2236 | 177k | self, | 2237 | 177k | storage_node_user_data: TUd, | 2238 | 177k | branch_node_user_data: TUd, | 2239 | 177k | ) -> StorageNodeAccess<'a, TUd> { | 2240 | 177k | let new_branch_node_partial_key_len = self.branch_partial_key.len(); | 2241 | | | 2242 | 177k | debug_assert_eq!( | 2243 | 177k | self.branch_children.iter().filter(|c| c.is_some()).count(), | 2244 | | 1 | 2245 | | ); | 2246 | | | 2247 | 177k | let new_branch_node_index = self.trie.nodes.insert(Node { | 2248 | 177k | parent: self.branch_parent, | 2249 | 177k | partial_key: self.branch_partial_key, | 2250 | 177k | children: self.branch_children, | 2251 | 177k | has_storage_value: false, | 2252 | 177k | user_data: branch_node_user_data, | 2253 | 177k | }); | 2254 | | | 2255 | 177k | let new_storage_node_index = self.trie.nodes.insert(Node { | 2256 | 177k | parent: Some((new_branch_node_index, self.storage_child_index)), | 2257 | 177k | partial_key: self.storage_partial_key, | 2258 | 177k | children: [None; 16], | 2259 | 177k | has_storage_value: true, | 2260 | 177k | user_data: storage_node_user_data, | 2261 | 177k | }); | 2262 | | | 2263 | 177k | self.trie | 2264 | 177k | .nodes | 2265 | 177k | .get_mut(new_branch_node_index) | 2266 | 177k | .unwrap() | 2267 | 177k | .children[usize::from(u8::from(self.storage_child_index))] = | 2268 | 177k | Some(new_storage_node_index); | 2269 | | | 2270 | | // Update the branch node's children to point to their new parent. | 2271 | 2.83M | for (child_index, child) in self.branch_children177k .iter177k ().enumerate177k () { | 2272 | 2.83M | let child177k = match child { | 2273 | 177k | Some(c) => self.trie.nodes.get_mut(*c).unwrap(), | 2274 | 2.65M | None => continue, | 2275 | | }; | 2276 | | | 2277 | 177k | let child_index = Nibble::try_from(u8::try_from(child_index).unwrap()).unwrap(); | 2278 | 177k | child.parent = Some((new_branch_node_index, child_index)); | 2279 | 177k | truncate_first_elems(&mut child.partial_key, new_branch_node_partial_key_len + 1); | 2280 | | } | 2281 | | | 2282 | | // Update the branch node's parent to point to its new child. | 2283 | 177k | if let Some((parent_index168k , child_index168k )) = self.branch_parent { | 2284 | 168k | let parent = self.trie.nodes.get_mut(parent_index).unwrap(); | 2285 | 168k | parent.children[usize::from(u8::from(child_index))] = Some(new_branch_node_index); | 2286 | 168k | } else { | 2287 | 8.75k | self.trie.root_index = Some(new_branch_node_index); | 2288 | 8.75k | } | 2289 | | | 2290 | | // Success! | 2291 | 177k | StorageNodeAccess { | 2292 | 177k | trie: self.trie, | 2293 | 177k | node_index: new_storage_node_index, | 2294 | 177k | } | 2295 | 177k | } |
Unexecuted instantiation: _RNvMsa_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16PrepareInsertTwoTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE6insertCs4ISLcsFEGeP_6author Unexecuted instantiation: _RNvMsa_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16PrepareInsertTwoINtNtCs66KPHxksi63_4core6option6OptionNtNtB7_12proof_encode4NodeEE6insertB9_ _RNvMsa_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16PrepareInsertTwoTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE6insertCs2XuF9XSsPgw_14json_rpc_basic Line | Count | Source | 2235 | 26 | pub fn insert( | 2236 | 26 | self, | 2237 | 26 | storage_node_user_data: TUd, | 2238 | 26 | branch_node_user_data: TUd, | 2239 | 26 | ) -> StorageNodeAccess<'a, TUd> { | 2240 | 26 | let new_branch_node_partial_key_len = self.branch_partial_key.len(); | 2241 | | | 2242 | 26 | debug_assert_eq!( | 2243 | 26 | self.branch_children.iter().filter(|c| c.is_some()).count(), | 2244 | | 1 | 2245 | | ); | 2246 | | | 2247 | 26 | let new_branch_node_index = self.trie.nodes.insert(Node { | 2248 | 26 | parent: self.branch_parent, | 2249 | 26 | partial_key: self.branch_partial_key, | 2250 | 26 | children: self.branch_children, | 2251 | 26 | has_storage_value: false, | 2252 | 26 | user_data: branch_node_user_data, | 2253 | 26 | }); | 2254 | | | 2255 | 26 | let new_storage_node_index = self.trie.nodes.insert(Node { | 2256 | 26 | parent: Some((new_branch_node_index, self.storage_child_index)), | 2257 | 26 | partial_key: self.storage_partial_key, | 2258 | 26 | children: [None; 16], | 2259 | 26 | has_storage_value: true, | 2260 | 26 | user_data: storage_node_user_data, | 2261 | 26 | }); | 2262 | | | 2263 | 26 | self.trie | 2264 | 26 | .nodes | 2265 | 26 | .get_mut(new_branch_node_index) | 2266 | 26 | .unwrap() | 2267 | 26 | .children[usize::from(u8::from(self.storage_child_index))] = | 2268 | 26 | Some(new_storage_node_index); | 2269 | | | 2270 | | // Update the branch node's children to point to their new parent. | 2271 | 416 | for (child_index, child) in self.branch_children26 .iter26 ().enumerate26 () { | 2272 | 416 | let child26 = match child { | 2273 | 26 | Some(c) => self.trie.nodes.get_mut(*c).unwrap(), | 2274 | 390 | None => continue, | 2275 | | }; | 2276 | | | 2277 | 26 | let child_index = Nibble::try_from(u8::try_from(child_index).unwrap()).unwrap(); | 2278 | 26 | child.parent = Some((new_branch_node_index, child_index)); | 2279 | 26 | truncate_first_elems(&mut child.partial_key, new_branch_node_partial_key_len + 1); | 2280 | | } | 2281 | | | 2282 | | // Update the branch node's parent to point to its new child. | 2283 | 26 | if let Some((parent_index24 , child_index24 )) = self.branch_parent { | 2284 | 24 | let parent = self.trie.nodes.get_mut(parent_index).unwrap(); | 2285 | 24 | parent.children[usize::from(u8::from(child_index))] = Some(new_branch_node_index); | 2286 | 24 | } else { | 2287 | 2 | self.trie.root_index = Some(new_branch_node_index); | 2288 | 2 | } | 2289 | | | 2290 | | // Success! | 2291 | 26 | StorageNodeAccess { | 2292 | 26 | trie: self.trie, | 2293 | 26 | node_index: new_storage_node_index, | 2294 | 26 | } | 2295 | 26 | } |
_RNvMsa_NtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structureINtB5_16PrepareInsertTwoTINtNtCs66KPHxksi63_4core6option6OptionRShEIB1g_NtNtB7_9trie_node17MerkleValueOutputEEE6insertCs8se6o44HBaX_25json_rpc_general_requests Line | Count | Source | 2235 | 247 | pub fn insert( | 2236 | 247 | self, | 2237 | 247 | storage_node_user_data: TUd, | 2238 | 247 | branch_node_user_data: TUd, | 2239 | 247 | ) -> StorageNodeAccess<'a, TUd> { | 2240 | 247 | let new_branch_node_partial_key_len = self.branch_partial_key.len(); | 2241 | | | 2242 | 247 | debug_assert_eq!( | 2243 | 247 | self.branch_children.iter().filter(|c| c.is_some()).count(), | 2244 | | 1 | 2245 | | ); | 2246 | | | 2247 | 247 | let new_branch_node_index = self.trie.nodes.insert(Node { | 2248 | 247 | parent: self.branch_parent, | 2249 | 247 | partial_key: self.branch_partial_key, | 2250 | 247 | children: self.branch_children, | 2251 | 247 | has_storage_value: false, | 2252 | 247 | user_data: branch_node_user_data, | 2253 | 247 | }); | 2254 | | | 2255 | 247 | let new_storage_node_index = self.trie.nodes.insert(Node { | 2256 | 247 | parent: Some((new_branch_node_index, self.storage_child_index)), | 2257 | 247 | partial_key: self.storage_partial_key, | 2258 | 247 | children: [None; 16], | 2259 | 247 | has_storage_value: true, | 2260 | 247 | user_data: storage_node_user_data, | 2261 | 247 | }); | 2262 | | | 2263 | 247 | self.trie | 2264 | 247 | .nodes | 2265 | 247 | .get_mut(new_branch_node_index) | 2266 | 247 | .unwrap() | 2267 | 247 | .children[usize::from(u8::from(self.storage_child_index))] = | 2268 | 247 | Some(new_storage_node_index); | 2269 | | | 2270 | | // Update the branch node's children to point to their new parent. | 2271 | 3.95k | for (child_index, child) in self.branch_children247 .iter247 ().enumerate247 () { | 2272 | 3.95k | let child247 = match child { | 2273 | 247 | Some(c) => self.trie.nodes.get_mut(*c).unwrap(), | 2274 | 3.70k | None => continue, | 2275 | | }; | 2276 | | | 2277 | 247 | let child_index = Nibble::try_from(u8::try_from(child_index).unwrap()).unwrap(); | 2278 | 247 | child.parent = Some((new_branch_node_index, child_index)); | 2279 | 247 | truncate_first_elems(&mut child.partial_key, new_branch_node_partial_key_len + 1); | 2280 | | } | 2281 | | | 2282 | | // Update the branch node's parent to point to its new child. | 2283 | 247 | if let Some((parent_index228 , child_index228 )) = self.branch_parent { | 2284 | 228 | let parent = self.trie.nodes.get_mut(parent_index).unwrap(); | 2285 | 228 | parent.children[usize::from(u8::from(child_index))] = Some(new_branch_node_index); | 2286 | 228 | } else { | 2287 | 19 | self.trie.root_index = Some(new_branch_node_index); | 2288 | 19 | } | 2289 | | | 2290 | | // Success! | 2291 | 247 | StorageNodeAccess { | 2292 | 247 | trie: self.trie, | 2293 | 247 | node_index: new_storage_node_index, | 2294 | 247 | } | 2295 | 247 | } |
|
2296 | | } |
2297 | | |
2298 | | /// Inserts `first` and `second` at the beginning of `vec`. |
2299 | 24.9k | fn insert_front(vec: &mut Vec<Nibble>, first: Vec<Nibble>, next: Nibble) { |
2300 | 24.9k | let shift = first.len() + 1; |
2301 | 24.9k | let previous_len = vec.len(); |
2302 | 24.9k | vec.resize(vec.len() + shift, Nibble::try_from(0).unwrap()); |
2303 | 51.0k | for n in (0..previous_len)24.9k .rev24.9k () { |
2304 | 51.0k | vec[n + shift] = vec[n]; |
2305 | 51.0k | } |
2306 | 24.9k | vec[0..first.len()].copy_from_slice(&first); |
2307 | 24.9k | vec[first.len()] = next; |
2308 | 24.9k | } _RNvNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structure12insert_front Line | Count | Source | 2299 | 24.9k | fn insert_front(vec: &mut Vec<Nibble>, first: Vec<Nibble>, next: Nibble) { | 2300 | 24.9k | let shift = first.len() + 1; | 2301 | 24.9k | let previous_len = vec.len(); | 2302 | 24.9k | vec.resize(vec.len() + shift, Nibble::try_from(0).unwrap()); | 2303 | 51.0k | for n in (0..previous_len)24.9k .rev24.9k () { | 2304 | 51.0k | vec[n + shift] = vec[n]; | 2305 | 51.0k | } | 2306 | 24.9k | vec[0..first.len()].copy_from_slice(&first); | 2307 | 24.9k | vec[first.len()] = next; | 2308 | 24.9k | } |
Unexecuted instantiation: _RNvNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structure12insert_front |
2309 | | |
2310 | | /// Removes the first `num` elements of `vec`. |
2311 | 341k | fn truncate_first_elems(vec: &mut Vec<Nibble>, num: usize) { |
2312 | 341k | debug_assert!(num <= vec.len()); |
2313 | 573k | for n in num341k ..vec341k .len341k () { |
2314 | 573k | vec[n - num] = vec[n]; |
2315 | 573k | } |
2316 | 341k | vec.truncate(vec.len() - num); |
2317 | 341k | } _RNvNtNtCsaBvc5fX2Vw6_7smoldot4trie14trie_structure20truncate_first_elems Line | Count | Source | 2311 | 341k | fn truncate_first_elems(vec: &mut Vec<Nibble>, num: usize) { | 2312 | 341k | debug_assert!(num <= vec.len()); | 2313 | 560k | for n in num341k ..vec341k .len341k () { | 2314 | 560k | vec[n - num] = vec[n]; | 2315 | 560k | } | 2316 | 341k | vec.truncate(vec.len() - num); | 2317 | 341k | } |
_RNvNtNtCs1BDdGGCOX8n_7smoldot4trie14trie_structure20truncate_first_elems Line | Count | Source | 2311 | 273 | fn truncate_first_elems(vec: &mut Vec<Nibble>, num: usize) { | 2312 | 273 | debug_assert!(num <= vec.len()); | 2313 | 12.4k | for n in num273 ..vec273 .len273 () { | 2314 | 12.4k | vec[n - num] = vec[n]; | 2315 | 12.4k | } | 2316 | 273 | vec.truncate(vec.len() - num); | 2317 | 273 | } |
|