From 23ae5a27c473b142e45cea1966d72af18f35f2a8 Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Sat, 26 Apr 2025 11:32:24 +0300 Subject: [PATCH] btree/tablebtree_move_to: micro-optimizations --- core/storage/btree.rs | 29 +++++++---------------------- core/storage/sqlite3_ondisk.rs | 17 +++++++++++++++++ core/types.rs | 1 + 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/core/storage/btree.rs b/core/storage/btree.rs index d191227a4..02c60363d 100644 --- a/core/storage/btree.rs +++ b/core/storage/btree.rs @@ -1043,18 +1043,8 @@ impl BTreeCursor { loop { if min > max { if let Some(leftmost_matching_cell) = leftmost_matching_cell { - self.stack.set_cell_index(leftmost_matching_cell as i32); - let matching_cell = contents.cell_get( - leftmost_matching_cell, - payload_overflow_threshold_max( - contents.page_type(), - self.usable_space() as u16, - ), - payload_overflow_threshold_min( - contents.page_type(), - self.usable_space() as u16, - ), - self.usable_space(), + let left_child_page = contents.cell_table_interior_read_left_child_page( + leftmost_matching_cell as usize, )?; // If we found our target rowid in the left subtree, // we need to move the parent cell pointer forwards or backwards depending on the iteration direction. @@ -1064,15 +1054,11 @@ impl BTreeCursor { // this parent: rowid 666 // left child has: 664,665,666 // we need to move to the previous parent (with e.g. rowid 663) when iterating backwards. - self.stack.next_cell_in_direction(iter_dir); - let BTreeCell::TableInteriorCell(TableInteriorCell { - _left_child_page, - .. - }) = matching_cell - else { - unreachable!("unexpected cell type: {:?}", matching_cell); - }; - let mem_page = self.pager.read_page(_left_child_page as usize)?; + let index_change = + -1 + (iter_dir == IterationDirection::Forwards) as i32 * 2; + self.stack + .set_cell_index(leftmost_matching_cell as i32 + index_change); + let mem_page = self.pager.read_page(left_child_page as usize)?; self.stack.push(mem_page); continue 'outer; } @@ -1089,7 +1075,6 @@ impl BTreeCursor { } } let cur_cell_idx = (min + max) / 2; - self.stack.set_cell_index(cur_cell_idx as i32); let cell_rowid = contents.cell_table_interior_read_rowid(cur_cell_idx as usize)?; // in sqlite btrees left child pages have <= keys. // table btrees can have a duplicate rowid in the interior cell, so for example if we are looking for rowid=10, diff --git a/core/storage/sqlite3_ondisk.rs b/core/storage/sqlite3_ondisk.rs index 8e091ef64..315d01460 100644 --- a/core/storage/sqlite3_ondisk.rs +++ b/core/storage/sqlite3_ondisk.rs @@ -617,6 +617,23 @@ impl PageContent { Ok(rowid) } + /// Read the left child page of a table interior cell. + #[inline(always)] + pub fn cell_table_interior_read_left_child_page(&self, idx: usize) -> Result { + assert!(self.page_type() == PageType::TableInterior); + let buf = self.as_ptr(); + const INTERIOR_PAGE_HEADER_SIZE_BYTES: usize = 12; + let cell_pointer_array_start = INTERIOR_PAGE_HEADER_SIZE_BYTES; + let cell_pointer = cell_pointer_array_start + (idx * 2); + let cell_pointer = self.read_u16(cell_pointer) as usize; + Ok(u32::from_be_bytes([ + buf[cell_pointer], + buf[cell_pointer + 1], + buf[cell_pointer + 2], + buf[cell_pointer + 3], + ])) + } + /// Read the rowid of a table leaf cell. #[inline(always)] pub fn cell_table_leaf_read_rowid(&self, idx: usize) -> Result { diff --git a/core/types.rs b/core/types.rs index b2a7a053b..5d86f97f3 100644 --- a/core/types.rs +++ b/core/types.rs @@ -1402,6 +1402,7 @@ impl SeekOp { /// A seek with SeekOp::LE implies: /// Find the last table/index key that compares less than or equal to the seek key /// -> used in backwards iteration. + #[inline(always)] pub fn iteration_direction(&self) -> IterationDirection { match self { SeekOp::EQ | SeekOp::GE | SeekOp::GT => IterationDirection::Forwards,