AcctIdx: introduce age per in-mem bucket (#19982)
This commit is contained in:
committed by
GitHub
parent
742155c214
commit
f579f73700
@ -1,13 +1,13 @@
|
|||||||
use crate::accounts_index::{
|
use crate::accounts_index::{
|
||||||
AccountMapEntry, AccountMapEntryInner, IndexValue, SlotList, WriteAccountMapEntry,
|
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 crate::bucket_map_holder_stats::BucketMapHolderStats;
|
||||||
use solana_measure::measure::Measure;
|
use solana_measure::measure::Measure;
|
||||||
use solana_sdk::{clock::Slot, pubkey::Pubkey};
|
use solana_sdk::{clock::Slot, pubkey::Pubkey};
|
||||||
use std::collections::{hash_map::Entry, HashMap};
|
use std::collections::{hash_map::Entry, HashMap};
|
||||||
use std::ops::{Bound, RangeBounds, RangeInclusive};
|
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::sync::{Arc, RwLock};
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
@ -15,8 +15,11 @@ type K = Pubkey;
|
|||||||
type CacheRangesHeld = RwLock<Vec<Option<RangeInclusive<Pubkey>>>>;
|
type CacheRangesHeld = RwLock<Vec<Option<RangeInclusive<Pubkey>>>>;
|
||||||
pub type SlotT<T> = (Slot, T);
|
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> {
|
pub struct InMemAccountsIndex<T: IndexValue> {
|
||||||
|
last_age_flushed: AtomicU8,
|
||||||
|
|
||||||
// backing store
|
// backing store
|
||||||
map_internal: RwLock<HashMap<Pubkey, AccountMapEntry<T>>>,
|
map_internal: RwLock<HashMap<Pubkey, AccountMapEntry<T>>>,
|
||||||
storage: Arc<BucketMapHolder<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> {
|
impl<T: IndexValue> InMemAccountsIndex<T> {
|
||||||
pub fn new(storage: &Arc<BucketMapHolder<T>>, bin: usize) -> Self {
|
pub fn new(storage: &Arc<BucketMapHolder<T>>, bin: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -48,9 +52,24 @@ impl<T: IndexValue> InMemAccountsIndex<T> {
|
|||||||
stop_flush: AtomicU64::default(),
|
stop_flush: AtomicU64::default(),
|
||||||
bin_dirty: AtomicBool::default(),
|
bin_dirty: AtomicBool::default(),
|
||||||
flushing_active: 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>>> {
|
fn map(&self) -> &RwLock<HashMap<Pubkey, AccountMapEntry<T>>> {
|
||||||
&self.map_internal
|
&self.map_internal
|
||||||
}
|
}
|
||||||
@ -484,4 +503,13 @@ mod tests {
|
|||||||
assert!(accts.cache_ranges_held.read().unwrap().is_empty());
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user