Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move ideal_storage_size calculation before it is used #3250

Merged
merged 2 commits into from
Oct 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 41 additions & 15 deletions accounts-db/src/ancient_append_vecs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a test for this, i.e. after we call collect_sort_filter_ancinet_slots() make sure that ideal_storage_size is updated?

// 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
Expand Down Expand Up @@ -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
Expand All @@ -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:?}");
Expand Down Expand Up @@ -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
Expand All @@ -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:?}");
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
};

Expand Down Expand Up @@ -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)]
Expand Down
Loading