|
|
@@ -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)]
|