use std::os::fd::AsRawFd;
use std::path::PathBuf;
use std::sync::atomic::{AtomicU64, Ordering};
pub mod observability {
use super::{AtomicU64, Ordering};
pub(super) static MADV_SEQUENTIAL_COUNT: AtomicU64 = AtomicU64::new(0);
pub(super) static FADV_DONTNEED_COUNT: AtomicU64 = AtomicU64::new(0);
pub fn madv_sequential_count() -> u64 {
MADV_SEQUENTIAL_COUNT.load(Ordering::Relaxed)
}
pub fn fadv_dontneed_count() -> u64 {
FADV_DONTNEED_COUNT.load(Ordering::Relaxed)
}
}
pub(super) enum BackingStore {
Mmap {
mmap: memmap2::Mmap,
file: std::fs::File,
},
Decrypted(Vec<u8>),
}
impl BackingStore {
pub(super) fn bytes(&self) -> &[u8] {
match self {
BackingStore::Mmap { mmap, .. } => mmap,
BackingStore::Decrypted(v) => v,
}
}
}
pub struct ColumnMmap {
pub(super) backing: BackingStore,
pub(super) path: PathBuf,
}
impl ColumnMmap {
pub fn bytes(&self) -> &[u8] {
self.backing.bytes()
}
pub fn len(&self) -> usize {
self.backing.bytes().len()
}
pub fn is_empty(&self) -> bool {
self.backing.bytes().is_empty()
}
pub fn is_mmap(&self) -> bool {
matches!(self.backing, BackingStore::Mmap { .. })
}
pub fn is_decrypted_owned(&self) -> bool {
matches!(self.backing, BackingStore::Decrypted(_))
}
}
impl std::ops::Deref for ColumnMmap {
type Target = [u8];
fn deref(&self) -> &Self::Target {
self.backing.bytes()
}
}
impl Drop for ColumnMmap {
fn drop(&mut self) {
let BackingStore::Mmap { ref mmap, ref file } = self.backing else {
return;
};
let len = mmap.len();
if len == 0 {
return;
}
let rc = unsafe {
libc::posix_fadvise(
file.as_raw_fd(),
0,
len as libc::off_t,
libc::POSIX_FADV_DONTNEED,
)
};
if rc == 0 {
observability::FADV_DONTNEED_COUNT.fetch_add(1, Ordering::Relaxed);
} else {
tracing::warn!(
path = %self.path.display(),
errno = rc,
"posix_fadvise(DONTNEED) failed on columnar mmap drop",
);
}
}
}
pub(super) fn advise_sequential(mmap: &memmap2::Mmap, col_path: &std::path::Path) {
if mmap.is_empty() {
return;
}
let rc = unsafe {
libc::madvise(
mmap.as_ptr() as *mut libc::c_void,
mmap.len(),
libc::MADV_SEQUENTIAL,
)
};
if rc == 0 {
observability::MADV_SEQUENTIAL_COUNT.fetch_add(1, Ordering::Relaxed);
} else {
tracing::warn!(
path = %col_path.display(),
errno = std::io::Error::last_os_error().raw_os_error().unwrap_or(0),
"madvise(MADV_SEQUENTIAL) failed on column mmap",
);
}
}