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

Commit f085c3d

Browse files
committed
Calculate account refs fix
1 parent ae5a641 commit f085c3d

File tree

1 file changed

+118
-23
lines changed

1 file changed

+118
-23
lines changed

runtime/src/accounts_db.rs

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

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

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-
}
849+
Self::calc_delete_dependencies(&accounts_index, &purges, &mut store_counts);
850+
803851
store_counts_time.stop();
804852

805853
// Only keep purges where the entire history of the account in the root set
@@ -3842,4 +3890,51 @@ pub mod tests {
38423890
accounts.all_account_count_in_append_vec(shrink_slot)
38433891
);
38443892
}
3893+
3894+
#[test]
3895+
fn test_delete_dependencies() {
3896+
let mut accounts_index = AccountsIndex::default();
3897+
let key0 = Pubkey::new_rand();
3898+
let key1 = Pubkey::new_rand();
3899+
let key2 = Pubkey::new_rand();
3900+
let info0 = AccountInfo {
3901+
store_id: 0,
3902+
offset: 0,
3903+
lamports: 0,
3904+
};
3905+
let info1 = AccountInfo {
3906+
store_id: 1,
3907+
offset: 0,
3908+
lamports: 0,
3909+
};
3910+
let info2 = AccountInfo {
3911+
store_id: 2,
3912+
offset: 0,
3913+
lamports: 0,
3914+
};
3915+
let info3 = AccountInfo {
3916+
store_id: 3,
3917+
offset: 0,
3918+
lamports: 0,
3919+
};
3920+
let mut reclaims = vec![];
3921+
accounts_index.insert(0, &key0, info0.clone(), &mut reclaims);
3922+
accounts_index.insert(1, &key0, info1.clone(), &mut reclaims);
3923+
accounts_index.insert(1, &key1, info1.clone(), &mut reclaims);
3924+
accounts_index.insert(2, &key1, info2.clone(), &mut reclaims);
3925+
accounts_index.insert(2, &key2, info2.clone(), &mut reclaims);
3926+
accounts_index.insert(3, &key2, info3.clone(), &mut reclaims);
3927+
let mut purges = HashMap::new();
3928+
purges.insert(key0, vec![(0, info0)]);
3929+
purges.insert(key1, vec![(1, info1)]);
3930+
purges.insert(key2, vec![(2, info2)]);
3931+
let mut store_counts = HashMap::new();
3932+
store_counts.insert(0, 2);
3933+
store_counts.insert(1, 2);
3934+
store_counts.insert(2, 2);
3935+
store_counts.insert(3, 2);
3936+
AccountsDB::calc_delete_dependencies(&accounts_index, &purges, &mut store_counts);
3937+
info!("store_counts: {:?}", store_counts);
3938+
assert_eq!(store_counts[&0], 4);
3939+
}
38453940
}

0 commit comments

Comments
 (0)