Skip to main content

sql_rs/storage/
page.rs

1use serde::{Deserialize, Serialize};
2
3pub const PAGE_SIZE: usize = 4096;
4pub type PageId = u32;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7pub enum PageType {
8    Header,
9    BTreeInternal,
10    BTreeLeaf,
11    Vector,
12    Overflow,
13}
14
15#[derive(Debug, Clone)]
16pub struct Page {
17    pub id: PageId,
18    pub page_type: PageType,
19    pub data: Vec<u8>,
20}
21
22impl Page {
23    pub fn new(id: PageId, page_type: PageType) -> Self {
24        Self {
25            id,
26            page_type,
27            data: vec![0; PAGE_SIZE],
28        }
29    }
30    
31    pub fn from_bytes(id: PageId, bytes: &[u8]) -> Self {
32        let page_type = match bytes[0] {
33            0 => PageType::Header,
34            1 => PageType::BTreeInternal,
35            2 => PageType::BTreeLeaf,
36            3 => PageType::Vector,
37            4 => PageType::Overflow,
38            _ => PageType::BTreeLeaf,
39        };
40        
41        let mut data = vec![0; PAGE_SIZE];
42        data[..bytes.len().min(PAGE_SIZE)].copy_from_slice(&bytes[..bytes.len().min(PAGE_SIZE)]);
43        
44        Self {
45            id,
46            page_type,
47            data,
48        }
49    }
50    
51    pub fn to_bytes(&self) -> &[u8] {
52        &self.data
53    }
54    
55    pub fn write_header(&mut self) {
56        self.data[0] = match self.page_type {
57            PageType::Header => 0,
58            PageType::BTreeInternal => 1,
59            PageType::BTreeLeaf => 2,
60            PageType::Vector => 3,
61            PageType::Overflow => 4,
62        };
63    }
64}
65
66#[derive(Debug)]
67pub struct PageCache {
68    pages: std::collections::HashMap<PageId, Page>,
69    max_size: usize,
70}
71
72impl PageCache {
73    pub fn new(max_size: usize) -> Self {
74        Self {
75            pages: std::collections::HashMap::new(),
76            max_size,
77        }
78    }
79    
80    pub fn get(&self, id: PageId) -> Option<&Page> {
81        self.pages.get(&id)
82    }
83    
84    pub fn insert(&mut self, page: Page) {
85        if self.pages.len() >= self.max_size {
86            if let Some(first_key) = self.pages.keys().next().copied() {
87                self.pages.remove(&first_key);
88            }
89        }
90        self.pages.insert(page.id, page);
91    }
92    
93    #[allow(dead_code)]
94    pub fn remove(&mut self, id: PageId) -> Option<Page> {
95        self.pages.remove(&id)
96    }
97    
98    pub fn clear(&mut self) {
99        self.pages.clear();
100    }
101}