use log::debug;
use super::{
BTreeBasePage, BTreePage, BTreePageID, PageCategory,
EMPTY_PAGE_ID,
};
use crate::{
btree::{page_cache::PageCache, tuple::Schema},
io::{SmallReader, SmallWriter, Vaporizable},
};
pub struct BTreeRootPointerPage {
base: BTreeBasePage,
root_pid: BTreePageID,
header_page_index: u32,
old_data: Vec<u8>,
}
impl BTreeRootPointerPage {
fn new(pid: &BTreePageID, bytes: &[u8]) -> Self {
let mut reader = SmallReader::new(&bytes);
let page_category = PageCategory::read_from(&mut reader);
if page_category != PageCategory::RootPointer {
panic!("invalid page category: {:?}", page_category);
}
let root_page_index = u32::read_from(&mut reader);
let root_page_category = PageCategory::read_from(&mut reader);
let header_page_index = u32::read_from(&mut reader);
let root_pid = BTreePageID {
category: root_page_category,
page_index: root_page_index,
table_id: pid.get_table_id(),
};
let mut instance = Self {
base: BTreeBasePage::new(pid),
root_pid,
header_page_index,
old_data: Vec::new(),
};
instance.set_before_image();
return instance;
}
pub fn new_empty_page(pid: &BTreePageID) -> Self {
let root_pid = BTreePageID {
category: PageCategory::Leaf,
page_index: 1,
table_id: pid.get_table_id(),
};
Self {
base: BTreeBasePage::new(pid),
root_pid,
header_page_index: EMPTY_PAGE_ID,
old_data: Vec::new(),
}
}
pub fn get_root_pid(&self) -> BTreePageID {
self.root_pid
}
pub fn set_root_pid(&mut self, pid: &BTreePageID) {
self.root_pid = *pid;
}
pub fn get_header_pid(&self) -> Option<BTreePageID> {
if self.header_page_index == EMPTY_PAGE_ID {
None
} else {
Some(BTreePageID::new(
PageCategory::Header,
self.get_pid().table_id,
self.header_page_index,
))
}
}
pub fn set_header_pid(&mut self, pid: &BTreePageID) {
self.header_page_index = pid.page_index;
}
}
impl BTreePage for BTreeRootPointerPage {
fn new(
pid: &BTreePageID,
bytes: &[u8],
_tuple_scheme: &Schema,
_key_field: usize,
) -> Self {
Self::new(pid, bytes)
}
fn get_pid(&self) -> BTreePageID {
self.base.get_pid()
}
fn get_parent_pid(&self) -> BTreePageID {
self.base.get_parent_pid()
}
fn set_parent_pid(&mut self, pid: &BTreePageID) {
self.base.set_parent_pid(pid)
}
fn get_page_data(&self) -> Vec<u8> {
let mut writer = SmallWriter::new();
writer.write(&self.get_pid().category);
writer.write(&self.root_pid.page_index);
writer.write(&self.root_pid.category);
writer.write(&self.header_page_index);
return writer.to_padded_bytes(PageCache::get_page_size());
}
fn set_before_image(&mut self) {
self.old_data = self.get_page_data();
}
fn get_before_image(&self) -> Vec<u8> {
if self.old_data.is_empty() {
panic!("no before image");
}
return self.old_data.clone();
}
fn peek(&self) {
debug!("BTreeRootPointerPage {{");
debug!(" pid: {:?}", self.get_pid());
debug!(" root_pid: {:?}", self.root_pid);
debug!(" header_page_index: {}", self.header_page_index);
debug!("}}");
}
}