use std::path::Path;
use memmap2::Mmap;
use crate::error::{Error, Result};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum Advice {
Random,
Sequential,
WillNeed,
}
#[cfg(unix)]
pub(crate) fn advise_mmap(mmap: &Mmap, advice: Advice) -> std::io::Result<()> {
mmap.advise(match advice {
Advice::Random => memmap2::Advice::Random,
Advice::Sequential => memmap2::Advice::Sequential,
Advice::WillNeed => memmap2::Advice::WillNeed,
})
}
#[cfg(not(unix))]
pub(crate) fn advise_mmap(_mmap: &Mmap, _advice: Advice) -> std::io::Result<()> {
Ok(())
}
pub(crate) fn preload_mmap(mmap: &Mmap) -> usize {
let _ = advise_mmap(mmap, Advice::Sequential);
let _ = advise_mmap(mmap, Advice::WillNeed);
let len = mmap.len();
let mut acc = 0u64;
let mut i = 0usize;
while i < len {
acc = acc.wrapping_add(mmap[i] as u64);
i += 4096;
}
std::hint::black_box(acc);
let _ = advise_mmap(mmap, Advice::Random);
len
}
#[cfg(unix)]
pub(crate) fn lock_mmap(mmap: &Mmap) -> std::io::Result<()> {
mmap.lock()
}
#[cfg(not(unix))]
pub(crate) fn lock_mmap(_mmap: &Mmap) -> std::io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::Unsupported,
"mlock is not available on this platform",
))
}
#[cfg(unix)]
pub(crate) fn unlock_mmap(mmap: &Mmap) -> std::io::Result<()> {
mmap.unlock()
}
#[cfg(not(unix))]
pub(crate) fn unlock_mmap(_mmap: &Mmap) -> std::io::Result<()> {
Err(std::io::Error::new(
std::io::ErrorKind::Unsupported,
"mlock is not available on this platform",
))
}
pub(crate) fn mmap_file(path: &Path) -> Result<Mmap> {
let f = std::fs::File::open(path).map_err(|e| Error::io(path, e))?;
#[allow(unsafe_code)]
let mmap = unsafe { Mmap::map(&f) }.map_err(|e| Error::io(path, e))?;
Ok(mmap)
}