diff --git a/runtime/src/bucket_map_holder_stats.rs b/runtime/src/bucket_map_holder_stats.rs index cd274ce472..af118e1019 100644 --- a/runtime/src/bucket_map_holder_stats.rs +++ b/runtime/src/bucket_map_holder_stats.rs @@ -11,9 +11,11 @@ pub struct BucketMapHolderStats { pub entries_from_mem: AtomicU64, pub entry_missing_us: AtomicU64, pub entries_missing: AtomicU64, + pub updates_in_mem: AtomicU64, pub items: AtomicU64, pub keys: AtomicU64, pub deletes: AtomicU64, + pub inserts: AtomicU64, } impl BucketMapHolderStats { @@ -60,6 +62,12 @@ impl BucketMapHolderStats { self.entry_missing_us.swap(0, Ordering::Relaxed) / 1000, i64 ), + ( + "updates_in_mem", + self.updates_in_mem.swap(0, Ordering::Relaxed), + i64 + ), + ("inserts", self.inserts.swap(0, Ordering::Relaxed), i64), ("deletes", self.deletes.swap(0, Ordering::Relaxed), i64), ("items", self.items.swap(0, Ordering::Relaxed), i64), ("keys", self.keys.swap(0, Ordering::Relaxed), i64), diff --git a/runtime/src/in_mem_accounts_index.rs b/runtime/src/in_mem_accounts_index.rs index 1f20b31e88..d5237910e8 100644 --- a/runtime/src/in_mem_accounts_index.rs +++ b/runtime/src/in_mem_accounts_index.rs @@ -90,11 +90,13 @@ impl InMemAccountsIndex { if let Entry::Occupied(index_entry) = self.entry(pubkey) { if index_entry.get().slot_list.read().unwrap().is_empty() { index_entry.remove(); + self.storage.stats.deletes.fetch_add(1, Ordering::Relaxed); return true; } } false } + pub fn upsert( &mut self, pubkey: &Pubkey, @@ -111,9 +113,11 @@ impl InMemAccountsIndex { reclaims, previous_slot_entry_was_cached, ); + Self::update_stat(&self.storage.stats.updates_in_mem, 1); } Entry::Vacant(vacant) => { vacant.insert(new_value); + Self::update_stat(&self.storage.stats.inserts, 1); } } } @@ -212,19 +216,30 @@ impl InMemAccountsIndex { pubkey: Pubkey, new_entry: AccountMapEntry, ) -> Option<(WriteAccountMapEntry, T, Pubkey)> { - let account_entry = self.entry(pubkey); - match account_entry { - Entry::Occupied(account_entry) => Some(( - WriteAccountMapEntry::from_account_map_entry(account_entry.get().clone()), - // extract the new account_info from the unused 'new_entry' - new_entry.slot_list.write().unwrap().remove(0).1, - *account_entry.key(), - )), + let result = match self.entry(pubkey) { + Entry::Occupied(account_entry) => { + Some(( + WriteAccountMapEntry::from_account_map_entry(account_entry.get().clone()), + // extract the new account_info from the unused 'new_entry' + new_entry.slot_list.write().unwrap().remove(0).1, + *account_entry.key(), + )) + } Entry::Vacant(account_entry) => { account_entry.insert(new_entry); None } - } + }; + let stats = self.stats(); + Self::update_stat( + if result.is_none() { + &stats.inserts + } else { + &stats.updates_in_mem + }, + 1, + ); + result } fn stats(&self) -> &BucketMapHolderStats {