use std::fs::File;
use memmap2::{Mmap, MmapOptions};
use crate::storage::page::PAGE_SIZE;
use crate::{Error, Result};
#[derive(Debug)]
pub(crate) struct MmapView {
map: Mmap,
}
impl MmapView {
pub(crate) fn open(file: &File) -> Result<Self> {
let file_len = file.metadata()?.len();
if file_len < PAGE_SIZE as u64 {
return Err(Error::Corrupted {
offset: 0,
reason: "page file too small for mmap",
});
}
let map = {
unsafe { MmapOptions::new().map(file)? }
};
Ok(Self { map })
}
pub(crate) fn read_page(&self, offset: usize) -> Result<[u8; PAGE_SIZE]> {
let end = offset.checked_add(PAGE_SIZE).ok_or(Error::Corrupted {
offset: offset as u64,
reason: "page offset overflow",
})?;
if end > self.map.len() {
return Err(Error::Corrupted {
offset: offset as u64,
reason: "mmap page read out of bounds",
});
}
let mut bytes = [0_u8; PAGE_SIZE];
bytes.copy_from_slice(&self.map[offset..end]);
Ok(bytes)
}
}