Skip to content

Commit

Permalink
Add tuple info codec
Browse files Browse the repository at this point in the history
  • Loading branch information
lewiszlw committed Feb 7, 2024
1 parent 2db2761 commit e93bff7
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 35 deletions.
2 changes: 1 addition & 1 deletion bustubx/src/storage/codec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod tuple;

pub use common::CommonCodec;
pub use scalar::ScalarValueCodec;
pub use table_page::TablePageCodec;
pub use table_page::{TablePageCodec, TablePageHeaderCodec, TablePageHeaderTupleInfoCodec};
pub use tuple::TupleCodec;

// data + consumed offset
Expand Down
66 changes: 43 additions & 23 deletions bustubx/src/storage/codec/table_page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,7 @@ impl TablePageHeaderCodec {
bytes.extend(CommonCodec::encode_u16(header.num_tuples));
bytes.extend(CommonCodec::encode_u16(header.num_deleted_tuples));
for tuple_info in header.tuple_infos.iter() {
bytes.extend(CommonCodec::encode_u16(tuple_info.offset));
bytes.extend(CommonCodec::encode_u16(tuple_info.size));
bytes.extend(CommonCodec::encode_u32(tuple_info.meta.insert_txn_id));
bytes.extend(CommonCodec::encode_u32(tuple_info.meta.delete_txn_id));
bytes.extend(CommonCodec::encode_bool(tuple_info.meta.is_deleted));
bytes.extend(TablePageHeaderTupleInfoCodec::encode(tuple_info));
}
bytes
}
Expand All @@ -62,25 +58,9 @@ impl TablePageHeaderCodec {

let mut tuple_infos = vec![];
for _ in 0..num_tuples {
let (tuple_offset, offset) = CommonCodec::decode_u16(left_bytes)?;
let (tuple_info, offset) = TablePageHeaderTupleInfoCodec::decode(left_bytes)?;
left_bytes = &left_bytes[offset..];
let (size, offset) = CommonCodec::decode_u16(left_bytes)?;
left_bytes = &left_bytes[offset..];
let (insert_txn_id, offset) = CommonCodec::decode_u32(left_bytes)?;
left_bytes = &left_bytes[offset..];
let (delete_txn_id, offset) = CommonCodec::decode_u32(left_bytes)?;
left_bytes = &left_bytes[offset..];
let (is_deleted, offset) = CommonCodec::decode_bool(left_bytes)?;
left_bytes = &left_bytes[offset..];
tuple_infos.push(TupleInfo {
offset: tuple_offset,
size,
meta: TupleMeta {
insert_txn_id,
delete_txn_id,
is_deleted,
},
});
tuple_infos.push(tuple_info);
}
Ok((
TablePageHeader {
Expand All @@ -94,6 +74,46 @@ impl TablePageHeaderCodec {
}
}

pub struct TablePageHeaderTupleInfoCodec;

impl TablePageHeaderTupleInfoCodec {
pub fn encode(tuple_info: &TupleInfo) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.extend(CommonCodec::encode_u16(tuple_info.offset));
bytes.extend(CommonCodec::encode_u16(tuple_info.size));
bytes.extend(CommonCodec::encode_u32(tuple_info.meta.insert_txn_id));
bytes.extend(CommonCodec::encode_u32(tuple_info.meta.delete_txn_id));
bytes.extend(CommonCodec::encode_bool(tuple_info.meta.is_deleted));
bytes
}

pub fn decode(bytes: &[u8]) -> BustubxResult<DecodedData<TupleInfo>> {
let mut left_bytes = bytes;
let (tuple_offset, offset) = CommonCodec::decode_u16(left_bytes)?;
left_bytes = &left_bytes[offset..];
let (size, offset) = CommonCodec::decode_u16(left_bytes)?;
left_bytes = &left_bytes[offset..];
let (insert_txn_id, offset) = CommonCodec::decode_u32(left_bytes)?;
left_bytes = &left_bytes[offset..];
let (delete_txn_id, offset) = CommonCodec::decode_u32(left_bytes)?;
left_bytes = &left_bytes[offset..];
let (is_deleted, offset) = CommonCodec::decode_bool(left_bytes)?;
left_bytes = &left_bytes[offset..];
Ok((
TupleInfo {
offset: tuple_offset,
size,
meta: TupleMeta {
insert_txn_id,
delete_txn_id,
is_deleted,
},
},
bytes.len() - left_bytes.len(),
))
}
}

#[cfg(test)]
mod tests {
use crate::buffer::INVALID_PAGE_ID;
Expand Down
29 changes: 18 additions & 11 deletions bustubx/src/storage/table_page.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
use crate::buffer::{PageId, BUSTUBX_PAGE_SIZE, INVALID_PAGE_ID};
use crate::buffer::{PageId, BUSTUBX_PAGE_SIZE};
use crate::catalog::SchemaRef;
use crate::common::rid::Rid;
use crate::storage::codec::{CommonCodec, TupleCodec};
use crate::storage::codec::{TablePageHeaderCodec, TablePageHeaderTupleInfoCodec, TupleCodec};

use super::tuple::{Tuple, TupleMeta};

pub const TABLE_PAGE_HEADER_SIZE: usize = 4 + 2 + 2;
pub const TABLE_PAGE_TUPLE_INFO_SIZE: usize = 2 + 2 + (4 + 4 + 4);
lazy_static::lazy_static! {
pub static ref EMPTY_TUPLE_INFO: TupleInfo = TupleInfo {
offset: 0,
size: 0,
meta: TupleMeta {
insert_txn_id: 0,
delete_txn_id: 0,
is_deleted: false,
}
};
}

/**
* Slotted page format:
Expand All @@ -21,7 +30,7 @@ pub const TABLE_PAGE_TUPLE_INFO_SIZE: usize = 2 + 2 + (4 + 4 + 4);
* | NextPageId (4)| NumTuples(2) | NumDeletedTuples(2) |
* ----------------------------------------------------------------------------
* ----------------------------------------------------------------
* | Tuple_1 offset+size (4) + TupleMeta(12) | Tuple_2 offset+size (4) + TupleMeta(12) | ... |
* | Tuple_1 offset+size + TupleMeta | Tuple_2 offset+size + TupleMeta | ... |
* ----------------------------------------------------------------
*
*/
Expand All @@ -42,7 +51,7 @@ impl TablePage {
next_page_id,
num_tuples: 0,
num_deleted_tuples: 0,
tuple_infos: Vec::with_capacity(BUSTUBX_PAGE_SIZE / TABLE_PAGE_TUPLE_INFO_SIZE),
tuple_infos: Vec::new(),
},
data: [0; BUSTUBX_PAGE_SIZE],
}
Expand All @@ -69,9 +78,9 @@ impl TablePage {

// Calculate the minimum valid tuple insertion offset, including the table page header size,
// the total size of each tuple info (existing tuple infos and newly added tuple info).
let min_tuple_offset = TABLE_PAGE_HEADER_SIZE as u16
+ (self.header.num_tuples as u16 + 1) * TABLE_PAGE_TUPLE_INFO_SIZE as u16;
if tuple_offset < min_tuple_offset {
let min_tuple_offset = TablePageHeaderCodec::encode(&self.header).len()
+ TablePageHeaderTupleInfoCodec::encode(&EMPTY_TUPLE_INFO).len();
if (tuple_offset as usize) < min_tuple_offset {
return None;
}

Expand Down Expand Up @@ -173,9 +182,7 @@ pub struct TupleInfo {

#[cfg(test)]
mod tests {
use crate::buffer::BUSTUBX_PAGE_SIZE;
use crate::catalog::{Column, DataType, Schema};
use crate::storage::codec::{TablePageCodec, TupleCodec};
use crate::storage::Tuple;
use std::sync::Arc;

Expand Down

0 comments on commit e93bff7

Please sign in to comment.