AcctIdx: only remove a fixed number of items per write lock (#23795)
This commit is contained in:
committed by
GitHub
parent
10eeafd3d6
commit
24f6855f86
@ -1123,42 +1123,43 @@ impl<T: IndexValue> InMemAccountsIndex<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut evicted = 0;
|
let mut evicted = 0;
|
||||||
// consider chunking these so we don't hold the write lock too long
|
// chunk these so we don't hold the write lock too long
|
||||||
let mut map = self.map().write().unwrap();
|
for evictions in evictions.chunks(50) {
|
||||||
for k in evictions {
|
let mut map = self.map().write().unwrap();
|
||||||
if let Entry::Occupied(occupied) = map.entry(k) {
|
for k in evictions {
|
||||||
let v = occupied.get();
|
if let Entry::Occupied(occupied) = map.entry(*k) {
|
||||||
if Arc::strong_count(v) > 1 {
|
let v = occupied.get();
|
||||||
// someone is holding the value arc's ref count and could modify it, so do not evict
|
if Arc::strong_count(v) > 1 {
|
||||||
v.try_exchange_age(next_age_on_failure, current_age);
|
// someone is holding the value arc's ref count and could modify it, so do not evict
|
||||||
continue;
|
v.try_exchange_age(next_age_on_failure, current_age);
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if v.dirty()
|
if v.dirty()
|
||||||
|| (!randomly_evicted
|
|| (!randomly_evicted
|
||||||
&& !Self::should_evict_based_on_age(current_age, v, startup))
|
&& !Self::should_evict_based_on_age(current_age, v, startup))
|
||||||
{
|
{
|
||||||
// marked dirty or bumped in age after we looked above
|
// marked dirty or bumped in age after we looked above
|
||||||
// these evictions will be handled in later passes (at later ages)
|
// these evictions will be handled in later passes (at later ages)
|
||||||
// but, at startup, everything is ready to age out if it isn't dirty
|
// but, at startup, everything is ready to age out if it isn't dirty
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if stop_evictions_changes_at_start != self.get_stop_evictions_changes() {
|
if stop_evictions_changes_at_start != self.get_stop_evictions_changes() {
|
||||||
// ranges were changed
|
// ranges were changed
|
||||||
v.try_exchange_age(next_age_on_failure, current_age);
|
v.try_exchange_age(next_age_on_failure, current_age);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// all conditions for eviction succeeded, so really evict item from in-mem cache
|
// all conditions for eviction succeeded, so really evict item from in-mem cache
|
||||||
evicted += 1;
|
evicted += 1;
|
||||||
occupied.remove();
|
occupied.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if map.is_empty() {
|
||||||
|
map.shrink_to_fit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if map.is_empty() {
|
|
||||||
map.shrink_to_fit();
|
|
||||||
}
|
|
||||||
drop(map);
|
|
||||||
self.stats()
|
self.stats()
|
||||||
.insert_or_delete_mem_count(false, self.bin, evicted);
|
.insert_or_delete_mem_count(false, self.bin, evicted);
|
||||||
Self::update_stat(&self.stats().flush_entries_evicted_from_mem, evicted as u64);
|
Self::update_stat(&self.stats().flush_entries_evicted_from_mem, evicted as u64);
|
||||||
|
Reference in New Issue
Block a user