small_db/btree/page/
root_pointer_page.rs1use log::debug;
2
3use super::{
4 BTreeBasePage, BTreePage, BTreePageID, PageCategory,
5 EMPTY_PAGE_ID,
6};
7use crate::{
8 btree::{page_cache::PageCache, tuple::Schema},
9 io::{SmallReader, SmallWriter, Vaporizable},
10};
11
12pub struct BTreeRootPointerPage {
19 base: BTreeBasePage,
20
21 root_pid: BTreePageID,
27
28 header_page_index: u32,
30
31 old_data: Vec<u8>,
35}
36
37impl BTreeRootPointerPage {
38 fn new(pid: &BTreePageID, bytes: &[u8]) -> Self {
39 let mut reader = SmallReader::new(&bytes);
40
41 let page_category = PageCategory::read_from(&mut reader);
43 if page_category != PageCategory::RootPointer {
44 panic!("invalid page category: {:?}", page_category);
45 }
46
47 let root_page_index = u32::read_from(&mut reader);
49
50 let root_page_category = PageCategory::read_from(&mut reader);
52
53 let header_page_index = u32::read_from(&mut reader);
55
56 let root_pid = BTreePageID {
57 category: root_page_category,
58 page_index: root_page_index,
59 table_id: pid.get_table_id(),
60 };
61
62 let mut instance = Self {
63 base: BTreeBasePage::new(pid),
64 root_pid,
65 header_page_index,
66 old_data: Vec::new(),
67 };
68
69 instance.set_before_image();
70 return instance;
71 }
72
73 pub fn new_empty_page(pid: &BTreePageID) -> Self {
74 let root_pid = BTreePageID {
76 category: PageCategory::Leaf,
77 page_index: 1,
78 table_id: pid.get_table_id(),
79 };
80
81 Self {
82 base: BTreeBasePage::new(pid),
83 root_pid,
84 header_page_index: EMPTY_PAGE_ID,
85 old_data: Vec::new(),
86 }
87 }
88
89 pub fn get_root_pid(&self) -> BTreePageID {
90 self.root_pid
91 }
92
93 pub fn set_root_pid(&mut self, pid: &BTreePageID) {
94 self.root_pid = *pid;
95 }
96
97 pub fn get_header_pid(&self) -> Option<BTreePageID> {
99 if self.header_page_index == EMPTY_PAGE_ID {
100 None
101 } else {
102 Some(BTreePageID::new(
103 PageCategory::Header,
104 self.get_pid().table_id,
105 self.header_page_index,
106 ))
107 }
108 }
109
110 pub fn set_header_pid(&mut self, pid: &BTreePageID) {
112 self.header_page_index = pid.page_index;
113 }
114}
115
116impl BTreePage for BTreeRootPointerPage {
117 fn new(
118 pid: &BTreePageID,
119 bytes: &[u8],
120 _tuple_scheme: &Schema,
121 _key_field: usize,
122 ) -> Self {
123 Self::new(pid, bytes)
124 }
125
126 fn get_pid(&self) -> BTreePageID {
127 self.base.get_pid()
128 }
129
130 fn get_parent_pid(&self) -> BTreePageID {
131 self.base.get_parent_pid()
132 }
133
134 fn set_parent_pid(&mut self, pid: &BTreePageID) {
135 self.base.set_parent_pid(pid)
136 }
137
138 fn get_page_data(&self) -> Vec<u8> {
139 let mut writer = SmallWriter::new();
140
141 writer.write(&self.get_pid().category);
143
144 writer.write(&self.root_pid.page_index);
146
147 writer.write(&self.root_pid.category);
149
150 writer.write(&self.header_page_index);
152
153 return writer.to_padded_bytes(PageCache::get_page_size());
154 }
155
156 fn set_before_image(&mut self) {
157 self.old_data = self.get_page_data();
158 }
159
160 fn get_before_image(&self) -> Vec<u8> {
161 if self.old_data.is_empty() {
162 panic!("no before image");
163 }
164 return self.old_data.clone();
165 }
166
167 fn peek(&self) {
168 debug!("BTreeRootPointerPage {{");
169 debug!(" pid: {:?}", self.get_pid());
170 debug!(" root_pid: {:?}", self.root_pid);
171 debug!(" header_page_index: {}", self.header_page_index);
172 debug!("}}");
173 }
174}