@@ -139,6 +139,83 @@ impl<H: Hasher + Default, V: Value, S: Store<V>> SparseMerkleTree<H, V, S> {
139139 Ok ( & self . root )
140140 }
141141
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+
142219 /// Get value of a leaf
143220 /// return zero value if leaf not exists
144221 pub fn get ( & self , key : & H256 ) -> Result < V > {
0 commit comments