pub trait MemoryConfig: Clone {
const TOTAL_CRDT_MEMORY: usize;
const MAX_REGISTERS: usize;
const MAX_COUNTERS: usize;
const MAX_SETS: usize;
const MAX_MAPS: usize;
const MAX_SET_ELEMENTS: usize;
const MAX_MAP_ENTRIES: usize;
const MAX_HISTORY_SIZE: usize;
const MAX_NODES: usize;
const CLOCK_MEMORY_BUDGET: usize;
const ERROR_BUFFER_SIZE: usize;
const MEMORY_ALIGNMENT: usize;
const CACHE_LINE_SIZE: usize;
fn validate() -> Result<(), &'static str> {
if Self::MEMORY_ALIGNMENT == 0
|| (Self::MEMORY_ALIGNMENT & (Self::MEMORY_ALIGNMENT - 1)) != 0
{
return Err("MEMORY_ALIGNMENT must be a power of 2");
}
if Self::MAX_NODES > 255 {
return Err("MAX_NODES cannot exceed 255 for efficient node ID representation");
}
if Self::MAX_SET_ELEMENTS > 64 {
return Err("MAX_SET_ELEMENTS cannot exceed 64 for efficient bitmap representation");
}
let estimated_usage = Self::estimate_memory_usage();
if estimated_usage > Self::TOTAL_CRDT_MEMORY {
return Err("Estimated memory usage exceeds configured budget");
}
Ok(())
}
fn estimate_memory_usage() -> usize {
let clock_memory = Self::CLOCK_MEMORY_BUDGET;
let error_memory = Self::ERROR_BUFFER_SIZE;
let register_memory = Self::MAX_REGISTERS * 16; let counter_memory = Self::MAX_COUNTERS * 8; let set_memory = Self::MAX_SETS * (8 + Self::MAX_SET_ELEMENTS.div_ceil(8)); let map_memory = Self::MAX_MAPS * Self::MAX_MAP_ENTRIES * 12;
clock_memory + error_memory + register_memory + counter_memory + set_memory + map_memory
}
}
pub type NodeId = u8;
#[derive(Debug, Clone, Copy)]
pub struct DefaultConfig;
impl Default for DefaultConfig {
fn default() -> Self {
Self
}
}
impl MemoryConfig for DefaultConfig {
const TOTAL_CRDT_MEMORY: usize = 32 * 1024; const MAX_REGISTERS: usize = 50;
const MAX_COUNTERS: usize = 25;
const MAX_SETS: usize = 15;
const MAX_MAPS: usize = 10;
const MAX_SET_ELEMENTS: usize = 32;
const MAX_MAP_ENTRIES: usize = 32;
const MAX_HISTORY_SIZE: usize = 4;
const MAX_NODES: usize = 16;
const CLOCK_MEMORY_BUDGET: usize = 512;
const ERROR_BUFFER_SIZE: usize = 256;
const MEMORY_ALIGNMENT: usize = 4;
const CACHE_LINE_SIZE: usize = 32;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config_validation() {
assert!(DefaultConfig::validate().is_ok());
}
#[test]
fn test_memory_estimation() {
let estimated = DefaultConfig::estimate_memory_usage();
assert!(estimated <= DefaultConfig::TOTAL_CRDT_MEMORY);
assert!(estimated > 0);
}
}