hold items with ref count != 1 in memory (#30414)

* hold items with ref count != 1 in memory

* fix tests
This commit is contained in:
Jeff Washington (jwash) 2023-02-22 08:57:59 -06:00 committed by GitHub
parent 08d71ae8a1
commit db8764f98d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 1 deletions

View File

@ -12,6 +12,7 @@ const STATS_INTERVAL_MS: u64 = 10_000;
#[derive(Debug, Default)]
pub struct BucketMapHolderStats {
pub held_in_mem_ref_count: AtomicU64,
pub held_in_mem_slot_list_len: AtomicU64,
pub held_in_mem_slot_list_cached: AtomicU64,
pub get_mem_us: AtomicU64,
@ -252,6 +253,11 @@ impl BucketMapHolderStats {
self.held_in_mem_slot_list_len.swap(0, Ordering::Relaxed),
i64
),
(
"held_in_mem_ref_count",
self.held_in_mem_ref_count.swap(0, Ordering::Relaxed),
i64
),
(
"held_in_mem_slot_list_cached",
self.held_in_mem_slot_list_cached.swap(0, Ordering::Relaxed),

View File

@ -949,6 +949,9 @@ impl<T: IndexValue> InMemAccountsIndex<T> {
if exceeds_budget {
// if we are already holding too many items in-mem, then we need to be more aggressive at kicking things out
(true, None)
} else if entry.ref_count() != 1 {
Self::update_stat(&self.stats().held_in_mem_ref_count, 1);
(false, None)
} else {
// only read the slot list if we are planning to throw the item out
let slot_list = entry.slot_list.read().unwrap();
@ -1136,6 +1139,8 @@ impl<T: IndexValue> InMemAccountsIndex<T> {
// not evicting, so don't write, even if dirty
continue;
}
} else if v.ref_count() != 1 {
continue;
}
// if we are evicting it, then we need to update disk if we're dirty
if v.clear_dirty() {
@ -1452,13 +1457,42 @@ mod tests {
bucket
}
#[test]
fn test_should_evict_from_mem_ref_count() {
for ref_count in [0, 1, 2] {
let bucket = new_for_test::<u64>();
let startup = false;
let current_age = 0;
let one_element_slot_list = vec![(0, 0)];
let one_element_slot_list_entry = Arc::new(AccountMapEntryInner::new(
one_element_slot_list,
ref_count,
AccountMapEntryMeta::default(),
));
// exceeded budget
assert_eq!(
bucket
.should_evict_from_mem(
current_age,
&one_element_slot_list_entry,
startup,
false,
false,
)
.0,
ref_count == 1
);
}
}
#[test]
fn test_should_evict_from_mem() {
solana_logger::setup();
let bucket = new_for_test::<u64>();
let mut startup = false;
let mut current_age = 0;
let ref_count = 0;
let ref_count = 1;
let one_element_slot_list = vec![(0, 0)];
let one_element_slot_list_entry = Arc::new(AccountMapEntryInner::new(
one_element_slot_list,