Adds get_and_then() & family to AccountsIndex (#35218)

This commit is contained in:
Brooks 2024-02-19 10:22:00 -05:00 committed by GitHub
parent ebf60359f4
commit 2ec136a1ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 44 additions and 41 deletions

View File

@ -9924,11 +9924,11 @@ pub mod tests {
.store(data.len(), Ordering::Relaxed);
let genesis_config = GenesisConfig::default();
assert!(db.accounts_index.get_account_read_entry(&pubkey).is_none());
assert!(!db.accounts_index.contains(&pubkey));
let result = db.generate_index(None, false, &genesis_config);
// index entry should only contain a single entry for the pubkey since index cannot hold more than 1 entry per slot
let entry = db.accounts_index.get_account_read_entry(&pubkey).unwrap();
assert_eq!(entry.slot_list().len(), 1);
let entry = db.accounts_index.get_cloned(&pubkey).unwrap();
assert_eq!(entry.slot_list.read().unwrap().len(), 1);
assert_eq!(append_vec.alive_bytes(), expected_alive_bytes);
// total # accounts in append vec
assert_eq!(append_vec.approx_stored_count(), 2);
@ -11409,16 +11409,14 @@ pub mod tests {
let key = Pubkey::default();
let account0 = AccountSharedData::new(1, 0, &key);
let ancestors = vec![(unrooted_slot, 1)].into_iter().collect();
assert!(!db.accounts_index.contains(&key));
if is_cached {
db.store_cached((unrooted_slot, &[(&key, &account0)][..]), None);
} else {
db.store_for_tests(unrooted_slot, &[(&key, &account0)]);
}
assert!(db.get_bank_hash_stats(unrooted_slot).is_some());
assert!(db
.accounts_index
.get(&key, Some(&ancestors), None)
.is_some());
assert!(db.accounts_index.contains(&key));
db.assert_load_account(unrooted_slot, key, 1);
// Purge the slot
@ -11427,11 +11425,7 @@ pub mod tests {
assert!(db.get_bank_hash_stats(unrooted_slot).is_none());
assert!(db.accounts_cache.slot_cache(unrooted_slot).is_none());
assert!(db.storage.get_slot_storage_entry(unrooted_slot).is_none());
assert!(db.accounts_index.get_account_read_entry(&key).is_none());
assert!(db
.accounts_index
.get(&key, Some(&ancestors), None)
.is_none());
assert!(!db.accounts_index.contains(&key));
// Test we can store for the same slot again and get the right information
let account0 = AccountSharedData::new(2, 0, &key);
@ -12189,11 +12183,8 @@ pub mod tests {
// The earlier entry for pubkey in the account index is purged,
let (slot_list_len, index_slot) = {
let account_entry = accounts
.accounts_index
.get_account_read_entry(&pubkey)
.unwrap();
let slot_list = account_entry.slot_list();
let account_entry = accounts.accounts_index.get_cloned(&pubkey).unwrap();
let slot_list = account_entry.slot_list.read().unwrap();
(slot_list.len(), slot_list[0].0)
};
assert_eq!(slot_list_len, 1);
@ -12258,10 +12249,7 @@ pub mod tests {
accounts.print_accounts_stats("post_purge");
// Make sure the index is for pubkey cleared
assert!(accounts
.accounts_index
.get_account_read_entry(&pubkey)
.is_none());
assert!(!accounts.accounts_index.contains(&pubkey));
// slot 1 & 2 should not have any stores
assert_no_stores(&accounts, 1);
@ -13833,10 +13821,7 @@ pub mod tests {
assert!(db
.load_without_fixed_root(&ancestors, &unrooted_key)
.is_some());
assert!(db
.accounts_index
.get_account_read_entry(&unrooted_key)
.is_some());
assert!(db.accounts_index.contains(&unrooted_key));
assert_eq!(db.accounts_cache.num_slots(), 1);
assert!(db.accounts_cache.slot_cache(unrooted_slot).is_some());
assert_eq!(
@ -14368,12 +14353,13 @@ pub mod tests {
let before_size = storage0.alive_bytes.load(Ordering::Acquire);
let account_info = accounts_db
.accounts_index
.get_account_read_entry(account.pubkey())
.map(|locked_entry| {
// Should only be one entry per key, since every key was only stored to slot 0
locked_entry.slot_list()[0]
})
.unwrap();
.get_cloned(account.pubkey())
.unwrap()
.slot_list
.read()
.unwrap()
// Should only be one entry per key, since every key was only stored to slot 0
[0];
assert_eq!(account_info.0, slot);
let reclaims = [account_info];
accounts_db.remove_dead_accounts(reclaims.iter(), None, None, true);
@ -15335,8 +15321,7 @@ pub mod tests {
assert_no_storages_at_slot(&db, *slot);
assert!(db.accounts_cache.slot_cache(*slot).is_none());
let account_in_slot = slot_to_pubkey_map[slot];
let item = db.accounts_index.get_account_read_entry(&account_in_slot);
assert!(item.is_none(), "item: {item:?}");
assert!(!db.accounts_index.contains(&account_in_slot));
}
// Wait for flush to finish before starting next trial
@ -15722,20 +15707,14 @@ pub mod tests {
// The later rooted zero-lamport update to `shared_key` cannot be cleaned
// because it is kept alive by the unrooted slot.
accounts.clean_accounts_for_tests();
assert!(accounts
.accounts_index
.get_account_read_entry(&shared_key)
.is_some());
assert!(accounts.accounts_index.contains(&shared_key));
// Simulate purge_slot() all from AccountsBackgroundService
accounts.purge_slot(slot0, 0, true);
// Now clean should clean up the remaining key
accounts.clean_accounts_for_tests();
assert!(accounts
.accounts_index
.get_account_read_entry(&shared_key)
.is_none());
assert!(!accounts.accounts_index.contains(&shared_key));
assert_no_storages_at_slot(&accounts, slot0);
}

View File

@ -1138,6 +1138,30 @@ impl<T: IndexValue, U: DiskIndexValue + From<T> + Into<T>> AccountsIndex<T, U> {
.map(ReadAccountMapEntry::from_account_map_entry)
}
/// Gets the index's entry for `pubkey` and applies `callback` to it
///
/// If `callback`'s boolean return value is true, add this entry to the in-mem cache.
pub fn get_and_then<R>(
&self,
pubkey: &Pubkey,
callback: impl FnOnce(Option<&AccountMapEntry<T>>) -> (bool, R),
) -> R {
self.get_bin(pubkey).get_internal(pubkey, callback)
}
/// Gets the index's entry for `pubkey` and clones it
///
/// Prefer `get_and_then()` whenever possible.
/// NOTE: The entry is *not* added to the in-mem cache.
pub fn get_cloned(&self, pubkey: &Pubkey) -> Option<AccountMapEntry<T>> {
self.get_and_then(pubkey, |entry| (false, entry.cloned()))
}
/// Is `pubkey` in the index?
pub fn contains(&self, pubkey: &Pubkey) -> bool {
self.get_and_then(pubkey, |entry| (false, entry.is_some()))
}
fn slot_list_mut<RT>(
&self,
pubkey: &Pubkey,