From a9a94166ef4adee79b824c660d92cfda82bfedc8 Mon Sep 17 00:00:00 2001 From: "Jeff Washington (jwash)" Date: Fri, 3 Jun 2022 13:34:17 -0500 Subject: [PATCH] load_account_into_read_cache (#25760) --- runtime/src/accounts_db.rs | 40 ++++++++++++++++++++++--- runtime/src/bank.rs | 7 +++++ runtime/src/read_only_accounts_cache.rs | 5 ++++ 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/runtime/src/accounts_db.rs b/runtime/src/accounts_db.rs index e446aaa3e2..095bff32ae 100644 --- a/runtime/src/accounts_db.rs +++ b/runtime/src/accounts_db.rs @@ -4148,6 +4148,10 @@ impl AccountsDb { self.do_load(ancestors, pubkey, None, load_hint) } + pub fn load_account_into_read_cache(&self, ancestors: &Ancestors, pubkey: &Pubkey) { + self.do_load_with_populate_read_cache(ancestors, pubkey, None, LoadHint::Unspecified, true); + } + pub fn load_with_fixed_root( &self, ancestors: &Ancestors, @@ -4480,6 +4484,19 @@ impl AccountsDb { pubkey: &Pubkey, max_root: Option, load_hint: LoadHint, + ) -> Option<(AccountSharedData, Slot)> { + self.do_load_with_populate_read_cache(ancestors, pubkey, max_root, load_hint, false) + } + + /// if 'load_into_read_cache_only', then return value is meaningless. + /// The goal is to get the account into the read-only cache. + fn do_load_with_populate_read_cache( + &self, + ancestors: &Ancestors, + pubkey: &Pubkey, + max_root: Option, + load_hint: LoadHint, + load_into_read_cache_only: bool, ) -> Option<(AccountSharedData, Slot)> { #[cfg(not(test))] assert!(max_root.is_none()); @@ -4488,10 +4505,25 @@ impl AccountsDb { self.read_index_for_accessor_or_load_slow(ancestors, pubkey, max_root, false)?; // Notice the subtle `?` at previous line, we bail out pretty early if missing. - if self.caching_enabled && !storage_location.is_cached() { - let result = self.read_only_accounts_cache.load(*pubkey, slot); - if let Some(account) = result { - return Some((account, slot)); + if self.caching_enabled { + let in_write_cache = storage_location.is_cached(); + if !load_into_read_cache_only { + if !in_write_cache { + let result = self.read_only_accounts_cache.load(*pubkey, slot); + if let Some(account) = result { + return Some((account, slot)); + } + } + } else { + // goal is to load into read cache + if in_write_cache { + // no reason to load in read cache. already in write cache + return None; + } + if self.read_only_accounts_cache.in_cache(pubkey, slot) { + // already in read cache + return None; + } } } diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 92043564a2..bb48168c3d 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -6641,6 +6641,13 @@ impl Bank { &self.rc.accounts.accounts_db.thread_pool_clean } + pub fn load_account_into_read_cache(&self, key: &Pubkey) { + self.rc + .accounts + .accounts_db + .load_account_into_read_cache(&self.ancestors, key); + } + pub fn update_accounts_hash_with_index_option( &self, use_index: bool, diff --git a/runtime/src/read_only_accounts_cache.rs b/runtime/src/read_only_accounts_cache.rs index 2ff5ad3711..f58eb70a9e 100644 --- a/runtime/src/read_only_accounts_cache.rs +++ b/runtime/src/read_only_accounts_cache.rs @@ -52,6 +52,11 @@ impl ReadOnlyAccountsCache { } } + /// true if pubkey is in cache at slot + pub fn in_cache(&self, pubkey: &Pubkey, slot: Slot) -> bool { + self.cache.contains_key(&(*pubkey, slot)) + } + pub(crate) fn load(&self, pubkey: Pubkey, slot: Slot) -> Option { let key = (pubkey, slot); let mut entry = match self.cache.get_mut(&key) {