diff --git a/runtime/src/in_mem_accounts_index.rs b/runtime/src/in_mem_accounts_index.rs index 87bba1c371..de577e5da9 100644 --- a/runtime/src/in_mem_accounts_index.rs +++ b/runtime/src/in_mem_accounts_index.rs @@ -1,13 +1,13 @@ use crate::accounts_index::{ AccountMapEntry, AccountMapEntryInner, IndexValue, SlotList, WriteAccountMapEntry, }; -use crate::bucket_map_holder::BucketMapHolder; +use crate::bucket_map_holder::{Age, BucketMapHolder}; use crate::bucket_map_holder_stats::BucketMapHolderStats; use solana_measure::measure::Measure; use solana_sdk::{clock::Slot, pubkey::Pubkey}; use std::collections::{hash_map::Entry, HashMap}; use std::ops::{Bound, RangeBounds, RangeInclusive}; -use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; +use std::sync::atomic::{AtomicBool, AtomicU64, AtomicU8, Ordering}; use std::sync::{Arc, RwLock}; use std::fmt::Debug; @@ -15,8 +15,11 @@ type K = Pubkey; type CacheRangesHeld = RwLock>>>; pub type SlotT = (Slot, T); -// one instance of this represents one bin of the accounts index. +#[allow(dead_code)] // temporary during staging + // one instance of this represents one bin of the accounts index. pub struct InMemAccountsIndex { + last_age_flushed: AtomicU8, + // backing store map_internal: RwLock>>, storage: Arc>, @@ -38,6 +41,7 @@ impl Debug for InMemAccountsIndex { } } +#[allow(dead_code)] // temporary during staging impl InMemAccountsIndex { pub fn new(storage: &Arc>, bin: usize) -> Self { Self { @@ -48,9 +52,24 @@ impl InMemAccountsIndex { stop_flush: AtomicU64::default(), bin_dirty: AtomicBool::default(), flushing_active: AtomicBool::default(), + // initialize this to max, to make it clear we have not flushed at age 0, the starting age + last_age_flushed: AtomicU8::new(Age::MAX), } } + /// true if this bucket needs to call flush for the current age + /// we need to scan each bucket once per value of age + fn get_should_age(&self) -> bool { + let last_age_flushed = self.last_age_flushed.load(Ordering::Relaxed); + let age = self.storage.age.load(Ordering::Relaxed); + last_age_flushed == age + } + + /// called after flush scans this bucket at the current age + fn set_has_aged(&self, age: Age) { + self.last_age_flushed.store(age, Ordering::Relaxed); + } + fn map(&self) -> &RwLock>> { &self.map_internal } @@ -484,4 +503,13 @@ mod tests { assert!(accts.cache_ranges_held.read().unwrap().is_empty()); } } + + #[test] + fn test_age() { + solana_logger::setup(); + let test = new_for_test::(); + assert!(!test.get_should_age()); + test.set_has_aged(0); + assert!(test.get_should_age()); + } }