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

Commit

Permalink
extract ancient maybe_unref_accounts_already_in_ancient (#28610)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffwashington authored Oct 26, 2022
1 parent c0f1ffb commit decf3de
Showing 1 changed file with 57 additions and 19 deletions.
76 changes: 57 additions & 19 deletions runtime/src/accounts_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,56 @@ enum LoadZeroLamports {
SomeWithZeroLamportAccountForTests,
}

#[derive(Debug)]
struct AncientSlotPubkeysInner {
pubkeys: HashSet<Pubkey>,
slot: Slot,
}

#[derive(Debug, Default)]
struct AncientSlotPubkeys {
inner: Option<AncientSlotPubkeysInner>,
}

impl AncientSlotPubkeys {
/// All accounts in 'slot' will be moved to 'current_ancient'
/// If 'slot' is different than the 'current_ancient'.slot, then an account in 'slot' may ALREADY be in the current ancient append vec.
/// In that case, we need to unref the pubkey because it will now only be referenced from 'current_ancient'.slot and no longer from 'slot'.
/// 'self' is also changed to accumulate the pubkeys that now exist in 'current_ancient'
/// When 'slot' differs from the previous inner slot, then we have moved to a new ancient append vec, and inner.pubkeys gets reset to the
/// pubkeys in the new 'current_ancient'.append_vec
fn maybe_unref_accounts_already_in_ancient(
&mut self,
slot: Slot,
db: &AccountsDb,
current_ancient: &CurrentAncientAppendVec,
to_store: &AccountsToStore,
) {
if slot != current_ancient.slot() {
// we are taking accounts from 'slot' and putting them into 'ancient_slot'
let (accounts, _hashes) = to_store.get(StorageSelector::Primary);
if Some(current_ancient.slot()) != self.inner.as_ref().map(|ap| ap.slot) {
let pubkeys = current_ancient
.append_vec()
.accounts
.account_iter()
.map(|account| account.meta.pubkey)
.collect::<HashSet<_>>();
self.inner = Some(AncientSlotPubkeysInner {
pubkeys,
slot: current_ancient.slot(),
});
}
// accounts in 'slot' but ALSO already in the ancient append vec at a different slot need to be unref'd since 'slot' is going away
// unwrap cannot fail because the code above will cause us to set it to Some(...) if it is None
db.unref_accounts_already_in_storage(
accounts,
self.inner.as_mut().map(|p| &mut p.pubkeys).unwrap(),
);
}
}
}

struct ShrinkCollect<'a> {
original_bytes: u64,
store_ids: Vec<AppendVecId>,
Expand Down Expand Up @@ -4362,8 +4412,7 @@ impl AccountsDb {
let mut dropped_roots = vec![];

// we have to keep track of what pubkeys exist in the current ancient append vec so we can unref correctly
let mut ancient_pubkeys = HashSet::default();
let mut ancient_slot_with_pubkeys = None;
let mut ancient_slot_pubkeys = AncientSlotPubkeys::default();

let len = sorted_slots.len();
for slot in sorted_slots {
Expand Down Expand Up @@ -4410,23 +4459,12 @@ impl AccountsDb {
// if this slot is not the ancient slot we're writing to, then this root will be dropped
let mut drop_root = slot != current_ancient.slot();

if slot != current_ancient.slot() {
// we are taking accounts from 'slot' and putting them into 'ancient_slot'
let (accounts, _hashes) = to_store.get(StorageSelector::Primary);
if Some(current_ancient.slot()) != ancient_slot_with_pubkeys {
// 'ancient_slot_with_pubkeys' is a local, re-used only for the set of slots we're iterating right now.
// the first time or when we change to a new ancient append vec, we need to recreate the set of ancient pubkeys here.
ancient_slot_with_pubkeys = Some(current_ancient.slot());
ancient_pubkeys = current_ancient
.append_vec()
.accounts
.account_iter()
.map(|account| account.meta.pubkey)
.collect::<HashSet<_>>();
}
// accounts in 'slot' but ALSO already in the ancient append vec at a different slot need to be unref'd since 'slot' is going away
self.unref_accounts_already_in_storage(accounts, &mut ancient_pubkeys);
}
ancient_slot_pubkeys.maybe_unref_accounts_already_in_ancient(
slot,
self,
&current_ancient,
&to_store,
);

let mut rewrite_elapsed = Measure::start("rewrite_elapsed");
// write what we can to the current ancient storage
Expand Down

0 comments on commit decf3de

Please sign in to comment.