use super::{
config::{CleanupStatus, FragmentationType, PressureTrend, UtilizationChangeReason},
pool_management::ScirS2PoolInfo,
statistics::{AllocationUsageStats, MemoryStateSnapshot, PerformanceSnapshot},
};
use crate::memory_profiler::allocation::PressureLevel;
use std::collections::HashMap;
use std::time::{Duration, Instant};
#[derive(Debug, Clone)]
pub enum ScirS2Event {
Allocation {
ptr: *mut u8,
size: usize,
allocator: String,
allocation_context: AllocationEventContext,
},
Deallocation {
ptr: *mut u8,
allocator: String,
deallocation_context: DeallocationEventContext,
},
PoolCreated {
pool_id: String,
capacity: usize,
pool_type: String,
creation_context: PoolCreationContext,
},
PoolDestroyed {
pool_id: String,
destruction_context: PoolDestructionContext,
},
MemoryPressure {
level: PressureLevel,
available_memory: usize,
pressure_context: MemoryPressureContext,
},
OptimizationSuggestion {
suggestion_type: String,
impact_estimate: f64,
suggested_action: String,
optimization_context: OptimizationContext,
},
PoolUtilizationChange {
pool_id: String,
old_utilization: f64,
new_utilization: f64,
change_reason: UtilizationChangeReason,
},
PerformanceDegradation {
allocator: String,
metric: String,
degradation_amount: f64,
threshold_exceeded: bool,
},
FragmentationEvent {
allocator: String,
fragmentation_level: f64,
fragmentation_type: FragmentationType,
mitigation_suggested: bool,
},
}
#[derive(Debug, Clone)]
pub struct AllocationEventContext {
pub thread_id: u64,
pub reason: String,
pub performance_snapshot: PerformanceSnapshot,
pub memory_snapshot: MemoryStateSnapshot,
}
#[derive(Debug, Clone)]
pub struct DeallocationEventContext {
pub thread_id: u64,
pub allocation_lifetime: Duration,
pub usage_stats: AllocationUsageStats,
}
#[derive(Debug, Clone)]
pub struct PoolCreationContext {
pub creation_reason: String,
pub initial_config: HashMap<String, String>,
pub expected_usage: String,
}
#[derive(Debug, Clone)]
pub struct PoolDestructionContext {
pub destruction_reason: String,
pub final_stats: ScirS2PoolInfo,
pub cleanup_status: CleanupStatus,
}
#[derive(Debug, Clone)]
pub struct MemoryPressureContext {
pub system_memory_usage: usize,
pub scirs2_memory_usage: usize,
pub active_allocators: Vec<String>,
pub pressure_trend: PressureTrend,
}
#[derive(Debug, Clone)]
pub struct OptimizationContext {
pub target_component: String,
pub performance_baseline: PerformanceSnapshot,
pub confidence: f64,
pub prerequisites: Vec<String>,
}
pub struct ScirS2EventProcessor {
callbacks: Vec<Box<dyn Fn(&ScirS2Event) + Send + Sync>>,
event_stats: EventStatistics,
filters: Vec<EventFilter>,
event_buffer: Vec<ScirS2Event>,
buffer_limit: usize,
}
#[derive(Debug, Clone)]
pub struct EventStatistics {
pub total_events: u64,
pub events_by_type: HashMap<String, u64>,
pub processing_times: Vec<Duration>,
pub avg_processing_time: Duration,
pub event_rate: f64,
pub last_processing_time: Instant,
}
#[derive(Debug, Clone)]
pub struct EventFilter {
pub name: String,
pub include_types: Vec<String>,
pub exclude_types: Vec<String>,
pub min_severity: EventSeverity,
pub custom_filter: Option<String>, }
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum EventSeverity {
Debug,
Info,
Warning,
Error,
Critical,
}
impl ScirS2EventProcessor {
pub fn new() -> Self {
Self {
callbacks: Vec::new(),
event_stats: EventStatistics::new(),
filters: Vec::new(),
event_buffer: Vec::new(),
buffer_limit: 1000,
}
}
pub fn add_callback<F>(&mut self, callback: F)
where
F: Fn(&ScirS2Event) + Send + Sync + 'static,
{
self.callbacks.push(Box::new(callback));
}
pub fn add_filter(&mut self, filter: EventFilter) {
self.filters.push(filter);
}
pub fn process_event(&mut self, event: ScirS2Event) {
let start_time = Instant::now();
if !self.event_passes_filters(&event) {
return;
}
self.event_stats.record_event(&event, start_time);
self.event_buffer.push(event.clone());
if self.event_buffer.len() >= self.buffer_limit {
self.process_buffer();
}
for callback in &self.callbacks {
callback(&event);
}
let processing_time = start_time.elapsed();
self.event_stats.processing_times.push(processing_time);
if self.event_stats.processing_times.len() > 1000 {
self.event_stats.processing_times.remove(0);
}
self.event_stats.update_avg_processing_time();
}
pub fn process_buffer(&mut self) {
if self.event_buffer.is_empty() {
return;
}
let allocation_events: Vec<_> = self
.event_buffer
.iter()
.filter_map(|e| match e {
ScirS2Event::Allocation { .. } => Some(e),
_ => None,
})
.collect();
let deallocation_events: Vec<_> = self
.event_buffer
.iter()
.filter_map(|e| match e {
ScirS2Event::Deallocation { .. } => Some(e),
_ => None,
})
.collect();
self.analyze_allocation_lifecycle(&allocation_events, &deallocation_events);
let pressure_events: Vec<_> = self
.event_buffer
.iter()
.filter_map(|e| match e {
ScirS2Event::MemoryPressure { .. } => Some(e),
_ => None,
})
.collect();
if !pressure_events.is_empty() {
self.analyze_pressure_trends(&pressure_events);
}
self.event_buffer.clear();
}
pub fn get_statistics(&self) -> &EventStatistics {
&self.event_stats
}
pub fn set_buffer_limit(&mut self, limit: usize) {
self.buffer_limit = limit;
}
pub fn get_event_severity(&self, event: &ScirS2Event) -> EventSeverity {
match event {
ScirS2Event::Allocation { .. } => EventSeverity::Debug,
ScirS2Event::Deallocation { .. } => EventSeverity::Debug,
ScirS2Event::PoolCreated { .. } => EventSeverity::Info,
ScirS2Event::PoolDestroyed { .. } => EventSeverity::Info,
ScirS2Event::MemoryPressure { level, .. } => match level {
PressureLevel::None => EventSeverity::Debug,
PressureLevel::Low => EventSeverity::Info,
PressureLevel::Medium => EventSeverity::Warning,
PressureLevel::High => EventSeverity::Error,
PressureLevel::Critical => EventSeverity::Critical,
},
ScirS2Event::OptimizationSuggestion { .. } => EventSeverity::Info,
ScirS2Event::PoolUtilizationChange { .. } => EventSeverity::Info,
ScirS2Event::PerformanceDegradation {
threshold_exceeded, ..
} => {
if *threshold_exceeded {
EventSeverity::Warning
} else {
EventSeverity::Info
}
}
ScirS2Event::FragmentationEvent {
fragmentation_level,
..
} => {
if *fragmentation_level > 0.5 {
EventSeverity::Warning
} else {
EventSeverity::Info
}
}
}
}
pub fn clear_statistics(&mut self) {
self.event_stats = EventStatistics::new();
}
pub fn flush_buffer(&mut self) {
self.process_buffer();
}
fn event_passes_filters(&self, event: &ScirS2Event) -> bool {
if self.filters.is_empty() {
return true;
}
for filter in &self.filters {
if !self.event_matches_filter(event, filter) {
return false;
}
}
true
}
fn event_matches_filter(&self, event: &ScirS2Event, filter: &EventFilter) -> bool {
let event_type = self.get_event_type_name(event);
let event_severity = self.get_event_severity(event);
if !filter.include_types.is_empty() && !filter.include_types.contains(&event_type) {
return false;
}
if filter.exclude_types.contains(&event_type) {
return false;
}
if event_severity < filter.min_severity {
return false;
}
true
}
fn get_event_type_name(&self, event: &ScirS2Event) -> String {
match event {
ScirS2Event::Allocation { .. } => "Allocation".to_string(),
ScirS2Event::Deallocation { .. } => "Deallocation".to_string(),
ScirS2Event::PoolCreated { .. } => "PoolCreated".to_string(),
ScirS2Event::PoolDestroyed { .. } => "PoolDestroyed".to_string(),
ScirS2Event::MemoryPressure { .. } => "MemoryPressure".to_string(),
ScirS2Event::OptimizationSuggestion { .. } => "OptimizationSuggestion".to_string(),
ScirS2Event::PoolUtilizationChange { .. } => "PoolUtilizationChange".to_string(),
ScirS2Event::PerformanceDegradation { .. } => "PerformanceDegradation".to_string(),
ScirS2Event::FragmentationEvent { .. } => "FragmentationEvent".to_string(),
}
}
fn analyze_allocation_lifecycle(
&self,
_allocations: &[&ScirS2Event],
_deallocations: &[&ScirS2Event],
) {
}
fn analyze_pressure_trends(&self, _pressure_events: &[&ScirS2Event]) {
}
}
impl EventStatistics {
fn new() -> Self {
Self {
total_events: 0,
events_by_type: HashMap::new(),
processing_times: Vec::new(),
avg_processing_time: Duration::from_secs(0),
event_rate: 0.0,
last_processing_time: Instant::now(),
}
}
fn record_event(&mut self, event: &ScirS2Event, timestamp: Instant) {
self.total_events += 1;
let event_type = match event {
ScirS2Event::Allocation { .. } => "Allocation",
ScirS2Event::Deallocation { .. } => "Deallocation",
ScirS2Event::PoolCreated { .. } => "PoolCreated",
ScirS2Event::PoolDestroyed { .. } => "PoolDestroyed",
ScirS2Event::MemoryPressure { .. } => "MemoryPressure",
ScirS2Event::OptimizationSuggestion { .. } => "OptimizationSuggestion",
ScirS2Event::PoolUtilizationChange { .. } => "PoolUtilizationChange",
ScirS2Event::PerformanceDegradation { .. } => "PerformanceDegradation",
ScirS2Event::FragmentationEvent { .. } => "FragmentationEvent",
};
*self
.events_by_type
.entry(event_type.to_string())
.or_insert(0) += 1;
let time_since_last = timestamp.duration_since(self.last_processing_time);
if time_since_last.as_secs_f64() > 0.0 {
self.event_rate = 1.0 / time_since_last.as_secs_f64();
}
self.last_processing_time = timestamp;
}
fn update_avg_processing_time(&mut self) {
if !self.processing_times.is_empty() {
let total: Duration = self.processing_times.iter().sum();
self.avg_processing_time = total / self.processing_times.len() as u32;
}
}
pub fn events_per_second(&self) -> f64 {
self.event_rate
}
pub fn most_common_event_type(&self) -> Option<String> {
self.events_by_type
.iter()
.max_by_key(|(_, count)| *count)
.map(|(event_type, _)| event_type.clone())
}
}
impl EventFilter {
pub fn new(name: String) -> Self {
Self {
name,
include_types: Vec::new(),
exclude_types: Vec::new(),
min_severity: EventSeverity::Debug,
custom_filter: None,
}
}
pub fn allocation_only() -> Self {
Self {
name: "Allocation Filter".to_string(),
include_types: vec!["Allocation".to_string(), "Deallocation".to_string()],
exclude_types: Vec::new(),
min_severity: EventSeverity::Debug,
custom_filter: None,
}
}
pub fn high_severity_only() -> Self {
Self {
name: "High Severity Filter".to_string(),
include_types: Vec::new(),
exclude_types: Vec::new(),
min_severity: EventSeverity::Warning,
custom_filter: None,
}
}
pub fn performance_events() -> Self {
Self {
name: "Performance Filter".to_string(),
include_types: vec![
"PerformanceDegradation".to_string(),
"OptimizationSuggestion".to_string(),
"FragmentationEvent".to_string(),
],
exclude_types: Vec::new(),
min_severity: EventSeverity::Info,
custom_filter: None,
}
}
pub fn include_type(&mut self, event_type: String) {
self.include_types.push(event_type);
}
pub fn exclude_type(&mut self, event_type: String) {
self.exclude_types.push(event_type);
}
pub fn set_min_severity(&mut self, severity: EventSeverity) {
self.min_severity = severity;
}
}
impl Default for ScirS2EventProcessor {
fn default() -> Self {
Self::new()
}
}