Skip to content

Commit

Permalink
update lru for read only cache if it has been long enough since last …
Browse files Browse the repository at this point in the history
…access
  • Loading branch information
jeffwashington committed Jul 20, 2023
1 parent b0456ea commit 5b481a3
Showing 1 changed file with 31 additions and 6 deletions.
37 changes: 31 additions & 6 deletions runtime/src/read_only_accounts_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use {
account::{AccountSharedData, ReadableAccount},
clock::Slot,
pubkey::Pubkey,
timing::timestamp,
},
std::sync::{
atomic::{AtomicU64, AtomicUsize, Ordering},
Expand All @@ -23,7 +24,28 @@ type ReadOnlyCacheKey = (Pubkey, Slot);
#[derive(Debug)]
struct ReadOnlyAccountCacheEntry {
account: AccountSharedData,
index: Index, // Index of the entry in the eviction queue.
/// Index of the entry in the eviction queue.
index: Index,
/// lower bits of last timestamp when eviction queue was updated
last_time: u32,
}

impl ReadOnlyAccountCacheEntry {
fn new(account: AccountSharedData, index: Index) -> Self {
Self {
account,
index,
last_time: Self::timestamp(),
}
}
/// lower bits of current timestamp. We don't need higher bits and u32 fits with Index u32
fn timestamp() -> u32 {
(timestamp() % (u32::MAX as u64 + 1)) as u32
}
/// ms since `last_time` timestamp
fn ms_since_last_time(&self) -> u32 {
Self::timestamp().wrapping_sub(self.last_time)
}
}

#[derive(Debug)]
Expand Down Expand Up @@ -78,16 +100,19 @@ impl ReadOnlyAccountsCache {
let (account, load_us) = measure_us!({
let key = (pubkey, slot);
let Some(mut entry) = self.cache.get_mut(&key) else {
self.misses.fetch_add(1, Ordering::Relaxed);
return None;
};
self.misses.fetch_add(1, Ordering::Relaxed);
return None;
};
// Move the entry to the end of the queue.
// self.queue is modified while holding a reference to the cache entry;
// so that another thread cannot write to the same key.
{
// If we updated the eviction queue within this much time, then leave it where it is. We're likely to hit it again.
let update_lru = entry.ms_since_last_time() > 500;
if update_lru {
let mut queue = self.queue.lock().unwrap();
queue.remove(entry.index);
entry.index = queue.insert_last(key);
entry.last_time = ReadOnlyAccountCacheEntry::timestamp();
}
let account = entry.account.clone();
drop(entry);
Expand All @@ -113,7 +138,7 @@ impl ReadOnlyAccountsCache {
// Insert the entry at the end of the queue.
let mut queue = self.queue.lock().unwrap();
let index = queue.insert_last(key);
entry.insert(ReadOnlyAccountCacheEntry { account, index });
entry.insert(ReadOnlyAccountCacheEntry::new(account, index));
}
Entry::Occupied(mut entry) => {
let entry = entry.get_mut();
Expand Down

0 comments on commit 5b481a3

Please sign in to comment.