get rid of WriteAccountMapEntry instance (#19093)

This commit is contained in:
Jeff Washington (jwash)
2021-09-27 16:24:19 -05:00
committed by GitHub
parent e4795ae7ed
commit 4f83818fdb

View File

@ -284,37 +284,6 @@ impl<T: IndexValue> PreAllocatedAccountMapEntry<T> {
} }
} }
#[self_referencing]
pub struct WriteAccountMapEntry<T: IndexValue> {
owned_entry: AccountMapEntry<T>,
#[borrows(owned_entry)]
#[covariant]
slot_list_guard: RwLockWriteGuard<'this, SlotList<T>>,
}
impl<T: IndexValue> WriteAccountMapEntry<T> {
pub fn from_account_map_entry(account_map_entry: AccountMapEntry<T>) -> Self {
WriteAccountMapEntryBuilder {
owned_entry: account_map_entry,
slot_list_guard_builder: |lock| lock.slot_list.write().unwrap(),
}
.build()
}
pub fn slot_list(&self) -> &SlotList<T> {
&*self.borrow_slot_list_guard()
}
pub fn slot_list_mut<RT>(
&mut self,
user: impl for<'this> FnOnce(&mut RwLockWriteGuard<'this, SlotList<T>>) -> RT,
) -> RT {
let result = self.with_slot_list_guard_mut(user);
self.borrow_owned_entry().set_dirty(true);
result
}
}
#[derive(Debug, Default, AbiExample, Clone)] #[derive(Debug, Default, AbiExample, Clone)]
pub struct RollingBitField { pub struct RollingBitField {
max_width: u64, max_width: u64,
@ -1199,12 +1168,20 @@ impl<T: IndexValue> AccountsIndex<T> {
.map(ReadAccountMapEntry::from_account_map_entry) .map(ReadAccountMapEntry::from_account_map_entry)
} }
fn get_account_write_entry(&self, pubkey: &Pubkey) -> Option<WriteAccountMapEntry<T>> { fn slot_list_mut<RT>(
self.account_maps[self.bin_calculator.bin_from_pubkey(pubkey)] &self,
pubkey: &Pubkey,
user: impl for<'a> FnOnce(&mut RwLockWriteGuard<'a, SlotList<T>>) -> RT,
) -> Option<RT> {
let read_lock = self.account_maps[self.bin_calculator.bin_from_pubkey(pubkey)]
.read() .read()
.unwrap() .unwrap();
.get(pubkey) let get = read_lock.get(pubkey);
.map(WriteAccountMapEntry::from_account_map_entry) get.map(|entry| {
let result = user(&mut entry.slot_list.write().unwrap());
entry.set_dirty(true);
result
})
} }
pub fn handle_dead_keys( pub fn handle_dead_keys(
@ -1342,8 +1319,7 @@ impl<T: IndexValue> AccountsIndex<T> {
where where
C: Contains<'a, Slot>, C: Contains<'a, Slot>,
{ {
if let Some(mut write_account_map_entry) = self.get_account_write_entry(pubkey) { self.slot_list_mut(pubkey, |slot_list| {
write_account_map_entry.slot_list_mut(|slot_list| {
slot_list.retain(|(slot, item)| { slot_list.retain(|(slot, item)| {
let should_purge = slots_to_purge.contains(slot); let should_purge = slots_to_purge.contains(slot);
if should_purge { if should_purge {
@ -1355,9 +1331,7 @@ impl<T: IndexValue> AccountsIndex<T> {
}); });
slot_list.is_empty() slot_list.is_empty()
}) })
} else { .unwrap_or(true)
true
}
} }
pub fn min_ongoing_scan_root(&self) -> Option<Slot> { pub fn min_ongoing_scan_root(&self) -> Option<Slot> {
@ -1719,12 +1693,10 @@ impl<T: IndexValue> AccountsIndex<T> {
max_clean_root: Option<Slot>, max_clean_root: Option<Slot>,
) { ) {
let mut is_slot_list_empty = false; let mut is_slot_list_empty = false;
if let Some(mut locked_entry) = self.get_account_write_entry(pubkey) { self.slot_list_mut(pubkey, |slot_list| {
locked_entry.slot_list_mut(|slot_list| {
self.purge_older_root_entries(slot_list, reclaims, max_clean_root); self.purge_older_root_entries(slot_list, reclaims, max_clean_root);
is_slot_list_empty = slot_list.is_empty(); is_slot_list_empty = slot_list.is_empty();
}); });
}
// If the slot list is empty, remove the pubkey from `account_maps`. Make sure to grab the // If the slot list is empty, remove the pubkey from `account_maps`. Make sure to grab the
// lock and double check the slot list is still empty, because another writer could have // lock and double check the slot list is still empty, because another writer could have
@ -1910,12 +1882,12 @@ impl<T: IndexValue> AccountsIndex<T> {
// if this account has no more entries. Note this does not update the secondary // if this account has no more entries. Note this does not update the secondary
// indexes! // indexes!
pub fn purge_roots(&self, pubkey: &Pubkey) -> (SlotList<T>, bool) { pub fn purge_roots(&self, pubkey: &Pubkey) -> (SlotList<T>, bool) {
let mut write_account_map_entry = self.get_account_write_entry(pubkey).unwrap(); self.slot_list_mut(pubkey, |slot_list| {
write_account_map_entry.slot_list_mut(|slot_list| {
let reclaims = self.get_rooted_entries(slot_list, None); let reclaims = self.get_rooted_entries(slot_list, None);
slot_list.retain(|(slot, _)| !self.is_root(*slot)); slot_list.retain(|(slot, _)| !self.is_root(*slot));
(reclaims, slot_list.is_empty()) (reclaims, slot_list.is_empty())
}) })
.unwrap()
} }
} }
@ -3922,10 +3894,7 @@ pub mod tests {
secondary_indexes.keys = None; secondary_indexes.keys = None;
index index.slot_list_mut(&account_key, |slot_list| slot_list.clear());
.get_account_write_entry(&account_key)
.unwrap()
.slot_list_mut(|slot_list| slot_list.clear());
// Everything should be deleted // Everything should be deleted
index.handle_dead_keys(&[&account_key], &secondary_indexes); index.handle_dead_keys(&[&account_key], &secondary_indexes);
@ -4028,10 +3997,7 @@ pub mod tests {
// was outdated by the update in the later slot, the primary account key is still alive, // was outdated by the update in the later slot, the primary account key is still alive,
// so both secondary keys will still be kept alive. // so both secondary keys will still be kept alive.
index.add_root(later_slot, false); index.add_root(later_slot, false);
index index.slot_list_mut(&account_key, |slot_list| {
.get_account_write_entry(&account_key)
.unwrap()
.slot_list_mut(|slot_list| {
index.purge_older_root_entries(slot_list, &mut vec![], None) index.purge_older_root_entries(slot_list, &mut vec![], None)
}); });