add tests for should_move_to_ancient_append_vec (#28438)
add tests for should_moev_to_ancient_append_vec
This commit is contained in:
parent
e283461d99
commit
b583ec79e1
|
@ -4172,20 +4172,30 @@ impl AccountsDb {
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
current_ancient: &mut Option<(Slot, Arc<AccountStorageEntry>)>,
|
current_ancient: &mut Option<(Slot, Arc<AccountStorageEntry>)>,
|
||||||
) -> Option<SnapshotStorage> {
|
) -> Option<SnapshotStorage> {
|
||||||
|
let can_randomly_shrink = true;
|
||||||
self.get_storages_for_slot(slot).and_then(|all_storages| {
|
self.get_storages_for_slot(slot).and_then(|all_storages| {
|
||||||
self.should_move_to_ancient_append_vec(&all_storages, current_ancient, slot)
|
self.should_move_to_ancient_append_vec(
|
||||||
.then_some(all_storages)
|
&all_storages,
|
||||||
|
current_ancient,
|
||||||
|
slot,
|
||||||
|
can_randomly_shrink,
|
||||||
|
)
|
||||||
|
.then_some(all_storages)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// return true if the accounts in this slot should be moved to an ancient append vec
|
/// return true if the accounts in this slot should be moved to an ancient append vec
|
||||||
/// otherwise, return false and the caller can skip this slot
|
/// otherwise, return false and the caller can skip this slot
|
||||||
/// side effect could be updating 'current_ancient'
|
/// side effect could be updating 'current_ancient'
|
||||||
pub fn should_move_to_ancient_append_vec(
|
/// can_randomly_shrink: true if ancient append vecs that otherwise don't qualify to be shrunk can be randomly shrunk
|
||||||
|
/// this is convenient for a running system
|
||||||
|
/// this is not useful for testing
|
||||||
|
fn should_move_to_ancient_append_vec(
|
||||||
&self,
|
&self,
|
||||||
all_storages: &SnapshotStorage,
|
all_storages: &SnapshotStorage,
|
||||||
current_ancient: &mut Option<(Slot, Arc<AccountStorageEntry>)>,
|
current_ancient: &mut Option<(Slot, Arc<AccountStorageEntry>)>,
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
|
can_randomly_shrink: bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if all_storages.len() != 1 {
|
if all_storages.len() != 1 {
|
||||||
// we are dealing with roots that are more than 1 epoch old. I chose not to support or test the case where we have > 1 append vec per slot.
|
// we are dealing with roots that are more than 1 epoch old. I chose not to support or test the case where we have > 1 append vec per slot.
|
||||||
|
@ -4199,7 +4209,8 @@ impl AccountsDb {
|
||||||
|
|
||||||
// randomly shrink ancient slots
|
// randomly shrink ancient slots
|
||||||
// this exercises the ancient shrink code more often
|
// this exercises the ancient shrink code more often
|
||||||
let random_shrink = thread_rng().gen_range(0, 100) == 0 && is_ancient(accounts);
|
let random_shrink =
|
||||||
|
can_randomly_shrink && thread_rng().gen_range(0, 100) == 0 && is_ancient(accounts);
|
||||||
|
|
||||||
if is_full_ancient(accounts) || random_shrink {
|
if is_full_ancient(accounts) || random_shrink {
|
||||||
if self.is_candidate_for_shrink(storage, true) || random_shrink {
|
if self.is_candidate_for_shrink(storage, true) || random_shrink {
|
||||||
|
@ -17050,4 +17061,158 @@ pub mod tests {
|
||||||
.remove(&root0);
|
.remove(&root0);
|
||||||
assert_eq!(db.get_sorted_potential_ancient_slots(), vec![root1]);
|
assert_eq!(db.get_sorted_potential_ancient_slots(), vec![root1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_should_move_to_ancient_append_vec() {
|
||||||
|
solana_logger::setup();
|
||||||
|
let db = AccountsDb::new_single_for_tests();
|
||||||
|
let slot5 = 5;
|
||||||
|
let tf = crate::append_vec::test_utils::get_append_vec_path(
|
||||||
|
"test_should_move_to_ancient_append_vec",
|
||||||
|
);
|
||||||
|
let write_version1 = 0;
|
||||||
|
let pubkey1 = solana_sdk::pubkey::new_rand();
|
||||||
|
let storages = sample_storage_with_entries(&tf, write_version1, slot5, &pubkey1)
|
||||||
|
.pop()
|
||||||
|
.unwrap();
|
||||||
|
let mut current_ancient = None;
|
||||||
|
|
||||||
|
let should_move =
|
||||||
|
db.should_move_to_ancient_append_vec(&storages, &mut current_ancient, slot5, false);
|
||||||
|
assert!(current_ancient.is_none());
|
||||||
|
// slot is not ancient, so it is good to move
|
||||||
|
assert!(should_move);
|
||||||
|
|
||||||
|
// try 2 storages in 1 slot, should not be able to move
|
||||||
|
current_ancient = Some((slot5, Arc::clone(&storages[0]))); // just 'some', contents don't matter
|
||||||
|
let two_storages = vec![storages[0].clone(), storages[0].clone()];
|
||||||
|
let should_move =
|
||||||
|
db.should_move_to_ancient_append_vec(&two_storages, &mut current_ancient, slot5, false);
|
||||||
|
assert!(current_ancient.is_none());
|
||||||
|
assert!(!should_move);
|
||||||
|
|
||||||
|
current_ancient = Some((slot5, Arc::clone(&storages[0]))); // just 'some', contents don't matter
|
||||||
|
let expected = current_ancient.clone().unwrap();
|
||||||
|
let should_move =
|
||||||
|
db.should_move_to_ancient_append_vec(&storages, &mut current_ancient, slot5, false);
|
||||||
|
// should have kept the same 'current_ancient'
|
||||||
|
let current = current_ancient.unwrap();
|
||||||
|
assert_eq!(current.0, slot5);
|
||||||
|
assert_eq!(current.1.slot(), slot5);
|
||||||
|
assert_eq!(current.1.slot(), expected.1.slot());
|
||||||
|
assert_eq!(current.1.append_vec_id(), expected.1.append_vec_id());
|
||||||
|
|
||||||
|
// slot is not ancient, so it is good to move
|
||||||
|
assert!(should_move);
|
||||||
|
|
||||||
|
// now, create an ancient slot and make sure that it does NOT think it needs to be moved and that it becomes the ancient append vec to use
|
||||||
|
let mut current_ancient = None;
|
||||||
|
let slot1_ancient = 1;
|
||||||
|
let ancient1 = db.create_ancient_append_vec(slot1_ancient).0.unwrap().1;
|
||||||
|
let should_move = db.should_move_to_ancient_append_vec(
|
||||||
|
&vec![ancient1.clone()],
|
||||||
|
&mut current_ancient,
|
||||||
|
slot1_ancient,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
assert!(!should_move);
|
||||||
|
let current_ancient = current_ancient.unwrap();
|
||||||
|
assert_eq!(current_ancient.1.append_vec_id(), ancient1.append_vec_id());
|
||||||
|
assert_eq!(current_ancient.0, slot1_ancient);
|
||||||
|
|
||||||
|
// current is ancient1
|
||||||
|
// try to move ancient2
|
||||||
|
// current should become ancient2
|
||||||
|
let slot2_ancient = 2;
|
||||||
|
let mut current_ancient = Some((slot1_ancient, ancient1.clone()));
|
||||||
|
let ancient2 = db.create_ancient_append_vec(slot2_ancient).0.unwrap().1;
|
||||||
|
let should_move = db.should_move_to_ancient_append_vec(
|
||||||
|
&vec![ancient2.clone()],
|
||||||
|
&mut current_ancient,
|
||||||
|
slot2_ancient,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
assert!(!should_move);
|
||||||
|
let current_ancient = current_ancient.unwrap();
|
||||||
|
assert_eq!(current_ancient.1.append_vec_id(), ancient2.append_vec_id());
|
||||||
|
assert_eq!(current_ancient.0, slot2_ancient);
|
||||||
|
|
||||||
|
// now try a full ancient append vec
|
||||||
|
let slot3_full_ancient = 3;
|
||||||
|
let mut current_ancient = None;
|
||||||
|
let full_ancient_3 = make_full_ancient_append_vec(&db, slot3_full_ancient);
|
||||||
|
let should_move = db.should_move_to_ancient_append_vec(
|
||||||
|
&vec![full_ancient_3.clone()],
|
||||||
|
&mut current_ancient,
|
||||||
|
slot3_full_ancient,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
assert!(!should_move);
|
||||||
|
assert!(current_ancient.is_none());
|
||||||
|
|
||||||
|
// now set current_ancient to something and see if it still goes to None
|
||||||
|
let mut current_ancient = Some((slot1_ancient, ancient1.clone()));
|
||||||
|
let should_move = db.should_move_to_ancient_append_vec(
|
||||||
|
&vec![full_ancient_3.clone()],
|
||||||
|
&mut current_ancient,
|
||||||
|
slot3_full_ancient,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
assert!(!should_move);
|
||||||
|
assert!(current_ancient.is_none());
|
||||||
|
|
||||||
|
// now mark the full ancient as candidate for shrink
|
||||||
|
adjust_alive_bytes(&full_ancient_3, 0);
|
||||||
|
|
||||||
|
// should shrink here, returning none for current
|
||||||
|
let mut current_ancient = None;
|
||||||
|
let should_move = db.should_move_to_ancient_append_vec(
|
||||||
|
&vec![full_ancient_3.clone()],
|
||||||
|
&mut current_ancient,
|
||||||
|
slot3_full_ancient,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
assert!(should_move);
|
||||||
|
assert!(current_ancient.is_none());
|
||||||
|
|
||||||
|
// should return true here, returning current from prior
|
||||||
|
// now set current_ancient to something and see if it still goes to None
|
||||||
|
let mut current_ancient = Some((slot1_ancient, ancient1.clone()));
|
||||||
|
let should_move = db.should_move_to_ancient_append_vec(
|
||||||
|
&vec![full_ancient_3],
|
||||||
|
&mut current_ancient,
|
||||||
|
slot3_full_ancient,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
assert!(should_move);
|
||||||
|
let current_ancient = current_ancient.unwrap();
|
||||||
|
assert_eq!(current_ancient.1.append_vec_id(), ancient1.append_vec_id());
|
||||||
|
assert_eq!(current_ancient.0, slot1_ancient);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn adjust_alive_bytes(storage: &Arc<AccountStorageEntry>, alive_bytes: usize) {
|
||||||
|
storage.alive_bytes.store(alive_bytes, Ordering::Release);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_ancient_append_vec_full(ancient: &Arc<AccountStorageEntry>) {
|
||||||
|
let vecs = vec![vec![ancient.clone()]];
|
||||||
|
while !is_full_ancient(&ancient.accounts) {
|
||||||
|
append_sample_data_to_storage(&vecs, &Pubkey::default(), 0);
|
||||||
|
}
|
||||||
|
adjust_alive_bytes(ancient, ancient.total_bytes() as usize);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_full_ancient_append_vec(db: &AccountsDb, slot: Slot) -> Arc<AccountStorageEntry> {
|
||||||
|
let full = db.create_ancient_append_vec(slot).0.unwrap().1;
|
||||||
|
make_ancient_append_vec_full(&full);
|
||||||
|
full
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_make_full_ancient_append_vec() {
|
||||||
|
let db = AccountsDb::new_single_for_tests();
|
||||||
|
let full = make_full_ancient_append_vec(&db, 1);
|
||||||
|
assert!(is_ancient(&full.accounts));
|
||||||
|
assert!(is_full_ancient(&full.accounts));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue