mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-09 02:04:22 +01:00
state machine for seek_end
This commit is contained in:
@@ -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<IOResult<()>> {
|
||||
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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,3 +36,9 @@ pub enum CountState {
|
||||
Loop,
|
||||
Finish,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum SeekEndState {
|
||||
Start,
|
||||
ProcessPage,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user