storage_manager/backend/heap/
mod.rs1use std::fs::File;
2use std::io::{self, Seek, SeekFrom, Write};
3
4use crate::disk::{create_page, read_page, write_page};
5use crate::page::{ITEM_ID_SIZE, Page, page_free_space};
6use crate::table::{TABLE_HEADER_SIZE, page_count};
7
8pub fn init_table(file: &mut File) -> io::Result<()> {
10 file.seek(SeekFrom::Start(0))?;
12
13 let mut zero_buf = vec![0u8; TABLE_HEADER_SIZE as usize];
15
16 zero_buf[0..4].copy_from_slice(&1u32.to_le_bytes());
19
20 file.write_all(&zero_buf)?;
22 file.flush()?;
23 file.sync_all()?;
24
25 create_page(file)?;
26
27 Ok(())
28}
29
30pub fn insert_tuple(file: &mut File, data: &[u8]) -> io::Result<()> {
31 let mut total_pages = page_count(file)?;
32 let mut last_page_num = total_pages - 1;
33
34 let mut page = Page::new();
35 read_page(file, &mut page, last_page_num)?;
36
37 let free_space = page_free_space(&page)?;
38 let required = data.len() as u32 + ITEM_ID_SIZE;
39
40 if required > free_space {
41 create_page(file)?;
42 total_pages += 1;
43 last_page_num = total_pages - 1;
44 read_page(file, &mut page, last_page_num)?;
45 }
46
47 let mut lower = u32::from_le_bytes(page.data[0..4].try_into().unwrap());
48 let mut upper = u32::from_le_bytes(page.data[4..8].try_into().unwrap());
49
50 let start = upper - data.len() as u32;
51 page.data[start as usize..upper as usize].copy_from_slice(data);
52
53 upper = start;
54 page.data[4..8].copy_from_slice(&upper.to_le_bytes());
55
56 page.data[lower as usize..lower as usize + 4].copy_from_slice(&start.to_le_bytes());
57 page.data[lower as usize + 4..lower as usize + 8]
58 .copy_from_slice(&(data.len() as u32).to_le_bytes());
59
60 lower += ITEM_ID_SIZE;
61 page.data[0..4].copy_from_slice(&lower.to_le_bytes());
62
63 write_page(file, &mut page, last_page_num)?;
64 Ok(())
65}