use crate::bplustree::NodeId;
use crate::layout::PAGE_SIZE;
use std::io::{self};
use zerocopy::{AsBytes, FromBytes, FromZeroes};
pub const PADDING_SIZE: usize = PAGE_SIZE - (std::mem::size_of::<Metadata>());
#[repr(C)]
#[derive(AsBytes, FromBytes, FromZeroes, Debug, Clone, Copy)]
pub struct Metadata {
pub root_node_id: NodeId,
pub id: u64,
pub txn_id: u64,
pub height: u64,
pub order: u64,
pub size: u64,
pub checksum: u64,
}
#[repr(C)]
#[derive(AsBytes, FromBytes, FromZeroes, Debug, Clone, Copy)]
pub struct MetadataPage {
pub data: Metadata,
_padding: [u8; PADDING_SIZE],
}
pub fn new_metadata_page(
root_id: u64,
id: u64,
txn_id: u64,
checksum: u64,
height: u64,
order: u64,
size: u64,
) -> MetadataPage {
MetadataPage {
data: Metadata {
root_node_id: root_id,
id,
txn_id,
height,
order,
size,
checksum,
},
_padding: [0; PADDING_SIZE],
}
}
pub fn new_metadata_page_with_object(meta: &Metadata) -> MetadataPage {
MetadataPage {
data: *meta,
_padding: [0; PADDING_SIZE],
}
}
impl MetadataPage {
pub fn from_bytes(buf: &[u8; PAGE_SIZE]) -> Result<&Self, std::io::Error> {
MetadataPage::ref_from(buf).ok_or(io::Error::new(
io::ErrorKind::InvalidData,
"Failed to decode MetadataPage",
))
}
}
pub fn calculate_checksum(meta: &MetadataPage) -> u64 {
use crc32fast::Hasher;
let bytes = meta.data.as_bytes();
let without_checksum = &bytes[..bytes.len() - (std::mem::size_of::<u64>())];
let mut hasher = Hasher::new();
hasher.update(without_checksum);
hasher.finalize() as u64
}