small_db/btree/page/
header_page.rs1use bit_vec::BitVec;
2use log::debug;
3
4use super::{BTreeBasePage, BTreePage, BTreePageID, PageCategory};
5use crate::{
6 btree::{page_cache::PageCache, tuple::Schema},
7 io::{SmallReader, SmallWriter, Vaporizable},
8};
9
10pub struct BTreeHeaderPage {
15 base: BTreeBasePage,
16
17 header: BitVec<u32>,
19
20 slot_count: usize,
21
22 old_data: Vec<u8>,
23}
24
25impl BTreeHeaderPage {
26 pub fn new(pid: &BTreePageID, bytes: &[u8]) -> BTreeHeaderPage {
27 let mut instance: Self;
28
29 if BTreeBasePage::is_empty_page(&bytes) {
30 instance = Self::new_empty_page(pid);
31 } else {
32 let mut reader = SmallReader::new(&bytes);
33
34 let page_category = PageCategory::read_from(&mut reader);
36 if page_category != PageCategory::Header {
37 panic!("invalid page category: {:?}", page_category);
38 }
39
40 let header = BitVec::read_from(&mut reader);
42
43 let slot_count = header.len();
44
45 instance = BTreeHeaderPage {
46 base: BTreeBasePage::new(pid),
47 header,
48 slot_count,
49 old_data: Vec::new(),
50 };
51 }
52
53 instance.set_before_image();
54 return instance;
55 }
56
57 pub fn new_empty_page(pid: &BTreePageID) -> BTreeHeaderPage {
58 let slot_count = 1000;
59
60 let mut header = BitVec::new();
61 header.grow(slot_count, false);
62
63 BTreeHeaderPage {
64 base: BTreeBasePage::new(pid),
65 header,
66 slot_count,
67 old_data: Vec::new(),
68 }
69 }
70
71 pub fn mark_slot_status(
73 &mut self,
74 slot_index: usize,
75 used: bool,
76 ) {
77 self.header.set(slot_index, used);
78 }
79
80 pub fn get_slots_count(&self) -> usize {
81 self.slot_count
82 }
83
84 pub fn get_empty_slot(&self) -> Option<u32> {
85 for i in 0..self.slot_count {
86 if !self.header[i] {
87 return Some(i as u32);
88 }
89 }
90 None
91 }
92}
93
94impl BTreePage for BTreeHeaderPage {
95 fn new(
96 pid: &BTreePageID,
97 bytes: &[u8],
98 _tuple_scheme: &Schema,
99 _key_field: usize,
100 ) -> Self {
101 Self::new(pid, bytes)
102 }
103
104 fn get_pid(&self) -> BTreePageID {
105 self.base.get_pid()
106 }
107
108 fn get_parent_pid(&self) -> BTreePageID {
109 self.base.get_parent_pid()
110 }
111
112 fn set_parent_pid(&mut self, pid: &BTreePageID) {
113 self.base.set_parent_pid(pid)
114 }
115
116 fn get_page_data(&self) -> Vec<u8> {
117 let mut writer = SmallWriter::new();
118
119 writer.write(&self.get_pid().category);
121
122 writer.write(&self.header);
124
125 return writer.to_padded_bytes(PageCache::get_page_size());
126 }
127
128 fn set_before_image(&mut self) {
129 self.old_data = self.get_page_data();
130 }
131
132 fn get_before_image(&self) -> Vec<u8> {
133 if self.old_data.is_empty() {
134 panic!("before image is not set");
135 }
136 return self.old_data.clone();
137 }
138
139 fn peek(&self) {
140 debug!("header page: {:?}", self.get_pid())
141 }
142}