contains_multiple_slots (#24500)

This commit is contained in:
Jeff Washington (jwash) 2022-04-20 09:53:36 -05:00 committed by GitHub
parent cfe2177e16
commit 0d797e2fff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 3 deletions

View File

@ -6631,7 +6631,6 @@ impl AccountsDb {
is_cached_store: bool,
reset_accounts: bool,
) -> StoreAccountsTiming {
let slot = accounts.target_slot();
let storage_finder = storage_finder
.unwrap_or_else(|| Box::new(move |slot, size| self.find_storage_candidate(slot, size)));
@ -6664,6 +6663,10 @@ impl AccountsDb {
let previous_slot_entry_was_cached = self.caching_enabled && is_cached_store;
// if we are squashing a single slot, then we can expect a single dead slot
let expected_single_dead_slot =
(!accounts.contains_multiple_slots()).then(|| accounts.target_slot());
// If the cache was flushed, then because `update_index` occurs
// after the account are stored by the above `store_accounts_to`
// call and all the accounts are stored, all reads after this point
@ -6699,7 +6702,13 @@ impl AccountsDb {
// equivalent to asserting there will be no dead slots, is safe.
let no_purge_stats = None;
let mut handle_reclaims_time = Measure::start("handle_reclaims");
self.handle_reclaims(&reclaims, Some(slot), no_purge_stats, None, reset_accounts);
self.handle_reclaims(
&reclaims,
expected_single_dead_slot,
no_purge_stats,
None,
reset_accounts,
);
handle_reclaims_time.stop();
self.stats
.store_handle_reclaims

View File

@ -19,6 +19,9 @@ pub trait StorableAccounts<'a, T: ReadableAccount + Sync>: Sync {
fn is_empty(&self) -> bool;
/// # accounts to write
fn len(&self) -> usize;
/// are there accounts from multiple slots
/// only used for an assert
fn contains_multiple_slots(&self) -> bool;
}
impl<'a, T: ReadableAccount + Sync> StorableAccounts<'a, T> for (Slot, &'a [(&'a Pubkey, &'a T)]) {
@ -41,6 +44,9 @@ impl<'a, T: ReadableAccount + Sync> StorableAccounts<'a, T> for (Slot, &'a [(&'a
fn len(&self) -> usize {
self.1.len()
}
fn contains_multiple_slots(&self) -> bool {
false
}
}
/// this tuple contains slot info PER account
@ -66,6 +72,16 @@ impl<'a, T: ReadableAccount + Sync> StorableAccounts<'a, T>
fn len(&self) -> usize {
self.1.len()
}
fn contains_multiple_slots(&self) -> bool {
let len = self.len();
if len > 0 {
let slot = self.slot(0);
// true if any item has a different slot than the first item
(1..len).any(|i| slot != self.slot(i))
} else {
false
}
}
}
#[cfg(test)]
@ -88,6 +104,23 @@ pub mod tests {
})
}
#[test]
fn test_contains_multiple_slots() {
let pk = Pubkey::new(&[1; 32]);
let account = AccountSharedData::create(1, Vec::default(), Pubkey::default(), false, 0);
let slot = 0;
let test3 = (
slot,
&vec![(&pk, &account, slot), (&pk, &account, slot)][..],
);
assert!(!(&test3).contains_multiple_slots());
let test3 = (
slot,
&vec![(&pk, &account, slot), (&pk, &account, slot + 1)][..],
);
assert!(test3.contains_multiple_slots());
}
#[test]
fn test_storable_accounts() {
let max_slots = 3_u64;
@ -122,9 +155,11 @@ pub mod tests {
assert_eq!(raw.0, *test3.pubkey(i));
assert_eq!(raw.1, *test3.account(i));
assert_eq!(raw.2, test3.slot(i));
assert_eq!(target_slot, test3.target_slot());
assert_eq!(target_slot, test2.slot(i));
}
assert_eq!(target_slot, test3.target_slot());
assert!(!test2.contains_multiple_slots());
assert_eq!(test3.contains_multiple_slots(), entries > 1);
}
}
}