Browse Source

Optimize update_index to avoid vec copies (#7624)

update_index to avoid vec copy
HaoranYi 2 months ago
parent
commit
7c6a2d8ea9
1 changed files with 17 additions and 4 deletions
  1. 17 4
      accounts-db/src/accounts_db.rs

+ 17 - 4
accounts-db/src/accounts_db.rs

@@ -5455,6 +5455,9 @@ impl AccountsDb {
         }
         }
     }
     }
 
 
+    /// Updates the accounts index with the given `infos` and `accounts`.
+    /// Returns a vector of `SlotList<AccountInfo>` containing the reclaims for each batch processed.
+    /// The element of the returned vector is guaranteed to be non-empty.
     fn update_index<'a>(
     fn update_index<'a>(
         &self,
         &self,
         infos: Vec<AccountInfo>,
         infos: Vec<AccountInfo>,
@@ -5462,7 +5465,7 @@ impl AccountsDb {
         reclaim: UpsertReclaim,
         reclaim: UpsertReclaim,
         update_index_thread_selection: UpdateIndexThreadSelection,
         update_index_thread_selection: UpdateIndexThreadSelection,
         thread_pool: &ThreadPool,
         thread_pool: &ThreadPool,
-    ) -> ReclaimsSlotList<AccountInfo> {
+    ) -> Vec<ReclaimsSlotList<AccountInfo>> {
         let target_slot = accounts.target_slot();
         let target_slot = accounts.target_slot();
         let len = std::cmp::min(accounts.len(), infos.len());
         let len = std::cmp::min(accounts.len(), infos.len());
 
 
@@ -5512,11 +5515,17 @@ impl AccountsDb {
                         let end = std::cmp::min(start + chunk_size, len);
                         let end = std::cmp::min(start + chunk_size, len);
                         update(start, end)
                         update(start, end)
                     })
                     })
-                    .flatten()
+                    .filter(|reclaims| !reclaims.is_empty())
                     .collect()
                     .collect()
             })
             })
         } else {
         } else {
-            update(0, len)
+            let reclaims = update(0, len);
+            if reclaims.is_empty() {
+                // If no reclaims, return an empty vector
+                vec![]
+            } else {
+                vec![reclaims]
+            }
         }
         }
     }
     }
 
 
@@ -5990,11 +5999,15 @@ impl AccountsDb {
         // If there are any reclaims then they should be handled. Reclaims affect
         // If there are any reclaims then they should be handled. Reclaims affect
         // all storages, and may result in the removal of dead storages.
         // all storages, and may result in the removal of dead storages.
         let mut handle_reclaims_elapsed = 0;
         let mut handle_reclaims_elapsed = 0;
+
+        // since reclaims only contains non-empty SlotList<AccountInfo>, we
+        // should skip handle_reclaims only when reclaims is empty. No need to
+        // check the elements of reclaims are empty.
         if !reclaims.is_empty() {
         if !reclaims.is_empty() {
             let purge_stats = PurgeStats::default();
             let purge_stats = PurgeStats::default();
             let mut handle_reclaims_time = Measure::start("handle_reclaims");
             let mut handle_reclaims_time = Measure::start("handle_reclaims");
             self.handle_reclaims(
             self.handle_reclaims(
-                reclaims.iter(),
+                reclaims.iter().flatten(),
                 None,
                 None,
                 &HashSet::default(),
                 &HashSet::default(),
                 HandleReclaims::ProcessDeadSlots(&purge_stats),
                 HandleReclaims::ProcessDeadSlots(&purge_stats),