quill_sql/recovery/wal/codec/
page.rs1use crate::buffer::PageId;
2use crate::error::{QuillSQLError, QuillSQLResult};
3use crate::recovery::Lsn;
4
5#[derive(Debug, Clone)]
6pub struct PageWritePayload {
7 pub page_id: PageId,
8 pub prev_page_lsn: Lsn,
9 pub page_image: Vec<u8>,
10}
11
12pub fn encode_page_write(body: &PageWritePayload) -> Vec<u8> {
13 let mut buf = Vec::with_capacity(4 + 8 + 4 + body.page_image.len());
16 buf.extend_from_slice(&body.page_id.to_le_bytes());
17 buf.extend_from_slice(&body.prev_page_lsn.to_le_bytes());
18 buf.extend_from_slice(&(body.page_image.len() as u32).to_le_bytes());
19 buf.extend_from_slice(&body.page_image);
20 buf
21}
22
23pub fn decode_page_write(bytes: &[u8]) -> QuillSQLResult<PageWritePayload> {
24 if bytes.len() < 4 + 8 + 4 {
25 return Err(QuillSQLError::Internal(
26 "PageWrite payload too short".to_string(),
27 ));
28 }
29 let page_id = u32::from_le_bytes(bytes[0..4].try_into().unwrap()) as PageId;
30 let prev_page_lsn = u64::from_le_bytes(bytes[4..12].try_into().unwrap()) as Lsn;
31 let image_len = u32::from_le_bytes(bytes[12..16].try_into().unwrap()) as usize;
32 if bytes.len() != 16 + image_len {
33 return Err(QuillSQLError::Internal(
34 "PageWrite payload length mismatch".to_string(),
35 ));
36 }
37 let page_image = bytes[16..].to_vec();
38 Ok(PageWritePayload {
39 page_id,
40 prev_page_lsn,
41 page_image,
42 })
43}