diff --git a/core/storage/btree.rs b/core/storage/btree.rs index c243c47f3..4c521cfb6 100644 --- a/core/storage/btree.rs +++ b/core/storage/btree.rs @@ -420,8 +420,7 @@ impl BTreeCursor { fn insert_into_cell(&mut self, page: &mut PageContent, payload: &Vec, cell_idx: usize) { // TODO: insert into cell payload in internal page let pc = self.allocate_cell_space(page, payload.len() as u16); - let mut buf_ref = RefCell::borrow_mut(&page.buffer); - let buf: &mut [u8] = buf_ref.as_mut_slice(); + let buf = page.as_ptr(); // copy data buf[pc as usize..pc as usize + payload.len()].copy_from_slice(payload); @@ -499,10 +498,8 @@ impl BTreeCursor { { // move data from one buffer to another // done in a separate block to satisfy borrow checker - let mut left_buf = RefCell::borrow_mut(&page.buffer); - let left_buf: &mut [u8] = left_buf.as_mut_slice(); - let mut right_buf = RefCell::borrow_mut(&right_page.buffer); - let right_buf: &mut [u8] = right_buf.as_mut_slice(); + let left_buf: &mut [u8] = page.as_ptr(); + let right_buf: &mut [u8] = right_page.as_ptr(); let mut rbrk = right_page.cell_content_area() as usize; @@ -510,7 +507,7 @@ impl BTreeCursor { let (mut cell_pointer_idx, _) = page.cell_get_raw_pointer_region(); // move half of cells to right page for cell_idx in cells_to_move..page.cell_count() { - let (start, len) = page.cell_get_raw_region_borrowed(cell_idx, left_buf); + let (start, len) = page.cell_get_raw_region(cell_idx); // copy data rbrk -= len; right_buf[rbrk..rbrk + len].copy_from_slice(&left_buf[start..start + len]); @@ -677,8 +674,7 @@ impl BTreeCursor { if gap + 2 + amount > top { // defragment self.defragment_page(page_ref, RefCell::borrow(&self.database_header)); - let mut buf_ref = RefCell::borrow_mut(&page_ref.buffer); - let buf = buf_ref.as_mut_slice(); + let buf = page_ref.as_ptr(); top = u16::from_be_bytes([buf[5], buf[6]]) as usize; } @@ -686,8 +682,7 @@ impl BTreeCursor { top -= amount; { - let mut buf_ref = RefCell::borrow_mut(&page_ref.buffer); - let buf = buf_ref.as_mut_slice(); + let buf = page_ref.as_ptr(); buf[5..7].copy_from_slice(&(top as u16).to_be_bytes()); } @@ -711,16 +706,14 @@ impl BTreeCursor { if cloned_page.cell_count() > 0 { let page_type = page.page_type(); - let buf = RefCell::borrow(&cloned_page.buffer); - let buf = buf.as_slice(); - let mut write_buf = RefCell::borrow_mut(&page.buffer); - let write_buf = write_buf.as_mut_slice(); + let read_buf = cloned_page.as_ptr(); + let write_buf = page.as_ptr(); for i in 0..cloned_page.cell_count() { let cell_offset = page.offset + 8; let cell_idx = cell_offset + i * 2; - let pc = u16::from_be_bytes([buf[cell_idx], buf[cell_idx + 1]]) as u64; + let pc = u16::from_be_bytes([read_buf[cell_idx], read_buf[cell_idx + 1]]) as u64; if pc > last_cell { unimplemented!("corrupted page"); } @@ -729,7 +722,7 @@ impl BTreeCursor { let size = match page_type { PageType::TableInterior => { - let (_, nr_key) = match read_varint(&buf[pc as usize ..]) { + let (_, nr_key) = match read_varint(&read_buf[pc as usize ..]) { Ok(v) => v, Err(_) => todo!( "error while parsing varint from cell, probably treat this as corruption?" @@ -738,13 +731,13 @@ impl BTreeCursor { 4 + nr_key as u64 } PageType::TableLeaf => { - let (payload_size, nr_payload) = match read_varint(&buf[pc as usize..]) { + let (payload_size, nr_payload) = match read_varint(&read_buf[pc as usize..]) { Ok(v) => v, Err(_) => todo!( "error while parsing varint from cell, probably treat this as corruption?" ), }; - let (_, nr_key) = match read_varint(&buf[pc as usize + nr_payload..]) { + let (_, nr_key) = match read_varint(&read_buf[pc as usize + nr_payload..]) { Ok(v) => v, Err(_) => todo!( "error while parsing varint from cell, probably treat this as corruption?" @@ -765,7 +758,7 @@ impl BTreeCursor { write_buf[cell_idx..cell_idx + 2].copy_from_slice(&(cbrk as u16).to_be_bytes()); // copy payload write_buf[cbrk as usize..cbrk as usize + size as usize] - .copy_from_slice(&buf[pc as usize..pc as usize + size as usize]); + .copy_from_slice(&read_buf[pc as usize..pc as usize + size as usize]); } } @@ -774,8 +767,7 @@ impl BTreeCursor { // return SQLITE_CORRUPT_PAGE(pPage); // } assert!(cbrk >= first_cell as u64); - let mut write_buf = RefCell::borrow_mut(&page.buffer); - let write_buf = write_buf.as_mut_slice(); + let write_buf = page.as_ptr(); // set new first byte of cell content write_buf[5..7].copy_from_slice(&(cbrk as u16).to_be_bytes()); @@ -791,8 +783,7 @@ impl BTreeCursor { // Free blocks can be zero, meaning the "real free space" that can be used to allocate is expected to be between first cell byte // and end of cell pointer area. fn compute_free_space(&self, page: &PageContent, db_header: Ref) -> u16 { - let buffer = RefCell::borrow(&page.buffer); - let buf = buffer.as_slice(); + let buf = page.as_ptr(); let usable_space = (db_header.page_size - db_header.unused_space as u16) as usize; let mut first_byte_in_cell_content = page.cell_content_area(); @@ -852,8 +843,7 @@ fn find_free_cell(page_ref: &PageContent, db_header: Ref, amount // unuse_space is reserved bytes at the end of page, therefore we must substract from maxpc let mut pc = page_ref.first_freeblock() as usize; - let buf_ref = RefCell::borrow(&page_ref.buffer); - let buf = buf_ref.as_slice(); + let buf = page_ref.as_ptr(); let usable_space = (db_header.page_size - db_header.unused_space as u16) as usize; let maxpc = usable_space - amount; diff --git a/core/storage/sqlite3_ondisk.rs b/core/storage/sqlite3_ondisk.rs index 6bd0333f3..64ea91b29 100644 --- a/core/storage/sqlite3_ondisk.rs +++ b/core/storage/sqlite3_ondisk.rs @@ -280,58 +280,48 @@ impl PageContent { self.read_u8(self.offset).try_into().unwrap() } - fn read_u8(&self, pos: usize) -> u8 { - // unsafe trick to borrow twice + pub fn as_ptr(&self) -> &mut [u8] { unsafe { + // unsafe trick to borrow twice let buf_pointer = &self.buffer.as_ptr(); - let buf = (*buf_pointer).as_ref().unwrap().as_slice(); - buf[pos] + let buf = (*buf_pointer).as_mut().unwrap().as_mut_slice(); + buf } } + fn read_u8(&self, pos: usize) -> u8 { + let buf = self.as_ptr(); + buf[pos] + } + fn read_u16(&self, pos: usize) -> u16 { - unsafe { - let buf_pointer = &self.buffer.as_ptr(); - let buf = (*buf_pointer).as_ref().unwrap().as_slice(); - u16::from_be_bytes([buf[self.offset + pos], buf[self.offset + pos + 1]]) - } + let buf = self.as_ptr(); + u16::from_be_bytes([buf[self.offset + pos], buf[self.offset + pos + 1]]) } fn read_u32(&self, pos: usize) -> u32 { - unsafe { - let buf_pointer = &self.buffer.as_ptr(); - let buf = (*buf_pointer).as_ref().unwrap().as_slice(); - u32::from_be_bytes([ - buf[self.offset + pos], - buf[self.offset + pos + 1], - buf[self.offset + pos + 2], - buf[self.offset + pos + 3], - ]) - } + let buf = self.as_ptr(); + u32::from_be_bytes([ + buf[self.offset + pos], + buf[self.offset + pos + 1], + buf[self.offset + pos + 2], + buf[self.offset + pos + 3], + ]) } pub fn write_u8(&self, pos: usize, value: u8) { - unsafe { - let buf_pointer = &self.buffer.as_ptr(); - let buf = (*buf_pointer).as_mut().unwrap().as_mut_slice(); - buf[self.offset + pos] = value; - } + let buf = self.as_ptr(); + buf[self.offset + pos] = value; } pub fn write_u16(&self, pos: usize, value: u16) { - unsafe { - let buf_pointer = &self.buffer.as_ptr(); - let buf = (*buf_pointer).as_mut().unwrap().as_mut_slice(); - buf[self.offset + pos..self.offset + pos + 2].copy_from_slice(&value.to_be_bytes()); - } + let buf = self.as_ptr(); + buf[self.offset + pos..self.offset + pos + 2].copy_from_slice(&value.to_be_bytes()); } pub fn write_u32(&self, pos: usize, value: u32) { - unsafe { - let buf_pointer = &self.buffer.as_ptr(); - let buf = (*buf_pointer).as_mut().unwrap().as_mut_slice(); - buf[self.offset + pos..self.offset + pos + 4].copy_from_slice(&value.to_be_bytes()); - } + let buf = self.as_ptr(); + buf[self.offset + pos..self.offset + pos + 4].copy_from_slice(&value.to_be_bytes()); } pub fn first_freeblock(&self) -> u16 { @@ -360,8 +350,7 @@ impl PageContent { } pub fn cell_get(&self, idx: usize) -> Result { - let buf = self.buffer.borrow(); - let buf = buf.as_slice(); + let buf = self.as_ptr(); let ncells = self.cell_count(); let cell_start = match self.page_type() { @@ -388,12 +377,7 @@ impl PageContent { } pub fn cell_get_raw_region(&self, idx: usize) -> (usize, usize) { - let mut buf = self.buffer.borrow_mut(); - let buf = buf.as_mut_slice(); - self.cell_get_raw_region_borrowed(idx, buf) - } - - pub fn cell_get_raw_region_borrowed(&self, idx: usize, buf: &mut [u8]) -> (usize, usize) { + let buf = self.as_ptr(); let ncells = self.cell_count(); let cell_start = match self.page_type() { PageType::IndexInterior => 12, @@ -438,8 +422,7 @@ impl PageContent { } pub fn write_database_header(&self, header: &DatabaseHeader) { - let mut buf = self.buffer.borrow_mut(); - let buf = buf.as_mut_slice(); + let buf = self.as_ptr(); write_header_to_buf(buf, header); } }