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}