@@ -139,6 +139,83 @@ impl<H: Hasher + Default, V: Value, S: Store<V>> SparseMerkleTree<H, V, S> {
139
139
Ok ( & self . root )
140
140
}
141
141
142
+ /// Update multiple leaves at once
143
+ pub fn update_all ( & mut self , mut leaves : Vec < ( H256 , V ) > ) -> Result < & H256 > {
144
+ // Dedup(only keep the last of each key) and sort leaves
145
+ leaves. reverse ( ) ;
146
+ leaves. sort_by_key ( |( a, _) | a. clone ( ) ) ;
147
+ leaves. dedup_by_key ( |( a, _) | a. clone ( ) ) ;
148
+
149
+ let mut nodes: Vec < ( H256 , MergeValue ) > = Vec :: new ( ) ;
150
+ for ( k, v) in leaves {
151
+ let value = MergeValue :: from_h256 ( v. to_h256 ( ) ) ;
152
+ if !value. is_zero ( ) {
153
+ self . store . insert_leaf ( k, v) ?;
154
+ } else {
155
+ self . store . remove_leaf ( & k) ?;
156
+ }
157
+ nodes. push ( ( k, value) ) ;
158
+ }
159
+
160
+ for height in 0 ..=core:: u8:: MAX {
161
+ let mut next_nodes: Vec < ( H256 , MergeValue ) > = Vec :: new ( ) ;
162
+ let mut i = 0 ;
163
+ while i < nodes. len ( ) {
164
+ let ( current_key, current_merge_value) = & nodes[ i] ;
165
+ i += 1 ;
166
+ let parent_key = current_key. parent_path ( height) ;
167
+ let parent_branch_key = BranchKey :: new ( height, parent_key) ;
168
+
169
+ // Test for neighbors
170
+ let mut right = None ;
171
+ if i < nodes. len ( ) && ( !current_key. is_right ( height) ) {
172
+ let ( neighbor_key, neighbor_value) = & nodes[ i] ;
173
+ let mut right_key = current_key. clone ( ) ;
174
+ right_key. set_bit ( height) ;
175
+ if right_key == * neighbor_key {
176
+ right = Some ( neighbor_value. clone ( ) ) ;
177
+ i += 1 ;
178
+ }
179
+ }
180
+
181
+ let ( left, right) = if let Some ( right_merge_value) = right {
182
+ ( current_merge_value. clone ( ) , right_merge_value)
183
+ } else {
184
+ // In case neighbor is not available, fetch from store
185
+ if let Some ( parent_branch) = self . store . get_branch ( & parent_branch_key) ? {
186
+ if current_key. is_right ( height) {
187
+ ( parent_branch. left , current_merge_value. clone ( ) )
188
+ } else {
189
+ ( current_merge_value. clone ( ) , parent_branch. right )
190
+ }
191
+ } else if current_key. is_right ( height) {
192
+ ( MergeValue :: zero ( ) , current_merge_value. clone ( ) )
193
+ } else {
194
+ ( current_merge_value. clone ( ) , MergeValue :: zero ( ) )
195
+ }
196
+ } ;
197
+
198
+ if !left. is_zero ( ) || !right. is_zero ( ) {
199
+ self . store . insert_branch (
200
+ parent_branch_key,
201
+ BranchNode {
202
+ left : left. clone ( ) ,
203
+ right : right. clone ( ) ,
204
+ } ,
205
+ ) ?;
206
+ } else {
207
+ self . store . remove_branch ( & parent_branch_key) ?;
208
+ }
209
+ next_nodes. push ( ( parent_key, merge :: < H > ( height, & parent_key, & left, & right) ) ) ;
210
+ }
211
+ nodes = next_nodes;
212
+ }
213
+
214
+ assert ! ( nodes. len( ) == 1 ) ;
215
+ self . root = nodes[ 0 ] . 1 . hash :: < H > ( ) ;
216
+ Ok ( & self . root )
217
+ }
218
+
142
219
/// Get value of a leaf
143
220
/// return zero value if leaf not exists
144
221
pub fn get ( & self , key : & H256 ) -> Result < V > {
0 commit comments