diff --git a/core/storage/btree.rs b/core/storage/btree.rs index 98f001485..0da906386 100644 --- a/core/storage/btree.rs +++ b/core/storage/btree.rs @@ -1317,7 +1317,7 @@ impl BTreeCursor { balance_info.pages_to_balance[i].set_dirty(); pages_to_balance_new.push(balance_info.pages_to_balance[i].clone()); } else { - let page = self.allocate_page(page_type, 0); + let page = self.pager.do_allocate_page(page_type, 0); pages_to_balance_new.push(page); // Since this page didn't exist before, we can set it to cells length as it // marks them as empty since it is a prefix sum of cells. @@ -1476,7 +1476,7 @@ impl BTreeCursor { let root = self.stack.top(); let root_contents = root.get_contents(); - let child = self.allocate_page(root_contents.page_type(), 0); + let child = self.pager.do_allocate_page(root_contents.page_type(), 0); tracing::debug!( "Balancing root. root={}, rightmost={}", @@ -1533,21 +1533,8 @@ impl BTreeCursor { self.stack.push(child.clone()); } - /// Allocate a new page to the btree via the pager. - /// This marks the page as dirty and writes the page header. - fn allocate_page(&self, page_type: PageType, offset: usize) -> PageRef { - let page = self.pager.allocate_page().unwrap(); - btree_init_page(&page, page_type, offset, self.usable_space() as u16); - page - } - - /// The "usable size" of a database page is the page size specified by the 2-byte integer at offset 16 - /// in the header, minus the "reserved" space size recorded in the 1-byte integer at offset 20 in the header. - /// The usable size of a page might be an odd number. However, the usable size is not allowed to be less than 480. - /// In other words, if the page size is 512, then the reserved space size cannot exceed 32. fn usable_space(&self) -> usize { - let db_header = self.pager.db_header.borrow(); - (db_header.page_size - db_header.reserved_space as u16) as usize + self.pager.usable_space() } /// Find the index of the cell in the page that contains the given rowid. @@ -1855,20 +1842,6 @@ impl BTreeCursor { } } - pub fn btree_create(&mut self, flags: usize) -> u32 { - let page_type = match flags { - 1 => PageType::TableLeaf, - 2 => PageType::IndexLeaf, - _ => unreachable!( - "wrong create table flags, should be 1 for table and 2 for index, got {}", - flags, - ), - }; - let page = self.allocate_page(page_type, 0); - let id = page.get().id; - id as u32 - } - fn clear_overflow_pages(&self, cell: &BTreeCell) -> Result> { // Get overflow info based on cell type let (first_overflow_page, n_overflow) = match cell { diff --git a/core/storage/pager.rs b/core/storage/pager.rs index 20e7f9e6b..526374b96 100644 --- a/core/storage/pager.rs +++ b/core/storage/pager.rs @@ -1,7 +1,7 @@ use crate::result::LimboResult; use crate::storage::buffer_pool::BufferPool; use crate::storage::database::DatabaseStorage; -use crate::storage::sqlite3_ondisk::{self, DatabaseHeader, PageContent}; +use crate::storage::sqlite3_ondisk::{self, DatabaseHeader, PageContent, PageType}; use crate::storage::wal::{CheckpointResult, Wal}; use crate::{Buffer, LimboError, Result}; use parking_lot::RwLock; @@ -203,6 +203,37 @@ impl Pager { }) } + pub fn btree_create(&self, flags: usize) -> u32 { + let page_type = match flags { + 1 => PageType::TableLeaf, + 2 => PageType::IndexLeaf, + _ => unreachable!( + "wrong create table flags, should be 1 for table and 2 for index, got {}", + flags, + ), + }; + let page = self.do_allocate_page(page_type, 0); + let id = page.get().id; + id as u32 + } + + /// Allocate a new page to the btree via the pager. + /// This marks the page as dirty and writes the page header. + pub fn do_allocate_page(&self, page_type: PageType, offset: usize) -> PageRef { + let page = self.allocate_page().unwrap(); + crate::btree_init_page(&page, page_type, offset, self.usable_space() as u16); + page + } + + /// The "usable size" of a database page is the page size specified by the 2-byte integer at offset 16 + /// in the header, minus the "reserved" space size recorded in the 1-byte integer at offset 20 in the header. + /// The usable size of a page might be an odd number. However, the usable size is not allowed to be less than 480. + /// In other words, if the page size is 512, then the reserved space size cannot exceed 32. + pub fn usable_space(&self) -> usize { + let db_header = self.db_header.borrow(); + (db_header.page_size - db_header.reserved_space as u16) as usize + } + pub fn begin_read_tx(&self) -> Result { self.wal.borrow_mut().begin_read_tx() } diff --git a/core/vdbe/mod.rs b/core/vdbe/mod.rs index f2c34c6e9..8b59879b4 100644 --- a/core/vdbe/mod.rs +++ b/core/vdbe/mod.rs @@ -2959,9 +2959,7 @@ impl Program { // TODO: implement temp databases todo!("temp databases not implemented yet"); } - let mut cursor = Box::new(BTreeCursor::new(pager.clone(), 0)); - - let root_page = cursor.btree_create(*flags); + let root_page = pager.btree_create(*flags); state.registers[*root] = OwnedValue::Integer(root_page as i64); state.pc += 1; }