storage_manager/backend/heap/
mod.rs

1use 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
8/// Initialize a new table file
9pub fn init_table(file: &mut File) -> io::Result<()> {
10    // Move cursor to the beginning of the file
11    file.seek(SeekFrom::Start(0))?;
12
13    // Allocate 8192 bytes
14    let mut zero_buf = vec![0u8; TABLE_HEADER_SIZE as usize];
15
16    //  Write "1" into the first 4 bytes (little-endian u32)
17    // This can represent the total number of pages, e.g. 1
18    zero_buf[0..4].copy_from_slice(&1u32.to_le_bytes());
19
20    // Write the full buffer (header) to the file
21    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}