diff --git a/core/storage/btree.rs b/core/storage/btree.rs index 5a23b6706..65e9c8b49 100644 --- a/core/storage/btree.rs +++ b/core/storage/btree.rs @@ -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 diff --git a/core/storage/sqlite3_ondisk.rs b/core/storage/sqlite3_ondisk.rs index 2191cc81a..8d5c5eb1f 100644 --- a/core/storage/sqlite3_ondisk.rs +++ b/core/storage/sqlite3_ondisk.rs @@ -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 {