store_cached takes StorableAccounts to eliminate collect (#26109)

This commit is contained in:
Jeff Washington (jwash) 2022-06-22 09:45:03 -04:00 committed by GitHub
parent 8a18e02f80
commit d3829b1a76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 65 deletions

View File

@ -1203,11 +1203,11 @@ impl Accounts {
leave_nonce_on_success,
);
self.accounts_db
.store_cached(slot, &accounts_to_store, Some(&txn_signatures));
.store_cached((slot, &accounts_to_store[..]), Some(&txn_signatures));
}
pub fn store_accounts_cached(&self, slot: Slot, accounts: &[(&Pubkey, &AccountSharedData)]) {
self.accounts_db.store_cached(slot, accounts, None)
self.accounts_db.store_cached((slot, accounts), None)
}
/// Add a slot to root. Root slots cannot be purged

View File

@ -7374,13 +7374,12 @@ impl AccountsDb {
.fetch_add(measure.as_us(), Ordering::Relaxed);
}
pub fn store_cached(
pub fn store_cached<'a, T: ReadableAccount + Sync + ZeroLamport>(
&self,
slot: Slot,
accounts: &[(&Pubkey, &AccountSharedData)],
txn_signatures: Option<&[Option<&Signature>]>,
accounts: impl StorableAccounts<'a, T>,
txn_signatures: Option<&'a [Option<&'a Signature>]>,
) {
self.store((slot, accounts), self.caching_enabled, txn_signatures);
self.store(accounts, self.caching_enabled, txn_signatures);
}
/// Store the account update.
@ -9755,7 +9754,7 @@ pub mod tests {
let account0 = AccountSharedData::new(1, 0, &key);
let ancestors = vec![(unrooted_slot, 1)].into_iter().collect();
if is_cached {
db.store_cached(unrooted_slot, &[(&key, &account0)], None);
db.store_cached((unrooted_slot, &[(&key, &account0)][..]), None);
} else {
db.store_uncached(unrooted_slot, &[(&key, &account0)]);
}
@ -12724,13 +12723,13 @@ pub mod tests {
let account = AccountSharedData::new(1, 16 * 4096, &Pubkey::default());
let pubkey1 = solana_sdk::pubkey::new_rand();
accounts.store_cached(0, &[(&pubkey1, &account)], None);
accounts.store_cached((0, &[(&pubkey1, &account)][..]), None);
let pubkey2 = solana_sdk::pubkey::new_rand();
accounts.store_cached(0, &[(&pubkey2, &account)], None);
accounts.store_cached((0, &[(&pubkey2, &account)][..]), None);
let zero_account = AccountSharedData::new(0, 1, &Pubkey::default());
accounts.store_cached(1, &[(&pubkey1, &zero_account)], None);
accounts.store_cached((1, &[(&pubkey1, &zero_account)][..]), None);
// Add root 0 and flush separately
accounts.get_accounts_delta_hash(0);
@ -12902,7 +12901,7 @@ pub mod tests {
let key = Pubkey::default();
let account0 = AccountSharedData::new(1, 0, &key);
let slot = 0;
db.store_cached(slot, &[(&key, &account0)], None);
db.store_cached((slot, &[(&key, &account0)][..]), None);
// Load with no ancestors and no root will return nothing
assert!(db
@ -12935,7 +12934,7 @@ pub mod tests {
let key = Pubkey::default();
let account0 = AccountSharedData::new(1, 0, &key);
let slot = 0;
db.store_cached(slot, &[(&key, &account0)], None);
db.store_cached((slot, &[(&key, &account0)][..]), None);
db.mark_slot_frozen(slot);
// No root was added yet, requires an ancestor to find
@ -12968,9 +12967,9 @@ pub mod tests {
let unrooted_key = solana_sdk::pubkey::new_rand();
let key5 = solana_sdk::pubkey::new_rand();
let key6 = solana_sdk::pubkey::new_rand();
db.store_cached(unrooted_slot, &[(&unrooted_key, &account0)], None);
db.store_cached(root5, &[(&key5, &account0)], None);
db.store_cached(root6, &[(&key6, &account0)], None);
db.store_cached((unrooted_slot, &[(&unrooted_key, &account0)][..]), None);
db.store_cached((root5, &[(&key5, &account0)][..]), None);
db.store_cached((root6, &[(&key6, &account0)][..]), None);
for slot in &[unrooted_slot, root5, root6] {
db.mark_slot_frozen(*slot);
}
@ -13033,7 +13032,7 @@ pub mod tests {
let num_slots = 2 * max_cache_slots();
for i in 0..num_roots + num_unrooted {
let key = Pubkey::new_unique();
db.store_cached(i as Slot, &[(&key, &account0)], None);
db.store_cached((i as Slot, &[(&key, &account0)][..]), None);
keys.push(key);
db.mark_slot_frozen(i as Slot);
if i < num_roots {
@ -13102,8 +13101,8 @@ pub mod tests {
let zero_lamport_account =
AccountSharedData::new(0, 0, AccountSharedData::default().owner());
let slot1_account = AccountSharedData::new(1, 1, AccountSharedData::default().owner());
db.store_cached(0, &[(&account_key, &zero_lamport_account)], None);
db.store_cached(1, &[(&account_key, &slot1_account)], None);
db.store_cached((0, &[(&account_key, &zero_lamport_account)][..]), None);
db.store_cached((1, &[(&account_key, &slot1_account)][..]), None);
db.add_root(0);
db.add_root(1);
@ -13125,7 +13124,7 @@ pub mod tests {
.unwrap();
assert_eq!(account.lamports(), 1);
assert_eq!(db.read_only_accounts_cache.cache_len(), 1);
db.store_cached(2, &[(&account_key, &zero_lamport_account)], None);
db.store_cached((2, &[(&account_key, &zero_lamport_account)][..]), None);
assert_eq!(db.read_only_accounts_cache.cache_len(), 1);
let account = db
.load_with_fixed_root(&Ancestors::default(), &account_key)
@ -13150,8 +13149,8 @@ pub mod tests {
let zero_lamport_account =
AccountSharedData::new(0, 0, AccountSharedData::default().owner());
let slot1_account = AccountSharedData::new(1, 1, AccountSharedData::default().owner());
db.store_cached(0, &[(&account_key, &zero_lamport_account)], None);
db.store_cached(1, &[(&account_key, &slot1_account)], None);
db.store_cached((0, &[(&account_key, &zero_lamport_account)][..]), None);
db.store_cached((1, &[(&account_key, &slot1_account)][..]), None);
db.add_root(0);
db.add_root(1);
@ -13205,18 +13204,20 @@ pub mod tests {
AccountSharedData::new(0, 0, AccountSharedData::default().owner());
// Store into slot 0, and then flush the slot to storage
db.store_cached(0, &[(&zero_lamport_account_key, &slot0_account)], None);
db.store_cached(
(0, &[(&zero_lamport_account_key, &slot0_account)][..]),
None,
);
// Second key keeps other lamport account entry for slot 0 alive,
// preventing clean of the zero_lamport_account in slot 1.
db.store_cached(0, &[(&other_account_key, &slot0_account)], None);
db.store_cached((0, &[(&other_account_key, &slot0_account)][..]), None);
db.add_root(0);
db.flush_accounts_cache(true, None);
assert!(!db.storage.get_slot_storage_entries(0).unwrap().is_empty());
// Store into slot 1, a dummy slot that will be dead and purged before flush
db.store_cached(
1,
&[(&zero_lamport_account_key, &zero_lamport_account)],
(1, &[(&zero_lamport_account_key, &zero_lamport_account)][..]),
None,
);
@ -13227,8 +13228,7 @@ pub mod tests {
// the refcount in the index. This means clean should *not* remove
// `zero_lamport_account_key` from slot 2
db.store_cached(
2,
&[(&zero_lamport_account_key, &zero_lamport_account)],
(2, &[(&zero_lamport_account_key, &zero_lamport_account)][..]),
None,
);
db.add_root(1);
@ -13352,11 +13352,11 @@ pub mod tests {
/ \
1 2 (root)
*/
db.store_cached(0, &[(&account_key, &zero_lamport_account)], None);
db.store_cached(1, &[(&account_key, &slot1_account)], None);
db.store_cached((0, &[(&account_key, &zero_lamport_account)][..]), None);
db.store_cached((1, &[(&account_key, &slot1_account)][..]), None);
// Fodder for the scan so that the lock on `account_key` is not held
db.store_cached(1, &[(&account_key2, &slot1_account)], None);
db.store_cached(2, &[(&account_key, &slot2_account)], None);
db.store_cached((1, &[(&account_key2, &slot1_account)][..]), None);
db.store_cached((2, &[(&account_key, &slot2_account)][..]), None);
db.get_accounts_delta_hash(0);
let max_scan_root = 0;
@ -13450,7 +13450,7 @@ pub mod tests {
for data_size in 0..num_keys {
let account = AccountSharedData::new(1, data_size, &Pubkey::default());
accounts_db.store_cached(slot, &[(&Pubkey::new_unique(), &account)], None);
accounts_db.store_cached((slot, &[(&Pubkey::new_unique(), &account)][..]), None);
}
accounts_db.add_root(slot);
@ -13513,11 +13513,13 @@ pub mod tests {
if scan_slot.is_some() {
accounts_db.store_cached(
// Store it in a slot that isn't returned in `slots`
stall_slot,
&[(
&scan_stall_key,
&AccountSharedData::new(1, 0, &Pubkey::default()),
)],
(
stall_slot,
&[(
&scan_stall_key,
&AccountSharedData::new(1, 0, &Pubkey::default()),
)][..],
),
None,
);
}
@ -13528,8 +13530,10 @@ pub mod tests {
for key in &keys[*slot as usize..] {
let space = 1; // 1 byte allows us to track by size
accounts_db.store_cached(
*slot,
&[(key, &AccountSharedData::new(1, space, &Pubkey::default()))],
(
*slot,
&[(key, &AccountSharedData::new(1, space, &Pubkey::default()))][..],
),
None,
);
}
@ -13573,8 +13577,10 @@ pub mod tests {
for key in &keys {
// Store a slot that overwrites all previous keys, rendering all previous keys dead
accounts_db.store_cached(
alive_slot,
&[(key, &AccountSharedData::new(1, 0, &Pubkey::default()))],
(
alive_slot,
&[(key, &AccountSharedData::new(1, 0, &Pubkey::default()))][..],
),
None,
);
accounts_db.add_root(alive_slot);
@ -13913,8 +13919,8 @@ pub mod tests {
let account1 = AccountSharedData::new(1, 0, AccountSharedData::default().owner());
// Store into slot 0
db.store_cached(0, &[(&account_key1, &account1)], None);
db.store_cached(0, &[(&account_key2, &account1)], None);
db.store_cached((0, &[(&account_key1, &account1)][..]), None);
db.store_cached((0, &[(&account_key2, &account1)][..]), None);
db.add_root(0);
if !do_intra_cache_clean {
// If we don't want the cache doing purges before flush,
@ -13928,7 +13934,7 @@ pub mod tests {
}
// Make account_key1 in slot 0 outdated by updating in rooted slot 1
db.store_cached(1, &[(&account_key1, &account1)], None);
db.store_cached((1, &[(&account_key1, &account1)][..]), None);
db.add_root(1);
// Flushes all roots
db.flush_accounts_cache(true, None);
@ -13952,7 +13958,7 @@ pub mod tests {
db.shrink_candidate_slots();
// Make slot 0 dead by updating the remaining key
db.store_cached(2, &[(&account_key2, &account1)], None);
db.store_cached((2, &[(&account_key2, &account1)][..]), None);
db.add_root(2);
// Flushes all roots
@ -14176,11 +14182,13 @@ pub mod tests {
let pubkey = Arc::new(Pubkey::new_unique());
let exit = Arc::new(AtomicBool::new(false));
db.store_cached(
0,
&[(
&pubkey,
&AccountSharedData::new(1, 0, AccountSharedData::default().owner()),
)],
(
0,
&[(
pubkey.as_ref(),
&AccountSharedData::new(1, 0, AccountSharedData::default().owner()),
)][..],
),
None,
);
db.add_root(0);
@ -14194,13 +14202,13 @@ pub mod tests {
std::thread::Builder::new()
.name("account-cache-flush".to_string())
.spawn(move || {
let mut slot = 1;
let mut slot: Slot = 1;
loop {
if exit.load(Ordering::Relaxed) {
return;
}
account.set_lamports(slot + 1);
db.store_cached(slot, &[(&pubkey, &account)], None);
db.store_cached((slot, &[(pubkey.as_ref(), &account)][..]), None);
db.add_root(slot);
sleep(Duration::from_millis(RACY_SLEEP_MS));
db.flush_accounts_cache(true, None);
@ -14368,7 +14376,7 @@ pub mod tests {
let num_trials = 10;
for _ in 0..num_trials {
let pubkey = Pubkey::new_unique();
db.store_cached(slot, &[(&pubkey, &account)], None);
db.store_cached((slot, &[(&pubkey, &account)][..]), None);
// Wait for both threads to finish
flush_trial_start_sender.send(()).unwrap();
remove_trial_start_sender.send(()).unwrap();
@ -14459,7 +14467,7 @@ pub mod tests {
let slot_to_pubkey_map: HashMap<Slot, Pubkey> = (0..num_cached_slots)
.map(|slot| {
let pubkey = Pubkey::new_unique();
db.store_cached(slot, &[(&pubkey, &account)], None);
db.store_cached((slot, &[(&pubkey, &account)][..]), None);
(slot, pubkey)
})
.collect();
@ -14888,21 +14896,21 @@ pub mod tests {
let owner = solana_sdk::pubkey::new_rand();
let space = 0;
let slot1 = 1;
let slot1: Slot = 1;
let account = AccountSharedData::new(111, space, &owner);
accounts_db.store_cached(slot1, &[(&pubkey, &account)], None);
accounts_db.store_cached((slot1, &[(&pubkey, &account)][..]), None);
accounts_db.get_accounts_delta_hash(slot1);
accounts_db.add_root(slot1);
let slot2 = 2;
let slot2: Slot = 2;
let account = AccountSharedData::new(222, space, &owner);
accounts_db.store_cached(slot2, &[(&pubkey, &account)], None);
accounts_db.store_cached((slot2, &[(&pubkey, &account)][..]), None);
accounts_db.get_accounts_delta_hash(slot2);
accounts_db.add_root(slot2);
let slot3 = 3;
let slot3: Slot = 3;
let account = AccountSharedData::new(0, space, &owner);
accounts_db.store_cached(slot3, &[(&pubkey, &account)], None);
accounts_db.store_cached((slot3, &[(&pubkey, &account)][..]), None);
accounts_db.get_accounts_delta_hash(slot3);
accounts_db.add_root(slot3);

View File

@ -340,24 +340,24 @@ pub mod tests {
let account1 =
AccountSharedData::new(account1_lamports1, 1, AccountSharedData::default().owner());
let slot0 = 0;
accounts.store_cached(slot0, &[(&key1, &account1)], None);
accounts.store_cached((slot0, &[(&key1, &account1)][..]), None);
let key2 = solana_sdk::pubkey::new_rand();
let account2_lamports: u64 = 200;
let account2 =
AccountSharedData::new(account2_lamports, 1, AccountSharedData::default().owner());
accounts.store_cached(slot0, &[(&key2, &account2)], None);
accounts.store_cached((slot0, &[(&key2, &account2)][..]), None);
let account1_lamports2 = 2;
let slot1 = 1;
let account1 = AccountSharedData::new(account1_lamports2, 1, account1.owner());
accounts.store_cached(slot1, &[(&key1, &account1)], None);
accounts.store_cached((slot1, &[(&key1, &account1)][..]), None);
let key3 = solana_sdk::pubkey::new_rand();
let account3_lamports: u64 = 300;
let account3 =
AccountSharedData::new(account3_lamports, 1, AccountSharedData::default().owner());
accounts.store_cached(slot1, &[(&key3, &account3)], None);
accounts.store_cached((slot1, &[(&key3, &account3)][..]), None);
let notifier = notifier.write().unwrap();
assert_eq!(notifier.accounts_notified.get(&key1).unwrap().len(), 2);