mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-31 23:14:21 +01:00
Merge 'core: Clean up B-Tree creation code' from Pekka Enberg
Move page allocation to pager so that we don't need to instantiate a cursor to create a B-Tree. Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com> Closes #1093
This commit is contained in:
@@ -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<CursorResult<()>> {
|
||||
// Get overflow info based on cell type
|
||||
let (first_overflow_page, n_overflow) = match cell {
|
||||
|
||||
@@ -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<LimboResult> {
|
||||
self.wal.borrow_mut().begin_read_tx()
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user