From 6802bb7e6a214d774c8a45c93869e2d9813993b1 Mon Sep 17 00:00:00 2001 From: Pere Diaz Bou Date: Wed, 8 Jan 2025 19:05:49 +0100 Subject: [PATCH] distinguish balance and balance_non_root `balance_non_root` should be as close as possible to `balance_non_root` in SQLite. This commits extract `balance_non_root` from `balance` and renames `balance_leaf` to `balance` as it enables future work on a complete `balance_non_root` procedure. --- core/storage/btree.rs | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/core/storage/btree.rs b/core/storage/btree.rs index 481866ee7..c84a0c2c0 100644 --- a/core/storage/btree.rs +++ b/core/storage/btree.rs @@ -78,6 +78,7 @@ macro_rules! return_if_locked { enum WriteState { Start, BalanceStart, + BalanceNonRoot, BalanceGetParentPage, BalanceMoveUp, Finish, @@ -730,9 +731,10 @@ impl BTreeCursor { } } WriteState::BalanceStart + | WriteState::BalanceNonRoot | WriteState::BalanceMoveUp | WriteState::BalanceGetParentPage => { - return_if_io!(self.balance_leaf()); + return_if_io!(self.balance()); } WriteState::Finish => { self.write_info.state = WriteState::Start; @@ -882,7 +884,7 @@ impl BTreeCursor { /// This is a naive algorithm that doesn't try to distribute cells evenly by content. /// It will try to split the page in half by keys not by content. /// Sqlite tries to have a page at least 40% full. - fn balance_leaf(&mut self) -> Result> { + fn balance(&mut self) -> Result> { let state = &self.write_info.state; match state { WriteState::BalanceStart => { @@ -906,7 +908,31 @@ impl BTreeCursor { self.balance_root(); return Ok(CursorResult::Ok(())); } - debug!("Balancing leaf. leaf={}", current_page.get().id); + + self.write_info.state = WriteState::BalanceNonRoot; + self.balance_non_root() + } + WriteState::BalanceNonRoot + | WriteState::BalanceGetParentPage + | WriteState::BalanceMoveUp => self.balance_non_root(), + + _ => unreachable!("invalid balance leaf state {:?}", state), + } + } + + fn balance_non_root(&mut self) -> Result> { + let state = &self.write_info.state; + match state { + WriteState::Start => todo!(), + WriteState::BalanceStart => todo!(), + WriteState::BalanceNonRoot => { + // drop divider cells and find right pointer + // NOTE: since we are doing a simple split we only finding the pointer we want to update (right pointer). + // Right pointer means cell that points to the last page, as we don't really want to drop this one. This one + // can be a "rightmost pointer" or a "cell". + // we always asumme there is a parent + let current_page = self.stack.top(); + debug!("balance_non_root(page={})", current_page.get().id); // Copy of page used to reference cell bytes. // This needs to be saved somewhere safe so taht references still point to here, @@ -1186,8 +1212,7 @@ impl BTreeCursor { let _ = self.write_info.page_copy.take(); Ok(CursorResult::Ok(())) } - - _ => unreachable!("invalid balance leaf state {:?}", state), + WriteState::Finish => todo!(), } }