diff --git a/accounts-db/src/ancient_append_vecs.rs b/accounts-db/src/ancient_append_vecs.rs index a53821b017c3ec..23cc93fb4f0833 100644 --- a/accounts-db/src/ancient_append_vecs.rs +++ b/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, - 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::>(); + 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)]