From fe0e4bcbb72ab2b0bb9f506aa5d9826193d1455a Mon Sep 17 00:00:00 2001 From: pedrocarlo Date: Mon, 11 Aug 2025 12:05:51 -0300 Subject: [PATCH] state machine for `seek_end` --- core/storage/btree.rs | 51 ++++++++++++++++++++-------------- core/storage/state_machines.rs | 6 ++++ 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/core/storage/btree.rs b/core/storage/btree.rs index 0e2a1e2f3..6693d7c8f 100644 --- a/core/storage/btree.rs +++ b/core/storage/btree.rs @@ -10,7 +10,7 @@ use crate::{ LEAF_PAGE_HEADER_SIZE_BYTES, LEFT_CHILD_PTR_SIZE_BYTES, }, state_machines::{ - AdvanceState, CountState, EmptyTableState, MoveToRightState, RewindState, + AdvanceState, CountState, EmptyTableState, MoveToRightState, RewindState, SeekEndState, SeekToLastState, }, }, @@ -556,6 +556,8 @@ pub struct BTreeCursor { advance_state: AdvanceState, /// State machine for [BTreeCursor::count] count_state: CountState, + /// State machine for [BTreeCursor::seek_end] + seek_end_state: SeekEndState, } /// We store the cell index and cell count for each page in the stack. @@ -621,6 +623,7 @@ impl BTreeCursor { rewind_state: RewindState::Start, advance_state: AdvanceState::Start, count_state: CountState::Start, + seek_end_state: SeekEndState::Start, } } @@ -4135,28 +4138,34 @@ impl BTreeCursor { pub fn seek_end(&mut self) -> Result> { assert!(self.mv_cursor.is_none()); // unsure about this -_- - let _c = self.move_to_root()?; - loop { - let mem_page = self.stack.top(); - let page_id = mem_page.get().get().id; - let (page, _c) = self.read_page(page_id)?; - return_if_locked_maybe_load!(self.pager, page); - - let page = page.get(); - let contents = page.get().contents.as_ref().unwrap(); - if contents.is_leaf() { - // set cursor just past the last cell to append - self.stack.set_cell_index(contents.cell_count() as i32); - return Ok(IOResult::Done(())); + match self.seek_end_state { + SeekEndState::Start => { + let _c = self.move_to_root()?; + self.seek_end_state = SeekEndState::ProcessPage; + Ok(IOResult::IO) } - - match contents.rightmost_pointer() { - Some(right_most_pointer) => { - self.stack.set_cell_index(contents.cell_count() as i32 + 1); // invalid on interior - let (child, _c) = self.read_page(right_most_pointer as usize)?; - self.stack.push(child); + SeekEndState::ProcessPage => { + let mem_page = self.stack.top(); + let page = mem_page.get(); + // TODO: remove this with IO Completion tracking + return_if_locked!(page); + let contents = page.get().contents.as_ref().unwrap(); + if contents.is_leaf() { + // set cursor just past the last cell to append + self.stack.set_cell_index(contents.cell_count() as i32); + self.seek_end_state = SeekEndState::Start; + return Ok(IOResult::Done(())); + } + + match contents.rightmost_pointer() { + Some(right_most_pointer) => { + self.stack.set_cell_index(contents.cell_count() as i32 + 1); // invalid on interior + let (child, _c) = self.read_page(right_most_pointer as usize)?; + self.stack.push(child); + Ok(IOResult::IO) + } + None => unreachable!("interior page must have rightmost pointer"), } - None => unreachable!("interior page must have rightmost pointer"), } } } diff --git a/core/storage/state_machines.rs b/core/storage/state_machines.rs index d2e7190ef..86b0de64a 100644 --- a/core/storage/state_machines.rs +++ b/core/storage/state_machines.rs @@ -36,3 +36,9 @@ pub enum CountState { Loop, Finish, } + +#[derive(Debug, Clone, Copy)] +pub enum SeekEndState { + Start, + ProcessPage, +}