From 5a4979f25f38e0cfe651045464cd2f11efedc18b Mon Sep 17 00:00:00 2001 From: sakridge Date: Wed, 4 Aug 2021 16:33:47 -0700 Subject: [PATCH] Handle 0-lamport account in index generation (#19041) * Handle 0-lamport account in index generation * rename duplicate to dirty keys Co-authored-by: Carl Lin --- runtime/src/accounts_index.rs | 37 ++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/runtime/src/accounts_index.rs b/runtime/src/accounts_index.rs index fc91292829..c4e804c5ee 100644 --- a/runtime/src/accounts_index.rs +++ b/runtime/src/accounts_index.rs @@ -1447,42 +1447,47 @@ impl< items.for_each(|(pubkey, account_info)| { let bin = self.bin_calculator.bin_from_pubkey(&pubkey); // this value is equivalent to what update() below would have created if we inserted a new item + let is_zero_lamport = account_info.is_zero_lamport(); let info = WriteAccountMapEntry::new_entry_after_update(slot, account_info); - binned[bin].1.push((pubkey, info)); + binned[bin].1.push((pubkey, info, is_zero_lamport)); }); binned.retain(|x| !x.1.is_empty()); let insertion_time = AtomicU64::new(0); - let duplicate_keys = binned + let dirty_pubkeys = binned .into_iter() .map(|(pubkey_bin, items)| { let mut _reclaims = SlotList::new(); // big enough so not likely to re-allocate, small enough to not over-allocate by too much // this assumes 10% of keys are duplicates. This vector will be flattened below. - let mut duplicate_keys = Vec::with_capacity(items.len() / 10); + let mut dirty_pubkeys = Vec::with_capacity(items.len() / 10); let mut w_account_maps = self.account_maps[pubkey_bin].write().unwrap(); let mut insert_time = Measure::start("insert_into_primary_index"); - items.into_iter().for_each(|(pubkey, new_item)| { - let already_exists = self.insert_new_entry_if_missing_with_lock( - pubkey, - &mut w_account_maps, - new_item, - ); - if let Some((mut w_account_entry, account_info, pubkey)) = already_exists { - w_account_entry.update(slot, account_info, &mut _reclaims); - duplicate_keys.push(pubkey); - } - }); + items + .into_iter() + .for_each(|(pubkey, new_item, is_zero_lamport)| { + let already_exists = self.insert_new_entry_if_missing_with_lock( + pubkey, + &mut w_account_maps, + new_item, + ); + if let Some((mut w_account_entry, account_info, pubkey)) = already_exists { + w_account_entry.update(slot, account_info, &mut _reclaims); + dirty_pubkeys.push(pubkey); + } else if is_zero_lamport { + dirty_pubkeys.push(pubkey); + } + }); insert_time.stop(); insertion_time.fetch_add(insert_time.as_us(), Ordering::Relaxed); - duplicate_keys + dirty_pubkeys }) .flatten() .collect::>(); - (duplicate_keys, insertion_time.load(Ordering::Relaxed)) + (dirty_pubkeys, insertion_time.load(Ordering::Relaxed)) } // Updates the given pubkey at the given slot with the new account information.