From 35e2088b7ea9e7c299bcb29b6fa6ae98fd2ba566 Mon Sep 17 00:00:00 2001 From: Pere Diaz Bou Date: Mon, 19 May 2025 15:00:32 +0200 Subject: [PATCH] cacheflush move dirty page to new snapshot After inserting a page into the wal, we dispose of the modified page. This is unnecessary as we can simply move new page to the newest snapshot where this page can be read. --- core/storage/pager.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/core/storage/pager.rs b/core/storage/pager.rs index 7d1acde7d..f369c9d57 100644 --- a/core/storage/pager.rs +++ b/core/storage/pager.rs @@ -461,6 +461,9 @@ impl Pager { Some(wal) => wal.borrow().get_max_frame(), None => 0, }; + let max_frame_after_append = self.wal.as_ref().map(|wal| { + wal.borrow().get_max_frame() + self.dirty_pages.borrow().len() as u64 + }); for page_id in self.dirty_pages.borrow().iter() { let mut cache = self.page_cache.write(); let page_key = PageCacheKey::new(*page_id, Some(max_frame)); @@ -473,6 +476,17 @@ impl Pager { db_size, self.flush_info.borrow().in_flight_writes.clone(), )?; + // Assuming writer will always end append frames at frameid == this_transaction.max_frame + dirty_pages, + // we can insert this page with a new key into that new "snapshot" that has the newest max frame. We don't + // simply clone the page and insert with new key because next cache.delete will invalidate the contents of the page, + // therefore we need to clone the contents itself and place them on the new page. Cloning contents should be fast because + // buffer is wrapped around an Arc. + let new_page = Page::new(*page_id); + new_page.get().contents = Some(page.get_contents().clone()); + new_page.set_loaded(); + let new_page: Arc = Arc::new(new_page); + let new_page_key = PageCacheKey::new(*page_id, max_frame_after_append); + cache.insert(new_page_key, new_page).map_err(|e| {LimboError::InternalError(format!("Failed to delete page {:?} from cache during flush: {:?}. Might be actively referenced.", page_id, e))})?; } page.clear_dirty(); // This page is no longer valid.