1use serde::{Deserialize, Serialize};
7
8use super::allocation::{BottleneckType, ImpactLevel, PerformanceBottleneck};
9use super::generic::MemoryAccessPattern;
10
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
13pub struct FunctionCallTrackingInfo {
14 pub function_name: String,
16 pub module_path: String,
18 pub total_call_count: u64,
20 pub call_frequency_per_sec: f64,
22 pub avg_execution_time_ns: f64,
24 pub total_execution_time_ns: u64,
26 pub call_stack_info: CallStackInfo,
28 pub memory_allocations_per_call: f64,
30 pub performance_characteristics: FunctionPerformanceCharacteristics,
32 pub call_patterns: Vec<CallPattern>,
34}
35
36#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
38pub struct CallStackInfo {
39 pub max_stack_depth: u32,
41 pub avg_stack_depth: f64,
43 pub common_call_sequences: Vec<CallSequence>,
45 pub recursive_calls: Vec<RecursiveCallInfo>,
47 pub stack_overflow_risk: StackOverflowRisk,
49}
50
51#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
53pub struct CallSequence {
54 pub function_sequence: Vec<String>,
56 pub frequency: u32,
58 pub avg_execution_time_ns: f64,
60 pub memory_usage_pattern: MemoryUsagePattern,
62}
63
64#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
66pub struct MemoryUsagePattern {
67 pub peak_memory_usage: usize,
69 pub avg_memory_usage: usize,
71 pub allocation_frequency: f64,
73 pub deallocation_frequency: f64,
75 pub leak_potential: LeakPotential,
77}
78
79#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
81pub enum LeakPotential {
82 Low,
84 Medium,
86 High,
88 Critical,
90}
91
92#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
94pub struct RecursiveCallInfo {
95 pub function_name: String,
97 pub max_recursion_depth: u32,
99 pub avg_recursion_depth: f64,
101 pub tail_recursion_potential: bool,
103 pub stack_usage_per_level: usize,
105 pub recursion_performance_impact: RecursionPerformanceImpact,
107}
108
109#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
111pub struct RecursionPerformanceImpact {
112 pub stack_overhead_per_call: usize,
114 pub call_overhead_ns: f64,
116 pub cache_impact: f64,
118 pub optimization_recommendations: Vec<String>,
120}
121
122#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
124pub enum StackOverflowRisk {
125 Low,
127 Medium,
129 High,
131 Critical,
133}
134
135#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
137pub struct FunctionPerformanceCharacteristics {
138 pub cpu_usage_percent: f64,
140 pub memory_characteristics: FunctionMemoryCharacteristics,
142 pub io_characteristics: IOCharacteristics,
144 pub concurrency_characteristics: ConcurrencyCharacteristics,
146 pub bottlenecks: Vec<PerformanceBottleneck>,
148}
149
150#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
152pub struct FunctionMemoryCharacteristics {
153 pub stack_memory_usage: usize,
155 pub heap_allocations: u32,
157 pub access_pattern: MemoryAccessPattern,
159 pub cache_efficiency: f64,
161 pub memory_bandwidth_utilization: f64,
163}
164
165#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
167pub struct IOCharacteristics {
168 pub file_io_operations: u32,
170 pub network_io_operations: u32,
172 pub avg_io_wait_time_ns: f64,
174 pub io_throughput_bytes_per_sec: f64,
176 pub io_efficiency_score: f64,
178}
179
180#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
182pub struct ConcurrencyCharacteristics {
183 pub thread_safety_level: ThreadSafetyLevel,
185 pub lock_contention_frequency: f64,
187 pub parallel_execution_potential: f64,
189 pub synchronization_overhead_ns: f64,
191 pub deadlock_risk: DeadlockRisk,
193}
194
195#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
197pub enum ThreadSafetyLevel {
198 ThreadSafe,
200 ConditionallyThreadSafe,
202 NotThreadSafe,
204 Unknown,
206}
207
208#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
210pub enum DeadlockRisk {
211 None,
213 Low,
215 Medium,
217 High,
219}
220
221#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
223pub struct CallPattern {
224 pub pattern_type: CallPatternType,
226 pub description: String,
228 pub frequency: u32,
230 pub performance_impact: f64,
232 pub optimization_potential: f64,
234}
235
236#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
238pub enum CallPatternType {
239 Sequential,
241 Recursive,
243 Iterative,
245 Conditional,
247 Parallel,
249 Asynchronous,
251 Callback,
253 EventDriven,
255}
256
257impl From<crate::core::types::FunctionCallTrackingInfo> for FunctionCallTrackingInfo {
258 fn from(old: crate::core::types::FunctionCallTrackingInfo) -> Self {
259 Self {
260 function_name: old.function_name,
261 module_path: old.module_path,
262 total_call_count: old.total_call_count,
263 call_frequency_per_sec: old.call_frequency_per_sec,
264 avg_execution_time_ns: old.avg_execution_time_ns,
265 total_execution_time_ns: old.total_execution_time_ns,
266 call_stack_info: CallStackInfo {
267 max_stack_depth: old.call_stack_info.max_stack_depth,
268 avg_stack_depth: old.call_stack_info.avg_stack_depth,
269 common_call_sequences: old
270 .call_stack_info
271 .common_call_sequences
272 .into_iter()
273 .map(|s| CallSequence {
274 function_sequence: s.function_sequence,
275 frequency: s.frequency,
276 avg_execution_time_ns: s.avg_execution_time_ns,
277 memory_usage_pattern: MemoryUsagePattern {
278 peak_memory_usage: s.memory_usage_pattern.peak_memory_usage,
279 avg_memory_usage: s.memory_usage_pattern.avg_memory_usage,
280 allocation_frequency: s.memory_usage_pattern.allocation_frequency,
281 deallocation_frequency: s.memory_usage_pattern.deallocation_frequency,
282 leak_potential: match s.memory_usage_pattern.leak_potential {
283 crate::core::types::LeakPotential::Low => LeakPotential::Low,
284 crate::core::types::LeakPotential::Medium => LeakPotential::Medium,
285 crate::core::types::LeakPotential::High => LeakPotential::High,
286 crate::core::types::LeakPotential::Critical => {
287 LeakPotential::Critical
288 }
289 },
290 },
291 })
292 .collect(),
293 recursive_calls: old
294 .call_stack_info
295 .recursive_calls
296 .into_iter()
297 .map(|r| RecursiveCallInfo {
298 function_name: r.function_name,
299 max_recursion_depth: r.max_recursion_depth,
300 avg_recursion_depth: r.avg_recursion_depth,
301 tail_recursion_potential: r.tail_recursion_potential,
302 stack_usage_per_level: r.stack_usage_per_level,
303 recursion_performance_impact: RecursionPerformanceImpact {
304 stack_overhead_per_call: r
305 .recursion_performance_impact
306 .stack_overhead_per_call,
307 call_overhead_ns: r.recursion_performance_impact.call_overhead_ns,
308 cache_impact: r.recursion_performance_impact.cache_impact,
309 optimization_recommendations: r
310 .recursion_performance_impact
311 .optimization_recommendations,
312 },
313 })
314 .collect(),
315 stack_overflow_risk: match old.call_stack_info.stack_overflow_risk {
316 crate::core::types::StackOverflowRisk::Low => StackOverflowRisk::Low,
317 crate::core::types::StackOverflowRisk::Medium => StackOverflowRisk::Medium,
318 crate::core::types::StackOverflowRisk::High => StackOverflowRisk::High,
319 crate::core::types::StackOverflowRisk::Critical => StackOverflowRisk::Critical,
320 },
321 },
322 memory_allocations_per_call: old.memory_allocations_per_call,
323 performance_characteristics: FunctionPerformanceCharacteristics {
324 cpu_usage_percent: old.performance_characteristics.cpu_usage_percent,
325 memory_characteristics: FunctionMemoryCharacteristics {
326 stack_memory_usage: old
327 .performance_characteristics
328 .memory_characteristics
329 .stack_memory_usage,
330 heap_allocations: old
331 .performance_characteristics
332 .memory_characteristics
333 .heap_allocations,
334 access_pattern: match old
335 .performance_characteristics
336 .memory_characteristics
337 .access_pattern
338 {
339 crate::core::types::MemoryAccessPattern::Sequential => {
340 MemoryAccessPattern::Sequential
341 }
342 crate::core::types::MemoryAccessPattern::Random => {
343 MemoryAccessPattern::Random
344 }
345 crate::core::types::MemoryAccessPattern::Strided { stride } => {
346 MemoryAccessPattern::Strided { stride }
347 }
348 crate::core::types::MemoryAccessPattern::Clustered => {
349 MemoryAccessPattern::Clustered
350 }
351 crate::core::types::MemoryAccessPattern::Mixed => {
352 MemoryAccessPattern::Mixed
353 }
354 },
355 cache_efficiency: old
356 .performance_characteristics
357 .memory_characteristics
358 .cache_efficiency,
359 memory_bandwidth_utilization: old
360 .performance_characteristics
361 .memory_characteristics
362 .memory_bandwidth_utilization,
363 },
364 io_characteristics: IOCharacteristics {
365 file_io_operations: old
366 .performance_characteristics
367 .io_characteristics
368 .file_io_operations,
369 network_io_operations: old
370 .performance_characteristics
371 .io_characteristics
372 .network_io_operations,
373 avg_io_wait_time_ns: old
374 .performance_characteristics
375 .io_characteristics
376 .avg_io_wait_time_ns,
377 io_throughput_bytes_per_sec: old
378 .performance_characteristics
379 .io_characteristics
380 .io_throughput_bytes_per_sec,
381 io_efficiency_score: old
382 .performance_characteristics
383 .io_characteristics
384 .io_efficiency_score,
385 },
386 concurrency_characteristics: ConcurrencyCharacteristics {
387 thread_safety_level: match old
388 .performance_characteristics
389 .concurrency_characteristics
390 .thread_safety_level
391 {
392 crate::core::types::ThreadSafetyLevel::ThreadSafe => {
393 ThreadSafetyLevel::ThreadSafe
394 }
395 crate::core::types::ThreadSafetyLevel::ConditionallyThreadSafe => {
396 ThreadSafetyLevel::ConditionallyThreadSafe
397 }
398 crate::core::types::ThreadSafetyLevel::NotThreadSafe => {
399 ThreadSafetyLevel::NotThreadSafe
400 }
401 crate::core::types::ThreadSafetyLevel::Unknown => {
402 ThreadSafetyLevel::Unknown
403 }
404 },
405 lock_contention_frequency: old
406 .performance_characteristics
407 .concurrency_characteristics
408 .lock_contention_frequency,
409 parallel_execution_potential: old
410 .performance_characteristics
411 .concurrency_characteristics
412 .parallel_execution_potential,
413 synchronization_overhead_ns: old
414 .performance_characteristics
415 .concurrency_characteristics
416 .synchronization_overhead_ns,
417 deadlock_risk: match old
418 .performance_characteristics
419 .concurrency_characteristics
420 .deadlock_risk
421 {
422 crate::core::types::DeadlockRisk::None => DeadlockRisk::None,
423 crate::core::types::DeadlockRisk::Low => DeadlockRisk::Low,
424 crate::core::types::DeadlockRisk::Medium => DeadlockRisk::Medium,
425 crate::core::types::DeadlockRisk::High => DeadlockRisk::High,
426 },
427 },
428 bottlenecks: old
429 .performance_characteristics
430 .bottlenecks
431 .into_iter()
432 .map(|b| PerformanceBottleneck {
433 bottleneck_type: match b.bottleneck_type {
434 crate::core::types::BottleneckType::MemoryAllocation => {
435 BottleneckType::MemoryAllocation
436 }
437 crate::core::types::BottleneckType::MemoryDeallocation => {
438 BottleneckType::MemoryDeallocation
439 }
440 crate::core::types::BottleneckType::CacheMiss => {
441 BottleneckType::CacheMiss
442 }
443 crate::core::types::BottleneckType::BranchMisprediction => {
444 BottleneckType::BranchMisprediction
445 }
446 crate::core::types::BottleneckType::FunctionCall => {
447 BottleneckType::FunctionCall
448 }
449 crate::core::types::BottleneckType::DataMovement => {
450 BottleneckType::DataMovement
451 }
452 crate::core::types::BottleneckType::Synchronization => {
453 BottleneckType::Synchronization
454 }
455 crate::core::types::BottleneckType::IO => BottleneckType::IO,
456 },
457 location: b.location,
458 severity: match b.severity {
459 crate::core::types::ImpactLevel::Low => ImpactLevel::Low,
460 crate::core::types::ImpactLevel::Medium => ImpactLevel::Medium,
461 crate::core::types::ImpactLevel::High => ImpactLevel::High,
462 crate::core::types::ImpactLevel::Critical => ImpactLevel::Critical,
463 },
464 description: b.description,
465 optimization_suggestion: b.optimization_suggestion,
466 })
467 .collect(),
468 },
469 call_patterns: old
470 .call_patterns
471 .into_iter()
472 .map(|p| CallPattern {
473 pattern_type: match p.pattern_type {
474 crate::core::types::CallPatternType::Sequential => {
475 CallPatternType::Sequential
476 }
477 crate::core::types::CallPatternType::Recursive => {
478 CallPatternType::Recursive
479 }
480 crate::core::types::CallPatternType::Iterative => {
481 CallPatternType::Iterative
482 }
483 crate::core::types::CallPatternType::Conditional => {
484 CallPatternType::Conditional
485 }
486 crate::core::types::CallPatternType::Parallel => CallPatternType::Parallel,
487 crate::core::types::CallPatternType::Asynchronous => {
488 CallPatternType::Asynchronous
489 }
490 crate::core::types::CallPatternType::Callback => CallPatternType::Callback,
491 crate::core::types::CallPatternType::EventDriven => {
492 CallPatternType::EventDriven
493 }
494 },
495 description: p.description,
496 frequency: p.frequency,
497 performance_impact: p.performance_impact,
498 optimization_potential: p.optimization_potential,
499 })
500 .collect(),
501 }
502 }
503}
504
505#[cfg(test)]
506mod tests {
507 use super::*;
508
509 #[test]
510 fn test_function_call_tracking_info() {
511 let info = FunctionCallTrackingInfo {
512 function_name: "test_func".to_string(),
513 module_path: "test::module".to_string(),
514 total_call_count: 100,
515 call_frequency_per_sec: 10.0,
516 avg_execution_time_ns: 1000.0,
517 total_execution_time_ns: 100000,
518 call_stack_info: CallStackInfo {
519 max_stack_depth: 5,
520 avg_stack_depth: 3.0,
521 common_call_sequences: vec![],
522 recursive_calls: vec![],
523 stack_overflow_risk: StackOverflowRisk::Low,
524 },
525 memory_allocations_per_call: 2.0,
526 performance_characteristics: FunctionPerformanceCharacteristics {
527 cpu_usage_percent: 5.0,
528 memory_characteristics: FunctionMemoryCharacteristics {
529 stack_memory_usage: 1024,
530 heap_allocations: 5,
531 access_pattern: MemoryAccessPattern::Sequential,
532 cache_efficiency: 0.9,
533 memory_bandwidth_utilization: 0.5,
534 },
535 io_characteristics: IOCharacteristics {
536 file_io_operations: 0,
537 network_io_operations: 0,
538 avg_io_wait_time_ns: 0.0,
539 io_throughput_bytes_per_sec: 0.0,
540 io_efficiency_score: 1.0,
541 },
542 concurrency_characteristics: ConcurrencyCharacteristics {
543 thread_safety_level: ThreadSafetyLevel::ThreadSafe,
544 lock_contention_frequency: 0.0,
545 parallel_execution_potential: 0.8,
546 synchronization_overhead_ns: 0.0,
547 deadlock_risk: DeadlockRisk::None,
548 },
549 bottlenecks: vec![],
550 },
551 call_patterns: vec![],
552 };
553
554 assert_eq!(info.function_name, "test_func");
555 assert_eq!(info.total_call_count, 100);
556 }
557
558 #[test]
559 fn test_call_pattern_type() {
560 let patterns = vec![
561 CallPatternType::Sequential,
562 CallPatternType::Recursive,
563 CallPatternType::Parallel,
564 ];
565
566 for pattern in patterns {
567 assert!(!format!("{pattern:?}").is_empty());
568 }
569 }
570}