From 5f19e411c8bc9eb5e13df07fdf2962c394ce1c8e Mon Sep 17 00:00:00 2001 From: Christopher Berner Date: Sat, 26 Oct 2024 17:31:34 -0700 Subject: [PATCH] Fix write cache to be LRU 3d184aa612ae4dcc3ce54fcb27316d3e078b2e35 unintentionally made the write cache evict randomly. This fixes it to be LRU just like the read cache. This speeds up some workloads, like ord indexing, by a factor of 4x or more --- src/tree_store/page_store/cached_file.rs | 20 +++++++++++--------- src/tree_store/page_store/lru_cache.rs | 4 ++++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/tree_store/page_store/cached_file.rs b/src/tree_store/page_store/cached_file.rs index afc48df9..0999a3b0 100644 --- a/src/tree_store/page_store/cached_file.rs +++ b/src/tree_store/page_store/cached_file.rs @@ -88,17 +88,19 @@ impl LRUWriteCache { } fn pop_lowest_priority(&mut self) -> Option<(u64, Arc<[u8]>)> { - let mut selected = None; - for (k, v) in self.cache.iter() { - if v.is_some() { - selected = Some(*k); + for _ in 0..self.cache.len() { + if let Some((k, v)) = self.cache.pop_lowest_priority() { + if let Some(v_inner) = v { + return Some((k, v_inner)); + } else { + // Value is borrowed by take_value(). We can't evict it, so put it back. + self.cache.insert(k, v); + } + } else { + break; } } - if let Some(key) = selected { - self.cache.remove(&key).map(|x| (key, x.unwrap())) - } else { - None - } + None } fn clear(&mut self) { diff --git a/src/tree_store/page_store/lru_cache.rs b/src/tree_store/page_store/lru_cache.rs index d981fdd0..5df77e12 100644 --- a/src/tree_store/page_store/lru_cache.rs +++ b/src/tree_store/page_store/lru_cache.rs @@ -16,6 +16,10 @@ impl LRUCache { } } + pub(crate) fn len(&self) -> usize { + self.cache.len() + } + pub(crate) fn insert(&mut self, key: u64, value: T) -> Option { let result = self .cache