use std::collections::{HashMap, VecDeque};
use std::time::Duration;
use super::config::MemoryOptimizationConfig;
pub struct HierarchicalMemoryManager {
pub config: MemoryOptimizationConfig,
pub memory_pools: HashMap<usize, MemoryPool>,
pub cache_hierarchy: CacheHierarchy,
pub memory_stats: MemoryStatistics,
}
impl HierarchicalMemoryManager {
#[must_use]
pub fn new(config: MemoryOptimizationConfig) -> Self {
Self {
config,
memory_pools: HashMap::new(),
cache_hierarchy: CacheHierarchy::new(),
memory_stats: MemoryStatistics::default(),
}
}
}
#[derive(Debug)]
pub struct MemoryPool {
pub id: String,
pub block_size: usize,
pub total_capacity: usize,
pub used_capacity: usize,
pub free_blocks: VecDeque<*mut u8>,
pub allocation_stats: AllocationStatistics,
}
#[derive(Debug)]
pub struct CacheHierarchy {
pub l1_cache: LRUCache<String, Vec<u8>>,
pub l2_cache: LRUCache<String, Vec<u8>>,
pub l3_cache: LRUCache<String, Vec<u8>>,
pub cache_stats: CacheStatistics,
}
impl CacheHierarchy {
#[must_use]
pub fn new() -> Self {
Self {
l1_cache: LRUCache::new(1024), l2_cache: LRUCache::new(1024 * 1024), l3_cache: LRUCache::new(10 * 1024 * 1024), cache_stats: CacheStatistics::default(),
}
}
}
impl Default for CacheHierarchy {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug)]
pub struct LRUCache<K, V> {
pub capacity: usize,
pub current_size: usize,
pub data: HashMap<K, V>,
pub access_order: VecDeque<K>,
}
impl<K: Clone + std::hash::Hash + Eq, V> LRUCache<K, V> {
#[must_use]
pub fn new(capacity: usize) -> Self {
Self {
capacity,
current_size: 0,
data: HashMap::new(),
access_order: VecDeque::new(),
}
}
pub fn get(&mut self, key: &K) -> Option<&V> {
if self.data.contains_key(key) {
self.access_order.retain(|k| k != key);
self.access_order.push_front(key.clone());
self.data.get(key)
} else {
None
}
}
pub fn insert(&mut self, key: K, value: V) {
if self.data.contains_key(&key) {
self.access_order.retain(|k| k != &key);
} else if self.current_size >= self.capacity {
if let Some(lru_key) = self.access_order.pop_back() {
self.data.remove(&lru_key);
self.current_size = self.current_size.saturating_sub(1);
}
}
self.data.insert(key.clone(), value);
self.access_order.push_front(key);
self.current_size += 1;
}
#[must_use]
pub fn contains(&self, key: &K) -> bool {
self.data.contains_key(key)
}
#[must_use]
pub fn len(&self) -> usize {
self.current_size
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.current_size == 0
}
}
#[derive(Debug, Clone)]
pub struct MemoryStatistics {
pub total_allocated: usize,
pub peak_usage: usize,
pub current_usage: usize,
pub allocation_count: u64,
pub deallocation_count: u64,
pub memory_efficiency: f64,
}
impl Default for MemoryStatistics {
fn default() -> Self {
Self {
total_allocated: 0,
peak_usage: 0,
current_usage: 0,
allocation_count: 0,
deallocation_count: 0,
memory_efficiency: 1.0,
}
}
}
impl MemoryStatistics {
pub fn record_allocation(&mut self, size: usize) {
self.total_allocated += size;
self.current_usage += size;
self.allocation_count += 1;
if self.current_usage > self.peak_usage {
self.peak_usage = self.current_usage;
}
self.update_efficiency();
}
pub fn record_deallocation(&mut self, size: usize) {
self.current_usage = self.current_usage.saturating_sub(size);
self.deallocation_count += 1;
self.update_efficiency();
}
fn update_efficiency(&mut self) {
if self.peak_usage > 0 {
self.memory_efficiency = self.current_usage as f64 / self.peak_usage as f64;
}
}
}
#[derive(Debug, Clone)]
pub struct AllocationStatistics {
pub total_allocations: u64,
pub failed_allocations: u64,
pub avg_allocation_size: f64,
pub utilization: f64,
}
impl Default for AllocationStatistics {
fn default() -> Self {
Self {
total_allocations: 0,
failed_allocations: 0,
avg_allocation_size: 0.0,
utilization: 0.0,
}
}
}
#[derive(Debug, Clone)]
pub struct CacheStatistics {
pub hits: u64,
pub misses: u64,
pub hit_rate: f64,
pub avg_access_time: Duration,
}
impl Default for CacheStatistics {
fn default() -> Self {
Self {
hits: 0,
misses: 0,
hit_rate: 0.0,
avg_access_time: Duration::from_nanos(0),
}
}
}
impl CacheStatistics {
pub fn record_hit(&mut self) {
self.hits += 1;
self.update_hit_rate();
}
pub fn record_miss(&mut self) {
self.misses += 1;
self.update_hit_rate();
}
fn update_hit_rate(&mut self) {
let total = self.hits + self.misses;
if total > 0 {
self.hit_rate = self.hits as f64 / total as f64;
}
}
}