feophantlib/engine/io/index_formats/
btree_first_page.rs1use crate::engine::io::{
2 format_traits::{Parseable, Serializable},
3 page_formats::{PageOffset, PageOffsetError},
4};
5use bytes::BufMut;
6use thiserror::Error;
7
8#[derive(Debug, PartialEq)]
10pub struct BTreeFirstPage {
11 pub root_offset: PageOffset,
12}
13
14impl Parseable<BTreeFirstPageError> for BTreeFirstPage {
15 type Output = Self;
16 fn parse(buffer: &mut impl bytes::Buf) -> Result<Self::Output, BTreeFirstPageError> {
17 let root_offset = PageOffset::parse(buffer)?;
18 Ok(BTreeFirstPage { root_offset })
19 }
20}
21
22impl Serializable for BTreeFirstPage {
23 fn serialize(&self, buffer: &mut impl BufMut) {
24 self.root_offset.serialize(buffer);
25 }
26}
27
28#[derive(Debug, Error)]
29pub enum BTreeFirstPageError {
30 #[error(transparent)]
31 PageOffsetError(#[from] PageOffsetError),
32}
33
34#[cfg(test)]
35mod tests {
36 use std::sync::Arc;
37
38 use bytes::BytesMut;
39 use tempfile::TempDir;
40 use uuid::Uuid;
41
42 use crate::{
43 constants::PAGE_SIZE,
44 engine::io::{
45 block_layer::file_manager2::FileManager2,
46 page_formats::{PageId, PageType},
47 },
48 };
49
50 use super::*;
51
52 #[test]
53 fn test_roundtrip() -> Result<(), Box<dyn std::error::Error>> {
54 let first = BTreeFirstPage {
55 root_offset: PageOffset(1),
56 };
57
58 let mut buffer = BytesMut::with_capacity(PAGE_SIZE as usize);
59 first.serialize(&mut buffer);
60
61 let result = BTreeFirstPage::parse(&mut buffer)?;
62
63 assert_eq!(first, result);
64
65 Ok(())
66 }
67
68 #[tokio::test]
69 async fn test_on_disk() -> Result<(), Box<dyn std::error::Error>> {
70 let tmp = TempDir::new()?;
71 let tmp_dir = tmp.path().as_os_str().to_os_string();
72
73 let fm = Arc::new(FileManager2::new(tmp_dir.clone())?);
74
75 let page_id = PageId {
76 resource_key: Uuid::new_v4(),
77 page_type: PageType::Data,
78 };
79
80 let (first_offset, first_guard) = fm.get_next_offset(&page_id).await?;
81 assert_eq!(first_offset, PageOffset(0));
82
83 let (root_offset, _root_guard) = fm.get_next_offset(&page_id).await?;
84 assert_ne!(root_offset, PageOffset(0));
85
86 let btfp = BTreeFirstPage { root_offset };
87 fm.update_page(first_guard, btfp.serialize_and_pad())
88 .await?;
89
90 let (mut new_first_page, _new_first_guard) = fm.get_page(&page_id, &PageOffset(0)).await?;
92 let btfp2 = BTreeFirstPage::parse(&mut new_first_page)?;
93 assert_ne!(btfp2.root_offset, PageOffset(0));
94
95 drop(fm);
97 let fm2 = Arc::new(FileManager2::new(tmp_dir)?);
98
99 let (mut new_first_page2, _new_first_guard2) =
100 fm2.get_page(&page_id, &PageOffset(0)).await?;
101 let btfp2 = BTreeFirstPage::parse(&mut new_first_page2)?;
102 assert_ne!(btfp2.root_offset, PageOffset(0));
103
104 Ok(())
105 }
106}