use memmap2::Mmap;
use std::fs::File;
pub struct MmapCache {
mmap: Mmap,
}
impl MmapCache {
pub fn new(file: &File) -> std::io::Result<Self> {
let mmap = unsafe { Mmap::map(file)? };
Ok(Self { mmap })
}
pub fn len(&self) -> usize {
self.mmap.len()
}
pub fn is_empty(&self) -> bool {
self.mmap.is_empty()
}
pub fn read_u64(&self, offset: u64) -> Option<u64> {
let off = usize::try_from(offset).ok()?;
let end = off.checked_add(8)?;
if end > self.mmap.len() {
return None;
}
let bytes: [u8; 8] = self.mmap[off..end].try_into().ok()?;
Some(u64::from_le_bytes(bytes))
}
pub fn read_u32(&self, offset: u64) -> Option<u32> {
let off = usize::try_from(offset).ok()?;
let end = off.checked_add(4)?;
if end > self.mmap.len() {
return None;
}
let bytes: [u8; 4] = self.mmap[off..end].try_into().ok()?;
Some(u32::from_le_bytes(bytes))
}
pub fn read_u8(&self, offset: u64) -> Option<u8> {
let off = usize::try_from(offset).ok()?;
self.mmap.get(off).copied()
}
pub fn read_bytes(&self, offset: u64, len: usize) -> Option<&[u8]> {
let off = usize::try_from(offset).ok()?;
let end = off.checked_add(len)?;
if end > self.mmap.len() {
return None;
}
Some(&self.mmap[off..end])
}
}