Skip to content

Commit

Permalink
update row page
Browse files Browse the repository at this point in the history
  • Loading branch information
jiangzhe authored and jiangzhe committed Dec 8, 2024
1 parent d0184c6 commit 9cf6df6
Show file tree
Hide file tree
Showing 5 changed files with 730 additions and 35 deletions.
1 change: 1 addition & 0 deletions doradb-catalog/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ pub struct TableSpec {
pub schema_name: SemiStr,
pub table_name: SemiStr,
pub columns: Vec<ColumnSpec>,
// todo: index and constraint
}

impl TableSpec {
Expand Down
22 changes: 14 additions & 8 deletions doradb-storage/src/index/block_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::buffer::guard::{PageExclusiveGuard, PageGuard, PageSharedGuard};
use crate::error::{Error, Result, Validation, Validation::{Valid, Invalid}};
use crate::latch::LatchFallbackMode;
use crate::row::{RowID, RowPage};
use crate::row::layout::ColLayout;
use parking_lot::Mutex;
use std::mem;

Expand Down Expand Up @@ -387,7 +388,7 @@ impl<'a> BlockIndex<'a> {
/// Get row page for insertion.
/// Caller should cache insert page id to avoid invoking this method frequently.
#[inline]
pub fn get_insert_page(&self, count: usize) -> Result<PageExclusiveGuard<'a, RowPage>> {
pub fn get_insert_page(&self, count: usize, cols: &[ColLayout]) -> Result<PageExclusiveGuard<'a, RowPage>> {
match self.get_insert_page_from_free_list() {
Valid(Ok(free_page)) => return Ok(free_page),
Valid(_) | Invalid => {
Expand All @@ -402,8 +403,9 @@ impl<'a> BlockIndex<'a> {
Invalid => (),
Valid(Ok((start_row_id, end_row_id))) => {
// initialize row page.
debug_assert!(end_row_id == start_row_id + count as u64);
let p = new_page.page_mut();
p.init(start_row_id, end_row_id);
p.init(start_row_id, count as u16, cols);
return Ok(new_page);
}
Valid(Err(e)) => {
Expand Down Expand Up @@ -931,12 +933,13 @@ mod tests {
fn test_block_index_free_list() {
let buf_pool = FixedBufferPool::with_capacity_static(64 * 1024 * 1024).unwrap();
{
let cols = vec![ColLayout::Byte8, ColLayout::Byte8];
let blk_idx = BlockIndex::new(buf_pool).unwrap();
let p1 = blk_idx.get_insert_page(100).unwrap();
let p1 = blk_idx.get_insert_page(100, &cols).unwrap();
let pid1 = p1.page_id();
blk_idx.free_exclusive_insert_page(p1);
assert!(blk_idx.insert_free_list.lock().len() == 1);
let p2 = blk_idx.get_insert_page(100).unwrap();
let p2 = blk_idx.get_insert_page(100, &cols).unwrap();
assert!(pid1 == p2.page_id());
assert!(blk_idx.insert_free_list.lock().is_empty());
}
Expand All @@ -949,12 +952,13 @@ mod tests {
fn test_block_index_insert_row_page() {
let buf_pool = FixedBufferPool::with_capacity_static(64 * 1024 * 1024).unwrap();
{
let cols = vec![ColLayout::Byte8, ColLayout::Byte8];
let blk_idx = BlockIndex::new(buf_pool).unwrap();
let p1 = blk_idx.get_insert_page(100).unwrap();
let p1 = blk_idx.get_insert_page(100, &cols).unwrap();
let pid1 = p1.page_id();
blk_idx.free_exclusive_insert_page(p1);
assert!(blk_idx.insert_free_list.lock().len() == 1);
let p2 = blk_idx.get_insert_page(100).unwrap();
let p2 = blk_idx.get_insert_page(100, &cols).unwrap();
assert!(pid1 == p2.page_id());
assert!(blk_idx.insert_free_list.lock().is_empty());
}
Expand All @@ -969,9 +973,10 @@ mod tests {
// allocate 1GB buffer pool is enough: 10240 pages ~= 640MB
let buf_pool = FixedBufferPool::with_capacity_static(1024 * 1024 * 1024).unwrap();
{
let cols = vec![ColLayout::Byte8, ColLayout::Byte8];
let blk_idx = BlockIndex::new(buf_pool).unwrap();
for _ in 0..row_pages {
let _ = blk_idx.get_insert_page(100).unwrap();
let _ = blk_idx.get_insert_page(100, &cols).unwrap();
}
let mut count = 0usize;
for res in blk_idx.cursor_shared(0).unwrap() {
Expand Down Expand Up @@ -1002,9 +1007,10 @@ mod tests {
let rows_per_page = 100usize;
let buf_pool = FixedBufferPool::with_capacity_static(1024 * 1024 * 1024).unwrap();
{
let cols = vec![ColLayout::Byte8, ColLayout::Byte8];
let blk_idx = BlockIndex::new(buf_pool).unwrap();
for _ in 0..row_pages {
let _ = blk_idx.get_insert_page(rows_per_page).unwrap();
let _ = blk_idx.get_insert_page(rows_per_page, &cols).unwrap();
}
{
let res = blk_idx.buf_pool.get_page::<BlockNode>(blk_idx.root, LatchFallbackMode::Spin).unwrap();
Expand Down
28 changes: 28 additions & 0 deletions doradb-storage/src/row/layout.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/// ColLayout defines the memory layout of columns
/// stored in row page.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum ColLayout {
Byte1, // i8, u8, bool, char(1) with ascii/latin charset
Byte2, // i16, u16, decimal(1-2)
Byte4, // i32, u32, f32, decimal(3-8)
Byte8, // i64, u64, f64, decimal(9-18)
Byte16, // decimal(19-38)
VarByte, // bytes, string, no more than 60k.
}

impl ColLayout {
#[inline]
pub const fn fix_len(&self) -> usize {
match self {
ColLayout::Byte1 => 1,
ColLayout::Byte2 => 2,
ColLayout::Byte4 => 4,
ColLayout::Byte8 => 8,
ColLayout::Byte16 => 16,
// 2-byte len, 2-byte offset, 12-byte prefix
// or inline version, 2-byte len, at most 14 inline bytes
ColLayout::VarByte => 16,
}
}
}
Loading

0 comments on commit 9cf6df6

Please sign in to comment.