Calculate account refs fix (#9447)
This commit is contained in:
parent
3037eb8d4f
commit
99655206c8
|
@ -701,6 +701,74 @@ impl AccountsDB {
|
||||||
accounts_index.uncleaned_roots.clear();
|
accounts_index.uncleaned_roots.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn inc_store_counts(
|
||||||
|
no_delete_id: AppendVecId,
|
||||||
|
purges: &HashMap<Pubkey, Vec<(Slot, AccountInfo)>>,
|
||||||
|
store_counts: &mut HashMap<AppendVecId, usize>,
|
||||||
|
already_counted: &mut HashSet<AppendVecId>,
|
||||||
|
) {
|
||||||
|
if already_counted.contains(&no_delete_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*store_counts.get_mut(&no_delete_id).unwrap() += 1;
|
||||||
|
already_counted.insert(no_delete_id);
|
||||||
|
let mut affected_pubkeys = HashSet::new();
|
||||||
|
for (key, account_infos) in purges {
|
||||||
|
for (_slot, account_info) in account_infos {
|
||||||
|
if account_info.store_id == no_delete_id {
|
||||||
|
affected_pubkeys.insert(key);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for key in affected_pubkeys {
|
||||||
|
for (_slot, account_info) in purges.get(&key).unwrap() {
|
||||||
|
Self::inc_store_counts(
|
||||||
|
account_info.store_id,
|
||||||
|
purges,
|
||||||
|
store_counts,
|
||||||
|
already_counted,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calc_delete_dependencies(
|
||||||
|
accounts_index: &AccountsIndex<AccountInfo>,
|
||||||
|
purges: &HashMap<Pubkey, Vec<(Slot, AccountInfo)>>,
|
||||||
|
store_counts: &mut HashMap<AppendVecId, usize>,
|
||||||
|
) {
|
||||||
|
// Another pass to check if there are some filtered accounts which
|
||||||
|
// do not match the criteria of deleting all appendvecs which contain them
|
||||||
|
// then increment their storage count.
|
||||||
|
let mut already_counted = HashSet::new();
|
||||||
|
for (pubkey, account_infos) in purges.iter() {
|
||||||
|
let no_delete =
|
||||||
|
if account_infos.len() as u64 != accounts_index.ref_count_from_storage(&pubkey) {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
let mut no_delete = false;
|
||||||
|
for (_slot, account_info) in account_infos {
|
||||||
|
if *store_counts.get(&account_info.store_id).unwrap() != 0 {
|
||||||
|
no_delete = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
no_delete
|
||||||
|
};
|
||||||
|
if no_delete {
|
||||||
|
for (_slot_id, account_info) in account_infos {
|
||||||
|
Self::inc_store_counts(
|
||||||
|
account_info.store_id,
|
||||||
|
&purges,
|
||||||
|
store_counts,
|
||||||
|
&mut already_counted,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Purge zero lamport accounts and older rooted account states as garbage
|
// Purge zero lamport accounts and older rooted account states as garbage
|
||||||
// collection
|
// collection
|
||||||
// Only remove those accounts where the entire rooted history of the account
|
// Only remove those accounts where the entire rooted history of the account
|
||||||
|
@ -777,29 +845,8 @@ impl AccountsDB {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Another pass to check if there are some filtered accounts which
|
Self::calc_delete_dependencies(&accounts_index, &purges, &mut store_counts);
|
||||||
// do not match the criteria of deleting all appendvecs which contain them
|
|
||||||
// then increment their storage count.
|
|
||||||
for (pubkey, account_infos) in &purges {
|
|
||||||
let no_delete =
|
|
||||||
if account_infos.len() as u64 != accounts_index.ref_count_from_storage(&pubkey) {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
let mut no_delete = false;
|
|
||||||
for (_slot, account_info) in account_infos {
|
|
||||||
if *store_counts.get(&account_info.store_id).unwrap() != 0 {
|
|
||||||
no_delete = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
no_delete
|
|
||||||
};
|
|
||||||
if no_delete {
|
|
||||||
for (_slot, account_info) in account_infos {
|
|
||||||
*store_counts.get_mut(&account_info.store_id).unwrap() += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
store_counts_time.stop();
|
store_counts_time.stop();
|
||||||
|
|
||||||
// Only keep purges where the entire history of the account in the root set
|
// Only keep purges where the entire history of the account in the root set
|
||||||
|
@ -3842,4 +3889,69 @@ pub mod tests {
|
||||||
accounts.all_account_count_in_append_vec(shrink_slot)
|
accounts.all_account_count_in_append_vec(shrink_slot)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_delete_dependencies() {
|
||||||
|
solana_logger::setup();
|
||||||
|
let mut accounts_index = AccountsIndex::default();
|
||||||
|
let key0 = Pubkey::new_from_array([0u8; 32]);
|
||||||
|
let key1 = Pubkey::new_from_array([1u8; 32]);
|
||||||
|
let key2 = Pubkey::new_from_array([2u8; 32]);
|
||||||
|
let info0 = AccountInfo {
|
||||||
|
store_id: 0,
|
||||||
|
offset: 0,
|
||||||
|
lamports: 0,
|
||||||
|
};
|
||||||
|
let info1 = AccountInfo {
|
||||||
|
store_id: 1,
|
||||||
|
offset: 0,
|
||||||
|
lamports: 0,
|
||||||
|
};
|
||||||
|
let info2 = AccountInfo {
|
||||||
|
store_id: 2,
|
||||||
|
offset: 0,
|
||||||
|
lamports: 0,
|
||||||
|
};
|
||||||
|
let info3 = AccountInfo {
|
||||||
|
store_id: 3,
|
||||||
|
offset: 0,
|
||||||
|
lamports: 0,
|
||||||
|
};
|
||||||
|
let mut reclaims = vec![];
|
||||||
|
accounts_index.insert(0, &key0, info0.clone(), &mut reclaims);
|
||||||
|
accounts_index.insert(1, &key0, info1.clone(), &mut reclaims);
|
||||||
|
accounts_index.insert(1, &key1, info1.clone(), &mut reclaims);
|
||||||
|
accounts_index.insert(2, &key1, info2.clone(), &mut reclaims);
|
||||||
|
accounts_index.insert(2, &key2, info2.clone(), &mut reclaims);
|
||||||
|
accounts_index.insert(3, &key2, info3.clone(), &mut reclaims);
|
||||||
|
accounts_index.add_root(0);
|
||||||
|
accounts_index.add_root(1);
|
||||||
|
accounts_index.add_root(2);
|
||||||
|
accounts_index.add_root(3);
|
||||||
|
let mut purges = HashMap::new();
|
||||||
|
purges.insert(key0, accounts_index.would_purge(&key0));
|
||||||
|
purges.insert(key1, accounts_index.would_purge(&key1));
|
||||||
|
purges.insert(key2, accounts_index.would_purge(&key2));
|
||||||
|
for (key, list) in &purges {
|
||||||
|
info!(" purge {} =>", key);
|
||||||
|
for x in list {
|
||||||
|
info!(" {:?}", x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut store_counts = HashMap::new();
|
||||||
|
store_counts.insert(0, 0);
|
||||||
|
store_counts.insert(1, 0);
|
||||||
|
store_counts.insert(2, 0);
|
||||||
|
store_counts.insert(3, 1);
|
||||||
|
AccountsDB::calc_delete_dependencies(&accounts_index, &purges, &mut store_counts);
|
||||||
|
let mut stores: Vec<_> = store_counts.keys().cloned().collect();
|
||||||
|
stores.sort();
|
||||||
|
for store in &stores {
|
||||||
|
info!("store: {:?} : {}", store, store_counts.get(&store).unwrap());
|
||||||
|
}
|
||||||
|
for x in 0..3 {
|
||||||
|
assert!(store_counts[&x] >= 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue