AcctIdx: introduce age per in-mem bucket (#19982)
This commit is contained in:
parent
742155c214
commit
f579f73700
|
@ -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<Vec<Option<RangeInclusive<Pubkey>>>>;
|
||||
pub type SlotT<T> = (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<T: IndexValue> {
|
||||
last_age_flushed: AtomicU8,
|
||||
|
||||
// backing store
|
||||
map_internal: RwLock<HashMap<Pubkey, AccountMapEntry<T>>>,
|
||||
storage: Arc<BucketMapHolder<T>>,
|
||||
|
@ -38,6 +41,7 @@ impl<T: IndexValue> Debug for InMemAccountsIndex<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)] // temporary during staging
|
||||
impl<T: IndexValue> InMemAccountsIndex<T> {
|
||||
pub fn new(storage: &Arc<BucketMapHolder<T>>, bin: usize) -> Self {
|
||||
Self {
|
||||
|
@ -48,9 +52,24 @@ impl<T: IndexValue> InMemAccountsIndex<T> {
|
|||
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<HashMap<Pubkey, AccountMapEntry<T>>> {
|
||||
&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::<u64>();
|
||||
assert!(!test.get_should_age());
|
||||
test.set_has_aged(0);
|
||||
assert!(test.get_should_age());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue