Skip to content

Commit

Permalink
fix a few storage iter lifetimes (solana-labs#917)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffwashington authored Apr 19, 2024
1 parent 3467dba commit fc2b05d
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 74 deletions.
10 changes: 6 additions & 4 deletions accounts-db/src/accounts_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8555,8 +8555,7 @@ impl AccountsDb {
rent_collector: &RentCollector,
storage_info: &StorageSizeAndCountMap,
) -> SlotIndexGenerationInfo {
let mut accounts = storage.accounts.account_iter();
if accounts.next().is_none() {
if storage.accounts.get_account_sizes(&[0]).is_empty() {
return SlotIndexGenerationInfo::default();
}
let secondary = !self.account_indexes.is_empty();
Expand Down Expand Up @@ -16939,11 +16938,14 @@ pub mod tests {
if count_marked_dead >= dead_accounts {
break;
}
let original = original.accounts.account_iter().next().unwrap();
let original_pubkey = original
.accounts
.get_stored_account_meta_callback(0, |account| *account.pubkey())
.unwrap();
let slot = ancient_slot + 1 + (count_marked_dead as Slot);
_ = db.purge_keys_exact(
[(
*original.pubkey(),
original_pubkey,
vec![slot].into_iter().collect::<HashSet<_>>(),
)]
.iter(),
Expand Down
143 changes: 73 additions & 70 deletions accounts-db/src/ancient_append_vecs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3160,77 +3160,80 @@ pub mod tests {
let data_size = None;
let (_db, storages, _slots, _infos) = get_sample_storages(num_slots, data_size);

let account = storages[0].accounts.get_stored_account_meta(0).unwrap().0;
let slot = 1;
let capacity = 0;
for i in 0..4usize {
let mut alive_accounts =
ShrinkCollectAliveSeparatedByRefs::with_capacity(capacity, slot);
let lamports = 1;

match i {
0 => {
// empty slot list (ignored anyway) because ref_count = 1
let slot_list = vec![];
alive_accounts.add(1, &account, &slot_list);
assert!(!alive_accounts.one_ref.accounts.is_empty());
assert!(alive_accounts.many_refs_old_alive.accounts.is_empty());
assert!(alive_accounts
.many_refs_this_is_newest_alive
.accounts
.is_empty());
}
1 => {
// non-empty slot list (but ignored) because slot_list = 1
let slot_list =
vec![(slot, AccountInfo::new(StorageLocation::Cached, lamports))];
alive_accounts.add(2, &account, &slot_list);
assert!(alive_accounts.one_ref.accounts.is_empty());
assert!(alive_accounts.many_refs_old_alive.accounts.is_empty());
assert!(!alive_accounts
.many_refs_this_is_newest_alive
.accounts
.is_empty());
}
2 => {
// multiple slot list, ref_count=2, this is NOT newest alive, so many_refs_old_alive
let slot_list = vec![
(slot, AccountInfo::new(StorageLocation::Cached, lamports)),
(
slot + 1,
AccountInfo::new(StorageLocation::Cached, lamports),
),
];
alive_accounts.add(2, &account, &slot_list);
assert!(alive_accounts.one_ref.accounts.is_empty());
assert!(!alive_accounts.many_refs_old_alive.accounts.is_empty());
assert!(alive_accounts
.many_refs_this_is_newest_alive
.accounts
.is_empty());
}
3 => {
// multiple slot list, ref_count=2, this is newest
let slot_list = vec![
(slot, AccountInfo::new(StorageLocation::Cached, lamports)),
(
slot - 1,
AccountInfo::new(StorageLocation::Cached, lamports),
),
];
alive_accounts.add(2, &account, &slot_list);
assert!(alive_accounts.one_ref.accounts.is_empty());
assert!(alive_accounts.many_refs_old_alive.accounts.is_empty());
assert!(!alive_accounts
.many_refs_this_is_newest_alive
.accounts
.is_empty());
}
_ => {
panic!("unexpected");
storages[0]
.accounts
.get_stored_account_meta_callback(0, |account| {
let slot = 1;
let capacity = 0;
for i in 0..4usize {
let mut alive_accounts =
ShrinkCollectAliveSeparatedByRefs::with_capacity(capacity, slot);
let lamports = 1;

match i {
0 => {
// empty slot list (ignored anyway) because ref_count = 1
let slot_list = vec![];
alive_accounts.add(1, &account, &slot_list);
assert!(!alive_accounts.one_ref.accounts.is_empty());
assert!(alive_accounts.many_refs_old_alive.accounts.is_empty());
assert!(alive_accounts
.many_refs_this_is_newest_alive
.accounts
.is_empty());
}
1 => {
// non-empty slot list (but ignored) because slot_list = 1
let slot_list =
vec![(slot, AccountInfo::new(StorageLocation::Cached, lamports))];
alive_accounts.add(2, &account, &slot_list);
assert!(alive_accounts.one_ref.accounts.is_empty());
assert!(alive_accounts.many_refs_old_alive.accounts.is_empty());
assert!(!alive_accounts
.many_refs_this_is_newest_alive
.accounts
.is_empty());
}
2 => {
// multiple slot list, ref_count=2, this is NOT newest alive, so many_refs_old_alive
let slot_list = vec![
(slot, AccountInfo::new(StorageLocation::Cached, lamports)),
(
slot + 1,
AccountInfo::new(StorageLocation::Cached, lamports),
),
];
alive_accounts.add(2, &account, &slot_list);
assert!(alive_accounts.one_ref.accounts.is_empty());
assert!(!alive_accounts.many_refs_old_alive.accounts.is_empty());
assert!(alive_accounts
.many_refs_this_is_newest_alive
.accounts
.is_empty());
}
3 => {
// multiple slot list, ref_count=2, this is newest
let slot_list = vec![
(slot, AccountInfo::new(StorageLocation::Cached, lamports)),
(
slot - 1,
AccountInfo::new(StorageLocation::Cached, lamports),
),
];
alive_accounts.add(2, &account, &slot_list);
assert!(alive_accounts.one_ref.accounts.is_empty());
assert!(alive_accounts.many_refs_old_alive.accounts.is_empty());
assert!(!alive_accounts
.many_refs_this_is_newest_alive
.accounts
.is_empty());
}
_ => {
panic!("unexpected");
}
}
}
}
}
});
}

#[test]
Expand Down

0 comments on commit fc2b05d

Please sign in to comment.