use crate::backend::native::{types::NativeBackendError, types::NativeResult};
pub struct MMapManager;
impl MMapManager {
pub fn get_mmap_statistics(mmap_size: u64, is_initialized: bool) -> MMapStatistics {
MMapStatistics {
is_initialized,
mmap_size,
is_mmap_active: is_initialized,
}
}
#[cfg(feature = "v2_experimental")]
pub fn is_mmap_available() -> bool {
true
}
#[cfg(not(feature = "v2_experimental"))]
pub fn is_mmap_available() -> bool {
false
}
#[cfg(feature = "v2_experimental")]
pub fn validate_read_bounds(
mmap_size: usize,
offset: u64,
buffer_len: usize,
) -> NativeResult<()> {
if offset as usize + buffer_len > mmap_size {
return Err(NativeBackendError::CorruptNodeRecord {
node_id: -1,
reason: format!(
"Read beyond mmap region: offset={}, len={}, mmap_size={}",
offset, buffer_len, mmap_size
),
});
}
Ok(())
}
#[cfg(feature = "v2_experimental")]
pub fn validate_write_bounds(
mmap_size: usize,
offset: u64,
data_len: usize,
) -> NativeResult<()> {
if offset as usize + data_len > mmap_size {
return Err(NativeBackendError::CorruptNodeRecord {
node_id: -1,
reason: format!(
"Write beyond mmap region: offset={}, len={}, mmap_size={}",
offset, data_len, mmap_size
),
});
}
Ok(())
}
pub fn check_recursion_depth(current_depth: u32, max_depth: u32) -> NativeResult<()> {
if current_depth > max_depth {
return Err(NativeBackendError::CorruptNodeRecord {
node_id: -1,
reason: format!("mmap recursion depth exceeded: {}", current_depth),
});
}
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct MMapStatistics {
pub is_initialized: bool,
pub mmap_size: u64,
pub is_mmap_active: bool,
}
impl MMapStatistics {
pub fn is_valid(&self) -> bool {
self.is_initialized && self.is_mmap_active && self.mmap_size > 0
}
pub fn get_size_bytes(&self) -> u64 {
self.mmap_size
}
pub fn get_size_kb(&self) -> f64 {
self.mmap_size as f64 / 1024.0
}
pub fn get_size_mb(&self) -> f64 {
self.mmap_size as f64 / (1024.0 * 1024.0)
}
}
#[derive(Debug, Clone)]
pub struct MMapConfig {
pub enable_mmap: bool,
pub growth_threshold_kb: u64,
pub max_recursion_depth: u32,
}
impl Default for MMapConfig {
fn default() -> Self {
Self {
enable_mmap: cfg!(feature = "v2_experimental"),
growth_threshold_kb: 1024, max_recursion_depth: 10,
}
}
}
impl MMapConfig {
pub fn new() -> Self {
Self::default()
}
pub fn disabled() -> Self {
Self {
enable_mmap: false,
..Default::default()
}
}
pub fn with_growth_threshold(mut self, threshold_kb: u64) -> Self {
self.growth_threshold_kb = threshold_kb;
self
}
pub fn with_max_recursion_depth(mut self, depth: u32) -> Self {
self.max_recursion_depth = depth;
self
}
pub fn should_enable_mmap(&self) -> bool {
self.enable_mmap && MMapManager::is_mmap_available()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_mmap_config() {
let config = MMapConfig::new();
let should_enable = cfg!(feature = "v2_experimental");
assert_eq!(
config.enable_mmap, should_enable,
"MMapConfig.enable_mmap should match v2_experimental feature flag state (enabled={})",
should_enable
);
assert_eq!(config.growth_threshold_kb, 1024);
assert_eq!(config.max_recursion_depth, 10);
}
#[test]
fn test_mmap_config_disabled() {
let config = MMapConfig::disabled();
assert!(!config.enable_mmap);
}
#[test]
fn test_mmap_config_builder() {
let config = MMapConfig::new()
.with_growth_threshold(2048)
.with_max_recursion_depth(20);
assert_eq!(config.growth_threshold_kb, 2048);
assert_eq!(config.max_recursion_depth, 20);
}
#[test]
fn test_mmap_statistics() {
let stats = MMapStatistics {
is_initialized: true,
mmap_size: 1024 * 1024, is_mmap_active: true,
};
assert!(stats.is_valid());
assert_eq!(stats.get_size_bytes(), 1024 * 1024);
assert_eq!(stats.get_size_kb(), 1024.0);
assert_eq!(stats.get_size_mb(), 1.0);
}
#[test]
fn test_mmap_statistics_uninitialized() {
let stats = MMapStatistics {
is_initialized: false,
mmap_size: 0,
is_mmap_active: false,
};
assert!(!stats.is_valid());
assert_eq!(stats.get_size_bytes(), 0);
assert_eq!(stats.get_size_kb(), 0.0);
assert_eq!(stats.get_size_mb(), 0.0);
}
#[cfg(feature = "v2_experimental")]
#[test]
fn test_validate_read_bounds_success() {
let result = MMapManager::validate_read_bounds(1024, 100, 100);
assert!(result.is_ok());
}
#[cfg(feature = "v2_experimental")]
#[test]
fn test_validate_read_bounds_failure() {
let result = MMapManager::validate_read_bounds(1024, 900, 200); assert!(result.is_err());
}
#[cfg(feature = "v2_experimental")]
#[test]
fn test_validate_write_bounds_success() {
let result = MMapManager::validate_write_bounds(1024, 100, 100);
assert!(result.is_ok());
}
#[cfg(feature = "v2_experimental")]
#[test]
fn test_validate_write_bounds_failure() {
let result = MMapManager::validate_write_bounds(1024, 900, 200); assert!(result.is_err());
}
#[test]
fn test_recursion_depth_check_success() {
let result = MMapManager::check_recursion_depth(5, 10);
assert!(result.is_ok());
}
#[test]
fn test_recursion_depth_check_failure() {
let result = MMapManager::check_recursion_depth(15, 10);
assert!(result.is_err());
}
#[test]
fn test_mmap_manager_availability() {
let is_available = MMapManager::is_mmap_available();
assert!(is_available == cfg!(feature = "v2_experimental"));
}
}