AcctIdx: first pass at aging buckets (#20008)
This commit is contained in:
parent
b507715d44
commit
c3679ab9bd
|
@ -88,12 +88,16 @@ impl<T: IndexValue> BucketMapHolder<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bucket_flushed_at_current_age(&self) {
|
pub fn bucket_flushed_at_current_age(&self) {
|
||||||
self.count_ages_flushed.fetch_add(1, Ordering::Relaxed);
|
self.count_ages_flushed.fetch_add(1, Ordering::Acquire);
|
||||||
}
|
}
|
||||||
|
|
||||||
// have all buckets been flushed at the current age?
|
// have all buckets been flushed at the current age?
|
||||||
pub fn all_buckets_flushed_at_current_age(&self) -> bool {
|
pub fn all_buckets_flushed_at_current_age(&self) -> bool {
|
||||||
self.count_ages_flushed.load(Ordering::Relaxed) >= self.bins
|
self.count_ages_flushed() >= self.bins
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn count_ages_flushed(&self) -> usize {
|
||||||
|
self.count_ages_flushed.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn maybe_advance_age(&self) -> bool {
|
pub fn maybe_advance_age(&self) -> bool {
|
||||||
|
|
|
@ -59,15 +59,19 @@ impl<T: IndexValue> InMemAccountsIndex<T> {
|
||||||
|
|
||||||
/// true if this bucket needs to call flush for the current age
|
/// true if this bucket needs to call flush for the current age
|
||||||
/// we need to scan each bucket once per value of age
|
/// we need to scan each bucket once per value of age
|
||||||
fn get_should_age(&self) -> bool {
|
fn get_should_age(&self, age: Age) -> bool {
|
||||||
let last_age_flushed = self.last_age_flushed.load(Ordering::Relaxed);
|
let last_age_flushed = self.last_age_flushed();
|
||||||
let age = self.storage.age.load(Ordering::Relaxed);
|
last_age_flushed != age
|
||||||
last_age_flushed == age
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// called after flush scans this bucket at the current age
|
/// called after flush scans this bucket at the current age
|
||||||
fn set_has_aged(&self, age: Age) {
|
fn set_has_aged(&self, age: Age) {
|
||||||
self.last_age_flushed.store(age, Ordering::Relaxed);
|
self.last_age_flushed.store(age, Ordering::Relaxed);
|
||||||
|
self.storage.bucket_flushed_at_current_age();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn last_age_flushed(&self) -> Age {
|
||||||
|
self.last_age_flushed.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map(&self) -> &RwLock<HashMap<Pubkey, AccountMapEntry<T>>> {
|
fn map(&self) -> &RwLock<HashMap<Pubkey, AccountMapEntry<T>>> {
|
||||||
|
@ -411,8 +415,10 @@ impl<T: IndexValue> InMemAccountsIndex<T> {
|
||||||
|
|
||||||
fn flush_internal(&self) {
|
fn flush_internal(&self) {
|
||||||
let was_dirty = self.bin_dirty.swap(false, Ordering::Acquire);
|
let was_dirty = self.bin_dirty.swap(false, Ordering::Acquire);
|
||||||
if !was_dirty {
|
let current_age = self.storage.current_age();
|
||||||
// wasn't dirty, no need to flush
|
let iterate_for_age = self.get_should_age(current_age);
|
||||||
|
if !was_dirty && !iterate_for_age {
|
||||||
|
// wasn't dirty and no need to age, so no need to flush this bucket
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,6 +437,11 @@ impl<T: IndexValue> InMemAccountsIndex<T> {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
if iterate_for_age {
|
||||||
|
// completed iteration of the buckets at the current age
|
||||||
|
assert_eq!(current_age, self.storage.current_age());
|
||||||
|
self.set_has_aged(current_age);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stats(&self) -> &BucketMapHolderStats {
|
fn stats(&self) -> &BucketMapHolderStats {
|
||||||
|
@ -518,8 +529,22 @@ mod tests {
|
||||||
fn test_age() {
|
fn test_age() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
let test = new_for_test::<u64>();
|
let test = new_for_test::<u64>();
|
||||||
assert!(!test.get_should_age());
|
assert!(test.get_should_age(test.storage.current_age()));
|
||||||
|
assert_eq!(test.storage.count_ages_flushed(), 0);
|
||||||
test.set_has_aged(0);
|
test.set_has_aged(0);
|
||||||
assert!(test.get_should_age());
|
assert!(!test.get_should_age(test.storage.current_age()));
|
||||||
|
assert_eq!(test.storage.count_ages_flushed(), 1);
|
||||||
|
// simulate rest of buckets aging
|
||||||
|
for _ in 1..BINS_FOR_TESTING {
|
||||||
|
assert!(!test.storage.all_buckets_flushed_at_current_age());
|
||||||
|
test.storage.bucket_flushed_at_current_age();
|
||||||
|
}
|
||||||
|
assert!(test.storage.all_buckets_flushed_at_current_age());
|
||||||
|
// advance age
|
||||||
|
test.storage.increment_age();
|
||||||
|
assert_eq!(test.storage.current_age(), 1);
|
||||||
|
assert!(!test.storage.all_buckets_flushed_at_current_age());
|
||||||
|
assert!(test.get_should_age(test.storage.current_age()));
|
||||||
|
assert_eq!(test.storage.count_ages_flushed(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue