From 8996a2cbe7b0edfb3ed3959db5893a4b1abbe516 Mon Sep 17 00:00:00 2001 From: "Jeff Washington (jwash)" Date: Tue, 12 Oct 2021 14:47:10 -0500 Subject: [PATCH] AcctIdx: set_slot_for_caching --- runtime/src/accounts_db.rs | 4 ++++ runtime/src/accounts_index.rs | 5 +++++ runtime/src/bucket_map_holder.rs | 13 +++++++++++-- runtime/src/bucket_map_holder_stats.rs | 6 ++++++ runtime/src/in_mem_accounts_index.rs | 23 +++++++++++++++++------ 5 files changed, 43 insertions(+), 8 deletions(-) diff --git a/runtime/src/accounts_db.rs b/runtime/src/accounts_db.rs index aaded1a59cdb9b..89789fdb03ee36 100644 --- a/runtime/src/accounts_db.rs +++ b/runtime/src/accounts_db.rs @@ -2179,6 +2179,10 @@ impl AccountsDb { reclaims_time.stop(); + if let Some(slot) = max_clean_root { + self.accounts_index.set_slot_for_caching(slot); + } + self.clean_accounts_stats.report(); datapoint_info!( "clean_accounts", diff --git a/runtime/src/accounts_index.rs b/runtime/src/accounts_index.rs index b058e194d2bff0..529471daf186ac 100644 --- a/runtime/src/accounts_index.rs +++ b/runtime/src/accounts_index.rs @@ -1400,6 +1400,11 @@ impl AccountsIndex { self.storage.storage.set_startup(value); } + /// tell the accounts index the slot above which accounts index entries should be cached + pub fn set_slot_for_caching(&self, slot: Slot) { + self.storage.storage.set_slot_for_caching(slot); + } + /// Get an account /// The latest account that appears in `ancestors` or `roots` is returned. pub(crate) fn get( diff --git a/runtime/src/bucket_map_holder.rs b/runtime/src/bucket_map_holder.rs index a28e79e70bf0ec..3a95089718fc79 100644 --- a/runtime/src/bucket_map_holder.rs +++ b/runtime/src/bucket_map_holder.rs @@ -4,10 +4,10 @@ use crate::in_mem_accounts_index::{InMemAccountsIndex, SlotT}; use crate::waitable_condvar::WaitableCondvar; use solana_bucket_map::bucket_map::{BucketMap, BucketMapConfig}; use solana_measure::measure::Measure; -use solana_sdk::clock::SLOT_MS; +use solana_sdk::clock::{Slot, SLOT_MS}; use solana_sdk::timing::AtomicInterval; use std::fmt::Debug; -use std::sync::atomic::{AtomicBool, AtomicU8, AtomicUsize, Ordering}; +use std::sync::atomic::{AtomicBool, AtomicU64, AtomicU8, AtomicUsize, Ordering}; use std::sync::{Arc, Mutex}; use std::time::Duration; pub type Age = u8; @@ -40,6 +40,9 @@ pub struct BucketMapHolder { /// and writing to disk in parallel are. /// Note startup is an optimization and is not required for correctness. startup: AtomicBool, + + /// used as an input for cache retention + pub slot_for_caching: AtomicU64, } impl Debug for BucketMapHolder { @@ -75,6 +78,11 @@ impl BucketMapHolder { self.startup.load(Ordering::Relaxed) } + /// tell the accounts index the slot above which accounts index entries should be cached + pub fn set_slot_for_caching(&self, slot: Slot) { + self.slot_for_caching.store(slot, Ordering::Relaxed); + } + pub fn set_startup(&self, value: bool) { if !value { self.wait_for_idle(); @@ -151,6 +159,7 @@ impl BucketMapHolder { bins, startup: AtomicBool::default(), mem_budget_mb, + slot_for_caching: AtomicU64::new(u64::MAX), _threads: threads, } } diff --git a/runtime/src/bucket_map_holder_stats.rs b/runtime/src/bucket_map_holder_stats.rs index 0deec6ffd4b3f8..0895733f96d474 100644 --- a/runtime/src/bucket_map_holder_stats.rs +++ b/runtime/src/bucket_map_holder_stats.rs @@ -11,6 +11,7 @@ const STATS_INTERVAL_MS: u64 = 10_000; pub struct BucketMapHolderStats { pub held_in_mem_slot_list_len: AtomicU64, pub held_in_mem_slot_list_cached: AtomicU64, + pub held_in_mem_slot: AtomicU64, pub get_mem_us: AtomicU64, pub gets_from_mem: AtomicU64, pub get_missing_us: AtomicU64, @@ -178,6 +179,11 @@ impl BucketMapHolderStats { self.held_in_mem_slot_list_cached.swap(0, Ordering::Relaxed), i64 ), + ( + "held_in_mem_slot", + self.held_in_mem_slot.swap(0, Ordering::Relaxed), + i64 + ), ("min_in_bin_mem", in_mem_stats.0, i64), ("max_in_bin_mem", in_mem_stats.1, i64), ("count_from_bins_mem", in_mem_stats.2, i64), diff --git a/runtime/src/in_mem_accounts_index.rs b/runtime/src/in_mem_accounts_index.rs index b3a25345f716bc..043e3542f598ca 100644 --- a/runtime/src/in_mem_accounts_index.rs +++ b/runtime/src/in_mem_accounts_index.rs @@ -662,12 +662,23 @@ impl InMemAccountsIndex { } false // keep 0 and > 1 slot lists in mem. They will be cleaned or shrunk soon. } else { - // keep items with slot lists that contained cached items - let remove = !slot_list.iter().any(|(_, info)| info.is_cached()); - if !remove && update_stats { - Self::update_stat(&self.stats().held_in_mem_slot_list_cached, 1); - } - remove + !slot_list.iter().any(|(slot, info)| { + if info.is_cached() { + // keep items with slot lists that contained cached items + if update_stats { + Self::update_stat(&self.stats().held_in_mem_slot_list_cached, 1); + } + true + } else if slot >= &self.storage.slot_for_caching.load(Ordering::Relaxed) { + // keep items with entries where slot >= slot_for_caching + if update_stats { + Self::update_stat(&self.stats().held_in_mem_slot, 1); + } + true + } else { + false + } + }) } } else { false