use crate::Result;
use crate::errors::PagedbError;
pub const FIRST_ALLOCATABLE_PAGE_ID: u64 = 4;
#[must_use]
pub const fn is_reserved(page_id: u64) -> bool {
page_id < FIRST_ALLOCATABLE_PAGE_ID
}
pub fn page_offset(page_id: u64, page_size: usize, operation: &'static str) -> Result<u64> {
let page_size =
u64::try_from(page_size).map_err(|_| PagedbError::arithmetic_overflow(operation))?;
page_id
.checked_mul(page_size)
.ok_or_else(|| PagedbError::arithmetic_overflow(operation))
}
#[cfg(test)]
mod tests {
use super::*;
const PAGE: usize = 4096;
#[test]
fn offset_scales_by_page_size() {
assert_eq!(page_offset(0, PAGE, "test").unwrap(), 0);
assert_eq!(page_offset(4, PAGE, "test").unwrap(), 16_384);
}
#[test]
fn offset_rejects_a_page_id_that_overflows_the_address_space() {
let first_unrepresentable = (u64::MAX / PAGE as u64) + 1;
assert!(matches!(
page_offset(first_unrepresentable, PAGE, "test"),
Err(PagedbError::ArithmeticOverflow { .. })
));
assert!(page_offset(first_unrepresentable - 1, PAGE, "test").is_ok());
}
}