hold items with ref count != 1 in memory (#30414)
* hold items with ref count != 1 in memory * fix tests
This commit is contained in:
parent
08d71ae8a1
commit
db8764f98d
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue