diff --git a/runtime/src/in_mem_accounts_index.rs b/runtime/src/in_mem_accounts_index.rs index 749aaffbb10468..1af3ceea00e530 100644 --- a/runtime/src/in_mem_accounts_index.rs +++ b/runtime/src/in_mem_accounts_index.rs @@ -103,7 +103,7 @@ pub struct InMemAccountsIndex + Into< flushing_active: AtomicBool, /// info to streamline initial index generation - startup_info: Mutex>, + startup_info: StartupInfo, /// possible evictions for next few slots coming up possible_evictions: RwLock>, @@ -131,9 +131,7 @@ pub enum InsertNewEntryResults { } #[derive(Default, Debug)] -struct StartupInfo { - /// entries to add next time we are flushing to disk - insert: Vec<(Slot, Pubkey, T)>, +struct StartupInfoDuplicates { /// entries that were found to have duplicate index entries. /// When all entries have been inserted, these can be resolved and held in memory. duplicates: Vec<(Slot, Pubkey, T)>, @@ -141,6 +139,14 @@ struct StartupInfo { duplicates_put_on_disk: HashSet<(Slot, Pubkey)>, } +#[derive(Default, Debug)] +struct StartupInfo { + /// entries to add next time we are flushing to disk + insert: Mutex>, + /// pubkeys with more than 1 entry + duplicates: Mutex>, +} + #[derive(Default, Debug)] /// result from scanning in-mem index during flush struct FlushScanResult { @@ -168,7 +174,7 @@ impl + Into> InMemAccountsIndex + Into> InMemAccountsIndex + Into> InMemAccountsIndex + Into> InMemAccountsIndex + Into> InMemAccountsIndex { // already on disk, so remember the new (slot, info) for later - startup_info.duplicates.push((slot, k, entry.1)); + duplicates.duplicates.push((slot, k, entry.1)); if let Some((slot, _)) = current_slot_list.first() { // accurately account for there being a duplicate for the first entry that was previously added to the disk index. // That entry could not have known yet that it was a duplicate. // It is important to capture each slot with a duplicate because of slot limits applied to clean. - startup_info.duplicates_put_on_disk.insert((*slot, k)); + duplicates.duplicates_put_on_disk.insert((*slot, k)); } Some((current_slot_list.to_vec(), ref_count)) } @@ -1087,13 +1093,16 @@ impl + Into> InMemAccountsIndex Vec<(Slot, Pubkey)> { - let mut write = self.startup_info.lock().unwrap(); + let inserts = self.startup_info.insert.lock().unwrap(); // in order to return accurate and complete duplicates, we must have nothing left remaining to insert - assert!(write.insert.is_empty()); + assert!(inserts.is_empty()); + drop(inserts); + + let mut duplicate_items = self.startup_info.duplicates.lock().unwrap(); + let duplicates = std::mem::take(&mut duplicate_items.duplicates); + let duplicates_put_on_disk = std::mem::take(&mut duplicate_items.duplicates_put_on_disk); + drop(duplicate_items); - let duplicates = std::mem::take(&mut write.duplicates); - let duplicates_put_on_disk = std::mem::take(&mut write.duplicates_put_on_disk); - drop(write); duplicates_put_on_disk .into_iter() .chain(duplicates.into_iter().map(|(slot, key, info)| {