Forráskód Böngészése

Move ideal_storage_size calculation before it is used (#3250)

* Move ideal_storage_size calculation before it is used

* Add test
dmakarov 1 éve
szülő
commit
91d0a5e2a9
1 módosított fájl, 41 hozzáadás és 15 törlés
  1. 41 15
      accounts-db/src/ancient_append_vecs.rs

+ 41 - 15
accounts-db/src/ancient_append_vecs.rs

@@ -416,14 +416,8 @@ impl AccountsDb {
         self.shrink_ancient_stats
             .slots_considered
             .fetch_add(sorted_slots.len() as u64, Ordering::Relaxed);
-        let mut ancient_slot_infos = self.collect_sort_filter_ancient_slots(sorted_slots, &tuning);
-        // ideal storage size is total alive bytes of ancient storages
-        // divided by half of max ancient slots
-        tuning.ideal_storage_size = NonZeroU64::new(
-            (ancient_slot_infos.total_alive_bytes.0 * 2 / tuning.max_ancient_slots.max(1) as u64)
-                .max(MINIMAL_IDEAL_STORAGE_SIZE),
-        )
-        .unwrap();
+        let mut ancient_slot_infos =
+            self.collect_sort_filter_ancient_slots(sorted_slots, &mut tuning);
         self.shrink_ancient_stats
             .ideal_storage_size
             .store(tuning.ideal_storage_size.into(), Ordering::Relaxed);
@@ -528,9 +522,16 @@ impl AccountsDb {
     fn collect_sort_filter_ancient_slots(
         &self,
         slots: Vec<Slot>,
-        tuning: &PackedAncientStorageTuning,
+        tuning: &mut PackedAncientStorageTuning,
     ) -> AncientSlotInfos {
         let mut ancient_slot_infos = self.calc_ancient_slot_info(slots, tuning);
+        // ideal storage size is total alive bytes of ancient storages
+        // divided by half of max ancient slots
+        tuning.ideal_storage_size = NonZeroU64::new(
+            (ancient_slot_infos.total_alive_bytes.0 * 2 / tuning.max_ancient_slots.max(1) as u64)
+                .max(MINIMAL_IDEAL_STORAGE_SIZE),
+        )
+        .unwrap();
 
         ancient_slot_infos.filter_ancient_slots(tuning, &self.shrink_ancient_stats);
         ancient_slot_infos
@@ -2584,7 +2585,7 @@ pub mod tests {
                 let alive_bytes_expected = storage.alive_bytes();
                 let high_slot = false;
                 let is_candidate_for_shrink = db.is_candidate_for_shrink(&storage);
-                let tuning = PackedAncientStorageTuning {
+                let mut tuning = PackedAncientStorageTuning {
                     percent_of_alive_shrunk_data: 100,
                     max_ancient_slots: 0,
                     // irrelevant for what this test is trying to test, but necessary to avoid minimums
@@ -2608,7 +2609,7 @@ pub mod tests {
                         infos = db.calc_ancient_slot_info(vec![slot1], &tuning);
                     }
                     TestCollectInfo::CollectSortFilterInfo => {
-                        infos = db.collect_sort_filter_ancient_slots(vec![slot1], &tuning);
+                        infos = db.collect_sort_filter_ancient_slots(vec![slot1], &mut tuning);
                     }
                 }
                 assert_eq!(infos.all_infos.len(), 1, "{method:?}");
@@ -2794,7 +2795,7 @@ pub mod tests {
                             continue; // unsupportable
                         }
                         TestCollectInfo::CollectSortFilterInfo => {
-                            let tuning = PackedAncientStorageTuning {
+                            let mut tuning = PackedAncientStorageTuning {
                                 percent_of_alive_shrunk_data: 100,
                                 max_ancient_slots: 0,
                                 // irrelevant
@@ -2805,7 +2806,7 @@ pub mod tests {
                                 can_randomly_shrink,
                                 ..default_tuning()
                             };
-                            db.collect_sort_filter_ancient_slots(slot_vec.clone(), &tuning)
+                            db.collect_sort_filter_ancient_slots(slot_vec.clone(), &mut tuning)
                         }
                     };
                     assert_eq!(infos.all_infos.len(), 1, "method: {method:?}");
@@ -3168,7 +3169,7 @@ pub mod tests {
     #[test]
     fn test_calc_ancient_slot_info_one_shrink_one_not() {
         let can_randomly_shrink = false;
-        let tuning = PackedAncientStorageTuning {
+        let mut tuning = PackedAncientStorageTuning {
             percent_of_alive_shrunk_data: 100,
             max_ancient_slots: 0,
             // irrelevant for what this test is trying to test, but necessary to avoid minimums
@@ -3220,7 +3221,7 @@ pub mod tests {
                     }
                     TestCollectInfo::CollectSortFilterInfo => {
                         // note this can sort infos.all_infos
-                        db.collect_sort_filter_ancient_slots(slot_vec.clone(), &tuning)
+                        db.collect_sort_filter_ancient_slots(slot_vec.clone(), &mut tuning)
                     }
                 };
 
@@ -3985,6 +3986,31 @@ pub mod tests {
         }
     }
 
+    /// The purpose of this test is to ensure the correct control flow
+    /// of calculating and using the value of the tuning parameter
+    /// `ideal_storage_size`.
+    #[test]
+    fn test_ideal_storage_size_updated_before_used() {
+        let mut tuning = PackedAncientStorageTuning {
+            percent_of_alive_shrunk_data: 100,
+            max_ancient_slots: 100,
+            ..default_tuning()
+        };
+        let data_size = 1_000_000;
+        let num_slots = tuning.max_ancient_slots;
+        let (db, slot1) =
+            create_db_with_storages_and_index(true /*alive*/, num_slots, Some(data_size));
+        let non_ancient_slot = slot1 + (2 * tuning.max_ancient_slots) as u64;
+        create_storages_and_update_index(&db, None, non_ancient_slot, 1, true, Some(data_size));
+        let mut slot_vec = (slot1..(slot1 + num_slots as Slot)).collect::<Vec<_>>();
+        slot_vec.push(non_ancient_slot);
+        let infos = db.collect_sort_filter_ancient_slots(slot_vec.clone(), &mut tuning);
+        let ideal_storage_size = tuning.ideal_storage_size.get();
+        let max_resulting_storages = tuning.max_resulting_storages.get();
+        let expected_all_infos_len = max_resulting_storages * ideal_storage_size / data_size - 1;
+        assert_eq!(infos.all_infos.len(), expected_all_infos_len as usize);
+    }
+
     #[test_case(0, 1 => 0)]
     #[test_case(1, 1 => 1)]
     #[test_case(2, 1 => 2)]