From cfadc4f5792fa8430af7124e6f258d7ab6894b89 Mon Sep 17 00:00:00 2001 From: PThorpe92 Date: Tue, 2 Sep 2025 09:32:35 -0400 Subject: [PATCH] Fix memory leak in page cache during balancing --- core/storage/page_cache.rs | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/core/storage/page_cache.rs b/core/storage/page_cache.rs index eb8ffb627..f4b3f7fe9 100644 --- a/core/storage/page_cache.rs +++ b/core/storage/page_cache.rs @@ -111,15 +111,29 @@ impl DumbLruPageCache { ) -> Result<(), CacheError> { trace!("insert(key={:?})", key); // Check first if page already exists in cache - if !ignore_exists { - if let Some(existing_page_ref) = self.get(&key)? { - assert!( - Arc::ptr_eq(&value, &existing_page_ref), - "Attempted to insert different page with same key: {key:?}" - ); - return Err(CacheError::KeyExists); + let existing_ptr = self.map.borrow().get(&key).copied(); + if let Some(ptr) = existing_ptr { + if !ignore_exists { + if let Some(existing_page_ref) = self.get(&key)? { + assert!( + Arc::ptr_eq(&value, &existing_page_ref), + "Attempted to insert different page with same key: {key:?}" + ); + return Err(CacheError::KeyExists); + } + } else { + // ignore_exists is called when the existing entry needs to be updated in place + unsafe { + let entry = ptr.as_ptr(); + (*entry).page = value; + } + self.unlink(ptr); + self.touch(ptr); + return Ok(()); } } + + // Key doesn't exist, proceed with new entry self.make_room_for(1)?; let entry = Box::new(PageCacheEntry { key, @@ -130,7 +144,6 @@ impl DumbLruPageCache { let ptr_raw = Box::into_raw(entry); let ptr = unsafe { NonNull::new_unchecked(ptr_raw) }; self.touch(ptr); - self.map.borrow_mut().insert(key, ptr); Ok(()) }