btree: add fast path version of cell_get_raw_region

This commit is contained in:
Jussi Saurio
2025-08-07 09:54:33 +03:00
parent c98136c8c4
commit 4b27cc0d46
2 changed files with 49 additions and 28 deletions

View File

@@ -2795,10 +2795,21 @@ impl BTreeCursor {
{
let old_page = old_page.as_ref().unwrap().get();
let old_page_contents = old_page.get_contents();
let page_type = old_page_contents.page_type();
let max_local = payload_overflow_threshold_max(page_type, usable_space);
let min_local = payload_overflow_threshold_min(page_type, usable_space);
let cell_count = old_page_contents.cell_count();
debug_validate_cells!(&old_page_contents, usable_space as u16);
for cell_idx in 0..old_page_contents.cell_count() {
let (cell_start, cell_len) =
old_page_contents.cell_get_raw_region(cell_idx, usable_space);
for cell_idx in 0..cell_count {
let (cell_start, cell_len) = old_page_contents
._cell_get_raw_region_faster(
cell_idx,
usable_space,
cell_count,
max_local,
min_local,
page_type,
);
let buf = old_page_contents.as_ptr();
let cell_buf = &mut buf[cell_start..cell_start + cell_len];
// TODO(pere): make this reference and not copy

View File

@@ -668,24 +668,42 @@ impl PageContent {
}
/// Get region(start end length) of a cell's payload
/// FIXME: make all usages of [cell_get_raw_region] to use the _faster version in cases where the method is called
/// repeatedly, since page_type, max_local, min_local are the same for all cells on the page. Also consider whether
/// max_local and min_local should be static properties of the page.
pub fn cell_get_raw_region(&self, idx: usize, usable_size: usize) -> (usize, usize) {
let page_type = self.page_type();
let max_local = payload_overflow_threshold_max(page_type, usable_size);
let min_local = payload_overflow_threshold_min(page_type, usable_size);
let cell_count = self.cell_count();
self._cell_get_raw_region_faster(
idx,
usable_size,
cell_count,
max_local,
min_local,
page_type,
)
}
/// Get region(start end length) of a cell's payload
pub fn _cell_get_raw_region_faster(
&self,
idx: usize,
usable_size: usize,
cell_count: usize,
max_local: usize,
min_local: usize,
page_type: PageType,
) -> (usize, usize) {
let buf = self.as_ptr();
let ncells = self.cell_count();
assert!(idx < ncells, "cell_get: idx out of bounds");
assert!(idx < cell_count, "cell_get: idx out of bounds");
let start = self.cell_get_raw_start_offset(idx);
let payload_overflow_threshold_max =
payload_overflow_threshold_max(self.page_type(), usable_size);
let payload_overflow_threshold_min =
payload_overflow_threshold_min(self.page_type(), usable_size);
let len = match self.page_type() {
let len = match page_type {
PageType::IndexInterior => {
let (len_payload, n_payload) = read_varint(&buf[start + 4..]).unwrap();
let (overflows, to_read) = payload_overflows(
len_payload as usize,
payload_overflow_threshold_max,
payload_overflow_threshold_min,
usable_size,
);
let (overflows, to_read) =
payload_overflows(len_payload as usize, max_local, min_local, usable_size);
if overflows {
4 + to_read + n_payload
} else {
@@ -698,12 +716,8 @@ impl PageContent {
}
PageType::IndexLeaf => {
let (len_payload, n_payload) = read_varint(&buf[start..]).unwrap();
let (overflows, to_read) = payload_overflows(
len_payload as usize,
payload_overflow_threshold_max,
payload_overflow_threshold_min,
usable_size,
);
let (overflows, to_read) =
payload_overflows(len_payload as usize, max_local, min_local, usable_size);
if overflows {
to_read + n_payload
} else {
@@ -717,12 +731,8 @@ impl PageContent {
PageType::TableLeaf => {
let (len_payload, n_payload) = read_varint(&buf[start..]).unwrap();
let (_, n_rowid) = read_varint(&buf[start + n_payload..]).unwrap();
let (overflows, to_read) = payload_overflows(
len_payload as usize,
payload_overflow_threshold_max,
payload_overflow_threshold_min,
usable_size,
);
let (overflows, to_read) =
payload_overflows(len_payload as usize, max_local, min_local, usable_size);
if overflows {
to_read + n_payload + n_rowid
} else {