Skip to content

Commit

Permalink
Example change
Browse files Browse the repository at this point in the history
  • Loading branch information
carllin committed Oct 15, 2020
1 parent 74a3b4a commit 970b2c7
Showing 1 changed file with 48 additions and 51 deletions.
99 changes: 48 additions & 51 deletions runtime/src/accounts_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,63 +53,61 @@ pub type Ancestors = HashMap<Slot, usize>;
pub type RefCount = u64;
pub type AccountMap<K, V> = BTreeMap<K, V>;

#[derive(Clone, Debug)]
pub struct AccountMapEntry<T> {
ref_count: Arc<AtomicU64>,
pub slot_list: Arc<RwLock<SlotList<T>>>,
type AccountMapEntry<T> = Arc<AccountMapEntryInner<T>>;

#[derive(Debug)]
pub struct AccountMapEntryInner<T> {
ref_count: AtomicU64,
pub slot_list: RwLock<SlotList<T>>,
}

#[self_referencing]
pub struct ReadAccountMapEntry<T: 'static> {
ref_count: Arc<AtomicU64>,
slot_list: OwningReadGuard<SlotList<T>>,
pub owned_entry: Arc<AccountMapEntry<T>>,
#[borrows(owned_entry)]
pub slot_list_guard: RwLockReadGuard<'this, SlotList<T>>,
}

impl<T: Clone> ReadAccountMapEntry<T> {
pub fn from_account_map_entry(account_map_entry: AccountMapEntry<T>) -> Self {
let slot_list = OwningReadGuardBuilder {
lock: account_map_entry.slot_list,
guard_builder: |lock| lock.read().unwrap(),
}
.build();
Self {
ref_count: account_map_entry.ref_count,
slot_list,
ReadAccountMapEntryBuilder {
owned_entry: Arc::new(account_map_entry),
slot_list_guard_builder: |lock| lock.slot_list.read().unwrap(),
}
.build()
}

pub fn slot_list(&self) -> &SlotList<T> {
&*self.slot_list
&*self.slot_list_guard
}

pub fn ref_count(&self) -> u64 {
self.ref_count.load(Ordering::Relaxed)
pub fn ref_count(&self) -> &AtomicU64 {
&self.owned_entry.ref_count
}
}

#[self_referencing]
pub struct WriteAccountMapEntry<T: 'static> {
ref_count: Arc<AtomicU64>,
slot_list: OwningWriteGuard<SlotList<T>>,
pub owned_entry: Arc<AccountMapEntry<T>>,
#[borrows(owned_entry)]
pub slot_list_guard: RwLockWriteGuard<'this, SlotList<T>>,
}

impl<T: 'static + Clone> WriteAccountMapEntry<T> {
pub fn from_account_map_entry(account_map_entry: AccountMapEntry<T>) -> Self {
let slot_list = OwningWriteGuardBuilder {
lock: account_map_entry.slot_list,
guard_builder: |lock| lock.write().unwrap(),
}
.build();
Self {
ref_count: account_map_entry.ref_count,
slot_list,
WriteAccountMapEntryBuilder {
owned_entry: Arc::new(account_map_entry),
slot_list_guard_builder: |lock| lock.slot_list.write().unwrap(),
}
.build()
}

pub fn slot_list(&self) -> &SlotList<T> {
&*self.slot_list
pub fn slot_list_mut(&mut self) -> &mut SlotList<T> {
&mut *self.slot_list_guard
}

pub fn ref_count(&self) -> u64 {
self.ref_count.load(Ordering::Relaxed)
pub fn ref_count(&self) -> &AtomicU64 {
&self.owned_entry.ref_count
}

// Try to update an item in account_maps. If the account is not
Expand All @@ -119,7 +117,7 @@ impl<T: 'static + Clone> WriteAccountMapEntry<T> {
pub fn update(&mut self, slot: Slot, account_info: T, reclaims: &mut SlotList<T>) {
// filter out other dirty entries from the same slot
let mut same_slot_previous_updates: Vec<(usize, (Slot, &T))> = self
.slot_list
.slot_list_mut()
.iter()
.enumerate()
.filter_map(|(i, (s, value))| {
Expand All @@ -134,12 +132,12 @@ impl<T: 'static + Clone> WriteAccountMapEntry<T> {

if let Some((list_index, (s, previous_update_value))) = same_slot_previous_updates.pop() {
reclaims.push((s, previous_update_value.clone()));
self.slot_list.remove(list_index);
self.slot_list_mut().remove(list_index);
} else {
// Only increment ref count if the account was not prevously updated in this slot
self.ref_count.fetch_add(1, Ordering::Relaxed);
self.ref_count().fetch_add(1, Ordering::Relaxed);
}
self.slot_list.push((slot, account_info));
self.slot_list_mut().push((slot, account_info));
}
}

Expand Down Expand Up @@ -268,10 +266,10 @@ impl<T: 'static + Clone> AccountsIndex<T> {
let mut w_account_entry = self.get_account_write_entry(pubkey);
let mut is_newly_inserted = false;
if w_account_entry.is_none() {
let new_entry = AccountMapEntry {
ref_count: Arc::new(AtomicU64::new(0)),
slot_list: Arc::new(RwLock::new(SlotList::with_capacity(32))),
};
let new_entry = Arc::new(AccountMapEntryInner {
ref_count: AtomicU64::new(0),
slot_list: RwLock::new(SlotList::with_capacity(32)),
});
let mut w_account_maps = self.account_maps.write().unwrap();
let account_entry = w_account_maps.entry(*pubkey).or_insert_with(|| {
is_newly_inserted = true;
Expand Down Expand Up @@ -330,23 +328,23 @@ impl<T: 'static + Clone> AccountsIndex<T> {
) -> (SlotList<T>, RefCount) {
(
self.get_rooted_entries(&locked_account_entry.slot_list()),
locked_account_entry.ref_count(),
locked_account_entry.ref_count().load(Ordering::Relaxed),
)
}

// filter any rooted entries and return them along with a bool that indicates
// if this account has no more entries.
pub fn purge(&self, pubkey: &Pubkey) -> (SlotList<T>, bool) {
let WriteAccountMapEntry { mut slot_list, .. } =
self.get_account_write_entry(pubkey).unwrap();
let mut write_account_map_entry = self.get_account_write_entry(pubkey).unwrap();
let slot_list = write_account_map_entry.slot_list_mut();
let reclaims = self.get_rooted_entries(&slot_list);
slot_list.retain(|(slot, _)| !self.is_root(*slot));
(reclaims, slot_list.is_empty())
}

pub fn purge_exact(&self, pubkey: &Pubkey, slots: HashSet<Slot>) -> (SlotList<T>, bool) {
let WriteAccountMapEntry { mut slot_list, .. } =
self.get_account_write_entry(pubkey).unwrap();
let mut write_account_map_entry = self.get_account_write_entry(pubkey).unwrap();
let slot_list = write_account_map_entry.slot_list_mut();
let reclaims = slot_list
.iter()
.filter(|(slot, _)| slots.contains(&slot))
Expand Down Expand Up @@ -442,13 +440,13 @@ impl<T: 'static + Clone> AccountsIndex<T> {

pub fn unref_from_storage(&self, pubkey: &Pubkey) {
if let Some(locked_entry) = self.get_account_read_entry(pubkey) {
locked_entry.ref_count.fetch_sub(1, Ordering::Relaxed);
locked_entry.ref_count().fetch_sub(1, Ordering::Relaxed);
}
}

pub fn ref_count_from_storage(&self, pubkey: &Pubkey) -> RefCount {
if let Some(locked_entry) = self.get_account_read_entry(pubkey) {
locked_entry.ref_count.load(Ordering::Relaxed)
locked_entry.ref_count().load(Ordering::Relaxed)
} else {
0
}
Expand Down Expand Up @@ -478,9 +476,8 @@ impl<T: 'static + Clone> AccountsIndex<T> {
reclaims: &mut SlotList<T>,
max_clean_root: Option<Slot>,
) {
if let Some(locked_entry) = self.get_account_write_entry(pubkey) {
let WriteAccountMapEntry { mut slot_list, .. } = locked_entry;
self.purge_older_root_entries(&mut *slot_list, reclaims, max_clean_root);
if let Some(mut locked_entry) = self.get_account_write_entry(pubkey) {
self.purge_older_root_entries(locked_entry.slot_list_mut(), reclaims, max_clean_root);
}
}

Expand All @@ -490,8 +487,8 @@ impl<T: 'static + Clone> AccountsIndex<T> {
pubkey: &Pubkey,
reclaims: &mut SlotList<T>,
) {
if let Some(locked_entry) = self.get_account_write_entry(pubkey) {
let WriteAccountMapEntry { mut slot_list, .. } = locked_entry;
if let Some(mut locked_entry) = self.get_account_write_entry(pubkey) {
let slot_list = locked_entry.slot_list_mut();
slot_list.retain(|(slot, entry)| {
if *slot == purge_slot {
reclaims.push((*slot, entry.clone()));
Expand Down

0 comments on commit 970b2c7

Please sign in to comment.