Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Commit 417a323

Browse files
committed
Calculate account refs fix
1 parent ae5a641 commit 417a323

File tree

1 file changed

+134
-23
lines changed

1 file changed

+134
-23
lines changed

runtime/src/accounts_db.rs

Lines changed: 134 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,73 @@ impl AccountsDB {
701701
accounts_index.uncleaned_roots.clear();
702702
}
703703

704+
fn inc_store_counts(
705+
no_delete_id: AppendVecId,
706+
purges: &HashMap<Pubkey, Vec<(Slot, AccountInfo)>>,
707+
store_counts: &mut HashMap<AppendVecId, usize>,
708+
already_counted: &mut HashSet<AppendVecId>,
709+
) {
710+
if already_counted.contains(&no_delete_id) {
711+
return;
712+
}
713+
*store_counts.get_mut(&no_delete_id).unwrap() += 1;
714+
already_counted.insert(no_delete_id);
715+
let mut affected_pubkeys = HashSet::new();
716+
for (key, account_infos) in purges {
717+
for (_slot, account_info) in account_infos {
718+
if account_info.store_id == no_delete_id {
719+
affected_pubkeys.insert(key);
720+
}
721+
}
722+
}
723+
for key in affected_pubkeys {
724+
for (_slot, account_info) in purges.get(&key).unwrap() {
725+
Self::inc_store_counts(
726+
account_info.store_id,
727+
purges,
728+
store_counts,
729+
already_counted,
730+
);
731+
}
732+
}
733+
}
734+
735+
fn calc_delete_dependencies(
736+
accounts_index: &AccountsIndex<AccountInfo>,
737+
purges: &HashMap<Pubkey, Vec<(Slot, AccountInfo)>>,
738+
store_counts: &mut HashMap<AppendVecId, usize>,
739+
) {
740+
// Another pass to check if there are some filtered accounts which
741+
// do not match the criteria of deleting all appendvecs which contain them
742+
// then increment their storage count.
743+
let mut already_counted = HashSet::new();
744+
for (pubkey, account_infos) in purges.iter() {
745+
let no_delete =
746+
if account_infos.len() as u64 != accounts_index.ref_count_from_storage(&pubkey) {
747+
true
748+
} else {
749+
let mut no_delete = false;
750+
for (_slot, account_info) in account_infos {
751+
if *store_counts.get(&account_info.store_id).unwrap() != 0 {
752+
no_delete = true;
753+
break;
754+
}
755+
}
756+
no_delete
757+
};
758+
if no_delete {
759+
for (_slot_id, account_info) in account_infos {
760+
Self::inc_store_counts(
761+
account_info.store_id,
762+
&purges,
763+
store_counts,
764+
&mut already_counted,
765+
);
766+
}
767+
}
768+
}
769+
}
770+
704771
// Purge zero lamport accounts and older rooted account states as garbage
705772
// collection
706773
// Only remove those accounts where the entire rooted history of the account
@@ -777,29 +844,8 @@ impl AccountsDB {
777844
}
778845
}
779846

780-
// Another pass to check if there are some filtered accounts which
781-
// do not match the criteria of deleting all appendvecs which contain them
782-
// then increment their storage count.
783-
for (pubkey, account_infos) in &purges {
784-
let no_delete =
785-
if account_infos.len() as u64 != accounts_index.ref_count_from_storage(&pubkey) {
786-
true
787-
} else {
788-
let mut no_delete = false;
789-
for (_slot, account_info) in account_infos {
790-
if *store_counts.get(&account_info.store_id).unwrap() != 0 {
791-
no_delete = true;
792-
break;
793-
}
794-
}
795-
no_delete
796-
};
797-
if no_delete {
798-
for (_slot, account_info) in account_infos {
799-
*store_counts.get_mut(&account_info.store_id).unwrap() += 1;
800-
}
801-
}
802-
}
847+
Self::calc_delete_dependencies(&accounts_index, &purges, &mut store_counts);
848+
803849
store_counts_time.stop();
804850

805851
// Only keep purges where the entire history of the account in the root set
@@ -3842,4 +3888,69 @@ pub mod tests {
38423888
accounts.all_account_count_in_append_vec(shrink_slot)
38433889
);
38443890
}
3891+
3892+
#[test]
3893+
fn test_delete_dependencies() {
3894+
solana_logger::setup();
3895+
let mut accounts_index = AccountsIndex::default();
3896+
let key0 = Pubkey::new_from_array([0u8; 32]);
3897+
let key1 = Pubkey::new_from_array([1u8; 32]);
3898+
let key2 = Pubkey::new_from_array([2u8; 32]);
3899+
let info0 = AccountInfo {
3900+
store_id: 0,
3901+
offset: 0,
3902+
lamports: 0,
3903+
};
3904+
let info1 = AccountInfo {
3905+
store_id: 1,
3906+
offset: 0,
3907+
lamports: 0,
3908+
};
3909+
let info2 = AccountInfo {
3910+
store_id: 2,
3911+
offset: 0,
3912+
lamports: 0,
3913+
};
3914+
let info3 = AccountInfo {
3915+
store_id: 3,
3916+
offset: 0,
3917+
lamports: 0,
3918+
};
3919+
let mut reclaims = vec![];
3920+
accounts_index.insert(0, &key0, info0.clone(), &mut reclaims);
3921+
accounts_index.insert(1, &key0, info1.clone(), &mut reclaims);
3922+
accounts_index.insert(1, &key1, info1.clone(), &mut reclaims);
3923+
accounts_index.insert(2, &key1, info2.clone(), &mut reclaims);
3924+
accounts_index.insert(2, &key2, info2.clone(), &mut reclaims);
3925+
accounts_index.insert(3, &key2, info3.clone(), &mut reclaims);
3926+
accounts_index.add_root(0);
3927+
accounts_index.add_root(1);
3928+
accounts_index.add_root(2);
3929+
accounts_index.add_root(3);
3930+
let mut purges = HashMap::new();
3931+
purges.insert(key0, accounts_index.would_purge(&key0));
3932+
purges.insert(key1, accounts_index.would_purge(&key1));
3933+
purges.insert(key2, accounts_index.would_purge(&key2));
3934+
for (key, list) in &purges {
3935+
info!(" purge {} =>", key);
3936+
for x in list {
3937+
info!(" {:?}", x);
3938+
}
3939+
}
3940+
3941+
let mut store_counts = HashMap::new();
3942+
store_counts.insert(0, 0);
3943+
store_counts.insert(1, 0);
3944+
store_counts.insert(2, 0);
3945+
store_counts.insert(3, 1);
3946+
AccountsDB::calc_delete_dependencies(&accounts_index, &purges, &mut store_counts);
3947+
let mut stores: Vec<_> = store_counts.keys().cloned().collect();
3948+
stores.sort();
3949+
for store in &stores {
3950+
info!("store: {:?} : {}", store, store_counts.get(&store).unwrap());
3951+
}
3952+
for x in 0..3 {
3953+
assert!(store_counts[&x] >= 1);
3954+
}
3955+
}
38453956
}

0 commit comments

Comments
 (0)