prepare replace Ancestors HashMap for performance (#16476)

This commit is contained in:
Jeff Washington (jwash) 2021-04-12 09:51:57 -06:00 committed by GitHub
parent 2bc19eb51e
commit 6930a77a0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 37 deletions

View File

@ -8,6 +8,7 @@ use rand::Rng;
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use solana_runtime::{
accounts::{create_test_accounts, AccountAddressFilter, Accounts},
accounts_index::Ancestors,
bank::*,
};
use solana_sdk::{
@ -233,7 +234,11 @@ fn bench_concurrent_read_write(bencher: &mut Bencher) {
let mut rng = rand::thread_rng();
loop {
let i = rng.gen_range(0, pubkeys.len());
test::black_box(accounts.load_slow(&HashMap::new(), &pubkeys[i]).unwrap());
test::black_box(
accounts
.load_slow(&Ancestors::default(), &pubkeys[i])
.unwrap(),
);
}
},
)
@ -244,7 +249,7 @@ fn bench_concurrent_read_write(bencher: &mut Bencher) {
fn bench_concurrent_scan_write(bencher: &mut Bencher) {
store_accounts_with_possible_contention("concurrent_scan_write", bencher, |accounts, _| loop {
test::black_box(
accounts.load_by_program(&HashMap::new(), &AccountSharedData::default().owner),
accounts.load_by_program(&Ancestors::default(), &AccountSharedData::default().owner),
);
})
}

View File

@ -5821,7 +5821,7 @@ pub mod tests {
db.caching_enabled = true;
let key = Pubkey::default();
let account0 = AccountSharedData::new(1, 0, &key);
let ancestors: HashMap<_, _> = vec![(unrooted_slot, 1)].into_iter().collect();
let ancestors = vec![(unrooted_slot, 1)].into_iter().collect();
db.store_cached(unrooted_slot, &[(&key, &account0)]);
db.bank_hashes
.write()
@ -5879,7 +5879,7 @@ pub mod tests {
assert_load_account(&db, new_root, key2, 1);
// Check purged account stays gone
let unrooted_slot_ancestors: HashMap<_, _> = vec![(unrooted_slot, 1)].into_iter().collect();
let unrooted_slot_ancestors = vec![(unrooted_slot, 1)].into_iter().collect();
assert!(db.load_slow(&unrooted_slot_ancestors, &key).is_none());
}
@ -6224,7 +6224,7 @@ pub mod tests {
// Make sure both accounts are in the same AppendVec in slot 0, which
// will prevent pubkey1 from being cleaned up later even when it's a
// zero-lamport account
let ancestors: HashMap<Slot, usize> = vec![(0, 1)].into_iter().collect();
let ancestors = vec![(0, 1)].into_iter().collect();
let (slot1, account_info1) = accounts
.accounts_index
.get(&pubkey1, Some(&ancestors), None)
@ -6414,7 +6414,7 @@ pub mod tests {
// Secondary index should still find both pubkeys
let mut found_accounts = HashSet::new();
accounts.accounts_index.index_scan_accounts(
&HashMap::new(),
&Ancestors::default(),
IndexKey::SplTokenMint(mint_key),
|key, _| {
found_accounts.insert(*key);
@ -6441,7 +6441,7 @@ pub mod tests {
// Secondary index should have purged `pubkey1` as well
let mut found_accounts = vec![];
accounts.accounts_index.index_scan_accounts(
&HashMap::new(),
&Ancestors::default(),
IndexKey::SplTokenMint(mint_key),
|key, _| found_accounts.push(*key),
);
@ -6897,7 +6897,7 @@ pub mod tests {
accounts.add_root(current_slot);
accounts.print_accounts_stats("pre_f");
accounts.update_accounts_hash(4, &HashMap::default());
accounts.update_accounts_hash(4, &Ancestors::default());
let accounts = f(accounts, current_slot);
@ -6909,7 +6909,7 @@ pub mod tests {
assert_load_account(&accounts, current_slot, dummy_pubkey, dummy_lamport);
accounts
.verify_bank_hash_and_lamports(4, &HashMap::default(), 1222)
.verify_bank_hash_and_lamports(4, &Ancestors::default(), 1222)
.unwrap();
}
@ -6959,8 +6959,9 @@ pub mod tests {
account.lamports = account_bal;
db.store_uncached(slot, &[(&pubkey, &account)]);
let (account, slot) =
db.load_slow(&HashMap::new(), &pubkey).unwrap_or_else(|| {
let (account, slot) = db
.load_slow(&Ancestors::default(), &pubkey)
.unwrap_or_else(|| {
panic!("Could not fetch stored account {}, iter {}", pubkey, i)
});
assert_eq!(slot, slot);
@ -7965,7 +7966,7 @@ pub mod tests {
accounts.all_account_count_in_append_vec(shrink_slot)
);
let no_ancestors = HashMap::default();
let no_ancestors = Ancestors::default();
accounts.update_accounts_hash(current_slot, &no_ancestors);
accounts
.verify_bank_hash_and_lamports(current_slot, &no_ancestors, 22300)
@ -8318,7 +8319,7 @@ pub mod tests {
accounts.print_accounts_stats("post-store");
let mut ancestors = HashMap::new();
let mut ancestors = Ancestors::default();
ancestors.insert(1, 0);
ancestors.insert(2, 1);
for (key, account_ref) in keys[..num_to_store].iter().zip(account_refs) {
@ -8346,7 +8347,7 @@ pub mod tests {
// Should still be able to find zero lamport account in slot 1
assert_eq!(
db.load_slow(&HashMap::new(), &account_key),
db.load_slow(&Ancestors::default(), &account_key),
Some((zero_lamport_account, 1))
);
}
@ -8361,7 +8362,7 @@ pub mod tests {
db.store_cached(slot, &[(&key, &account0)]);
// Load with no ancestors and no root will return nothing
assert!(db.load_slow(&HashMap::new(), &key).is_none());
assert!(db.load_slow(&Ancestors::default(), &key).is_none());
// Load with ancestors not equal to `slot` will return nothing
let ancestors = vec![(slot + 1, 1)].into_iter().collect();
@ -8376,7 +8377,10 @@ pub mod tests {
// Adding root will return the account even without ancestors
db.add_root(slot);
assert_eq!(db.load_slow(&HashMap::new(), &key), Some((account0, slot)));
assert_eq!(
db.load_slow(&Ancestors::default(), &key),
Some((account0, slot))
);
}
#[test]
@ -8401,7 +8405,10 @@ pub mod tests {
// Add root then flush
db.add_root(slot);
db.flush_accounts_cache(true, None);
assert_eq!(db.load_slow(&HashMap::new(), &key), Some((account0, slot)));
assert_eq!(
db.load_slow(&Ancestors::default(), &key),
Some((account0, slot))
);
}
#[test]
@ -8442,11 +8449,11 @@ pub mod tests {
assert_eq!(db.accounts_cache.num_slots(), 1);
assert!(db.accounts_cache.slot_cache(unrooted_slot).is_some());
assert_eq!(
db.load_slow(&HashMap::new(), &key5),
db.load_slow(&Ancestors::default(), &key5),
Some((account0.clone(), root5))
);
assert_eq!(
db.load_slow(&HashMap::new(), &key6),
db.load_slow(&Ancestors::default(), &key6),
Some((account0, root6))
);
}
@ -8503,7 +8510,7 @@ pub mod tests {
// Should still be able to fetch all the accounts after flush
for (slot, key) in (0..num_slots as Slot).zip(keys) {
let ancestors = if slot < num_roots as Slot {
HashMap::new()
Ancestors::default()
} else {
vec![(slot, 1)].into_iter().collect()
};

View File

@ -354,7 +354,7 @@ impl<T: 'static + Clone + IsCached + ZeroLamport> AccountsIndex<T> {
// In both cases we can ignore the given ancestors and instead just rely on the roots
// present as `max_root` indicates the roots present in the index are more up to date
// than the ancestors given.
let empty = HashMap::new();
let empty = Ancestors::default();
let ancestors = if ancestors.contains_key(&max_root) {
ancestors
} else {
@ -1205,7 +1205,7 @@ pub mod tests {
fn test_get_empty() {
let key = Keypair::new();
let index = AccountsIndex::<bool>::default();
let ancestors = HashMap::new();
let ancestors = Ancestors::default();
assert!(index.get(&key.pubkey(), Some(&ancestors), None).is_none());
assert!(index.get(&key.pubkey(), None, None).is_none());
@ -1230,7 +1230,7 @@ pub mod tests {
);
assert!(gc.is_empty());
let ancestors = HashMap::new();
let ancestors = Ancestors::default();
assert!(index.get(&key.pubkey(), Some(&ancestors), None).is_none());
assert!(index.get(&key.pubkey(), None, None).is_none());
@ -1354,7 +1354,7 @@ pub mod tests {
};
let pubkey_range = (pubkey_start, pubkey_end);
let ancestors: Ancestors = HashMap::new();
let ancestors = Ancestors::default();
let mut scanned_keys = HashSet::new();
index.range_scan_accounts("", &ancestors, pubkey_range, |pubkey, _index| {
scanned_keys.insert(*pubkey);
@ -1424,7 +1424,7 @@ pub mod tests {
fn run_test_scan_accounts(num_pubkeys: usize) {
let (index, _) = setup_accounts_index_keys(num_pubkeys);
let ancestors: Ancestors = HashMap::new();
let ancestors = Ancestors::default();
let mut scanned_keys = HashSet::new();
index.unchecked_scan_accounts("", &ancestors, |pubkey, _index| {
@ -1713,7 +1713,7 @@ pub mod tests {
let mut num = 0;
let mut found_key = false;
index.unchecked_scan_accounts("", &Ancestors::new(), |pubkey, _index| {
index.unchecked_scan_accounts("", &Ancestors::default(), |pubkey, _index| {
if pubkey == &key.pubkey() {
found_key = true;
assert_eq!(_index, (&true, 3));
@ -1787,7 +1787,7 @@ pub mod tests {
// Given a max_root, should filter out roots < max_root, but specified
// ancestors should not be affected
let ancestors: HashMap<Slot, usize> = vec![(3, 1), (7, 1)].into_iter().collect();
let ancestors = vec![(3, 1), (7, 1)].into_iter().collect();
assert_eq!(
index
.latest_slot(Some(&ancestors), &slot_slice, Some(4))

View File

@ -1054,7 +1054,7 @@ impl Bank {
parent_slot: parent.slot(),
collector_id: *collector_id,
collector_fees: AtomicU64::new(0),
ancestors: HashMap::new(),
ancestors: Ancestors::default(),
hash: RwLock::new(Hash::default()),
is_delta: AtomicBool::new(false),
tick_height: AtomicU64::new(parent.tick_height.load(Relaxed)),

View File

@ -301,11 +301,11 @@ mod tests {
let blockhash = hash(Hash::default().as_ref());
let status_cache = BankStatusCache::default();
assert_eq!(
status_cache.get_status(&sig, &blockhash, &HashMap::new()),
status_cache.get_status(&sig, &blockhash, &Ancestors::default()),
None
);
assert_eq!(
status_cache.get_status_any_blockhash(&sig, &HashMap::new()),
status_cache.get_status_any_blockhash(&sig, &Ancestors::default()),
None
);
}
@ -332,7 +332,7 @@ mod tests {
let sig = Signature::default();
let mut status_cache = BankStatusCache::default();
let blockhash = hash(Hash::default().as_ref());
let ancestors = HashMap::new();
let ancestors = Ancestors::default();
status_cache.insert(&blockhash, &sig, 1, ());
assert_eq!(status_cache.get_status(&sig, &blockhash, &ancestors), None);
assert_eq!(
@ -346,7 +346,7 @@ mod tests {
let sig = Signature::default();
let mut status_cache = BankStatusCache::default();
let blockhash = hash(Hash::default().as_ref());
let ancestors = HashMap::new();
let ancestors = Ancestors::default();
status_cache.insert(&blockhash, &sig, 0, ());
status_cache.add_root(0);
assert_eq!(
@ -376,7 +376,7 @@ mod tests {
let sig = Signature::default();
let mut status_cache = BankStatusCache::default();
let blockhash = hash(Hash::default().as_ref());
let ancestors = HashMap::new();
let ancestors = Ancestors::default();
status_cache.insert(&blockhash, &sig, 0, ());
for i in 0..(MAX_CACHE_ENTRIES + 1) {
status_cache.add_root(i as u64);
@ -389,7 +389,7 @@ mod tests {
let sig = Signature::default();
let mut status_cache = BankStatusCache::default();
let blockhash = hash(Hash::default().as_ref());
let ancestors = HashMap::new();
let ancestors = Ancestors::default();
status_cache.insert(&blockhash, &sig, 0, ());
status_cache.add_root(0);
status_cache.clear();
@ -401,7 +401,7 @@ mod tests {
let sig = Signature::default();
let mut status_cache = BankStatusCache::default();
let blockhash = hash(Hash::default().as_ref());
let ancestors = HashMap::new();
let ancestors = Ancestors::default();
status_cache.add_root(0);
status_cache.clear();
status_cache.insert(&blockhash, &sig, 0, ());
@ -474,9 +474,9 @@ mod tests {
status_cache.insert(&blockhash, &sig, 1, ());
status_cache.insert(&blockhash2, &sig, 1, ());
let mut ancestors0 = HashMap::new();
let mut ancestors0 = Ancestors::default();
ancestors0.insert(0, 0);
let mut ancestors1 = HashMap::new();
let mut ancestors1 = Ancestors::default();
ancestors1.insert(1, 0);
// Clear slot 0 related data