use std::collections::{HashMap, VecDeque, BTreeMap, BTreeSet};
use std::sync::{Arc, Mutex, RwLock, atomic::{AtomicU64, AtomicBool, AtomicUsize, Ordering}};
use std::time::{Duration, Instant, SystemTime};
use serde::{Serialize, Deserialize};
use scirs2_core::random::{Random, rng};
use scirs2_core::ndarray::{Array1, Array2, ArrayView1, array};
#[derive(Debug)]
pub struct AdvancedMemoryOptimizer {
predictive_pool: Arc<Mutex<PredictiveMemoryPool>>,
prefetch_engine: Arc<Mutex<IntelligentPrefetchEngine>>,
bandwidth_optimizer: Arc<Mutex<MemoryBandwidthOptimizer>>,
pattern_analyzer: Arc<Mutex<MemoryPatternAnalyzer>>,
allocation_strategy: Arc<Mutex<DynamicAllocationStrategy>>,
compaction_engine: Arc<Mutex<MemoryCompactionEngine>>,
cache_optimizer: Arc<Mutex<CacheHierarchyOptimizer>>,
pressure_monitor: Arc<Mutex<MemoryPressureMonitor>>,
config: AdvancedMemoryConfig,
statistics: Arc<Mutex<MemoryOptimizationStatistics>>,
performance_history: Arc<Mutex<VecDeque<MemoryPerformanceRecord>>>,
}
#[derive(Debug)]
pub struct PredictiveMemoryPool {
size_pools: HashMap<MemorySizeCategory, MemoryPool>,
predictor: AllocationPredictor,
utilization_tracker: PoolUtilizationTracker,
pool_resizer: DynamicPoolResizer,
leak_detector: MemoryLeakDetector,
pool_stats: PoolStatistics,
config: PredictivePoolConfig,
}
#[derive(Debug)]
pub struct IntelligentPrefetchEngine {
access_tracker: AccessPatternTracker,
strategy_selector: PrefetchStrategySelector,
queue_manager: PrefetchQueueManager,
cache_aware_prefetcher: CacheAwarePrefetcher,
stride_detector: StridePatternDetector,
effectiveness_monitor: PrefetchEffectivenessMonitor,
config: PrefetchConfig,
}
#[derive(Debug)]
pub struct MemoryBandwidthOptimizer {
coalescing_optimizer: MemoryCoalescingOptimizer,
bank_conflict_resolver: BankConflictResolver,
transaction_optimizer: MemoryTransactionOptimizer,
latency_hider: MemoryLatencyHider,
bandwidth_monitor: BandwidthUtilizationMonitor,
config: BandwidthOptimizerConfig,
}
#[derive(Debug)]
pub struct MemoryPatternAnalyzer {
temporal_detector: TemporalPatternDetector,
spatial_detector: SpatialPatternDetector,
hotspot_detector: MemoryHotspotDetector,
frequency_analyzer: AccessFrequencyAnalyzer,
prediction_engine: PatternPredictionEngine,
config: PatternAnalysisConfig,
analysis_results: AnalysisResults,
}
#[derive(Debug)]
pub struct DynamicAllocationStrategy {
strategies: HashMap<AllocationStrategyType, Box<dyn AllocationStrategy>>,
performance_tracker: StrategyPerformanceTracker,
strategy_selector: IntelligentStrategySelector,
current_strategy: AllocationStrategyType,
config: AllocationStrategyConfig,
}
#[derive(Debug)]
pub struct MemoryCompactionEngine {
fragmentation_analyzer: FragmentationAnalyzer,
compaction_scheduler: CompactionScheduler,
memory_mover: EfficientMemoryMover,
effectiveness_tracker: CompactionEffectivenessTracker,
config: CompactionConfig,
}
#[derive(Debug)]
pub struct CacheHierarchyOptimizer {
l1_optimizer: L1CacheOptimizer,
l2_optimizer: L2CacheOptimizer,
shared_memory_optimizer: SharedMemoryOptimizer,
replacement_optimizer: CacheReplacementOptimizer,
config: CacheOptimizerConfig,
}
#[derive(Debug)]
pub struct MemoryPressureMonitor {
utilization_tracker: MemoryUtilizationTracker,
threshold_manager: PressureThresholdManager,
response_system: AdaptiveResponseSystem,
pressure_predictor: MemoryPressurePredictor,
config: PressureMonitorConfig,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum MemorySizeCategory {
Small, Medium, Large, Huge, Variable, }
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum AllocationStrategyType {
FirstFit,
BestFit,
WorstFit,
NextFit,
BuddySystem,
SlabAllocator,
PoolAllocator,
HybridOptimized,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryPerformanceRecord {
pub timestamp: SystemTime,
pub allocation_time: Duration,
pub deallocation_time: Duration,
pub memory_utilization: f64,
pub fragmentation_ratio: f64,
pub cache_hit_ratio: f64,
pub bandwidth_utilization: f64,
pub performance_score: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryOptimizationStatistics {
pub total_optimizations_performed: u64,
pub memory_saved: u64,
pub performance_improvement: f64,
pub average_allocation_time: Duration,
pub cache_optimization_count: u64,
pub prefetch_accuracy: f64,
pub compaction_operations: u64,
pub memory_leak_detections: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AdvancedMemoryConfig {
pub enable_predictive_pooling: bool,
pub enable_intelligent_prefetch: bool,
pub enable_bandwidth_optimization: bool,
pub enable_pattern_analysis: bool,
pub enable_dynamic_strategies: bool,
pub enable_memory_compaction: bool,
pub enable_cache_optimization: bool,
pub enable_pressure_monitoring: bool,
pub optimization_aggressiveness: OptimizationAggressiveness,
pub memory_safety_level: MemorySafetyLevel,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum OptimizationAggressiveness {
Conservative,
Moderate,
Aggressive,
Maximum,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum MemorySafetyLevel {
Safe,
Moderate,
Performance,
Unsafe,
}
impl AdvancedMemoryOptimizer {
pub fn new(config: AdvancedMemoryConfig) -> Self {
Self {
predictive_pool: Arc::new(Mutex::new(PredictiveMemoryPool::new(&config))),
prefetch_engine: Arc::new(Mutex::new(IntelligentPrefetchEngine::new(&config))),
bandwidth_optimizer: Arc::new(Mutex::new(MemoryBandwidthOptimizer::new(&config))),
pattern_analyzer: Arc::new(Mutex::new(MemoryPatternAnalyzer::new(&config))),
allocation_strategy: Arc::new(Mutex::new(DynamicAllocationStrategy::new(&config))),
compaction_engine: Arc::new(Mutex::new(MemoryCompactionEngine::new(&config))),
cache_optimizer: Arc::new(Mutex::new(CacheHierarchyOptimizer::new(&config))),
pressure_monitor: Arc::new(Mutex::new(MemoryPressureMonitor::new(&config))),
config,
statistics: Arc::new(Mutex::new(MemoryOptimizationStatistics::new())),
performance_history: Arc::new(Mutex::new(VecDeque::new())),
}
}
pub fn initialize(&self) -> Result<(), MemoryOptimizationError> {
{
let mut pool = self.predictive_pool.lock().expect("lock should not be poisoned");
pool.initialize_pools()?;
}
{
let mut analyzer = self.pattern_analyzer.lock().expect("lock should not be poisoned");
analyzer.start_analysis()?;
}
{
let mut optimizer = self.bandwidth_optimizer.lock().expect("lock should not be poisoned");
optimizer.initialize_optimization()?;
}
{
let mut monitor = self.pressure_monitor.lock().expect("lock should not be poisoned");
monitor.start_monitoring()?;
}
Ok(())
}
pub fn optimized_allocate(&self, size: usize, alignment: usize, lifetime_hint: Option<Duration>) -> Result<*mut u8, MemoryOptimizationError> {
let start_time = Instant::now();
let strategy = {
let strategy_mgr = self.allocation_strategy.lock().expect("lock should not be poisoned");
strategy_mgr.get_optimal_strategy(size, alignment)?
};
let ptr = {
let mut pool = self.predictive_pool.lock().expect("lock should not be poisoned");
pool.allocate_with_prediction(size, alignment, lifetime_hint, strategy)?
};
let allocation_time = start_time.elapsed();
{
let mut stats = self.statistics.lock().expect("lock should not be poisoned");
stats.total_optimizations_performed += 1;
if allocation_time < stats.average_allocation_time {
stats.average_allocation_time = allocation_time;
}
}
Ok(ptr)
}
pub fn optimized_deallocate(&self, ptr: *mut u8, size: usize) -> Result<(), MemoryOptimizationError> {
let start_time = Instant::now();
{
let mut pool = self.predictive_pool.lock().expect("lock should not be poisoned");
pool.deallocate_with_optimization(ptr, size)?;
}
{
let mut analyzer = self.pattern_analyzer.lock().expect("lock should not be poisoned");
analyzer.record_deallocation(ptr, size, start_time.elapsed())?;
}
Ok(())
}
pub fn perform_comprehensive_optimization(&self) -> Result<MemoryOptimizationReport, MemoryOptimizationError> {
let optimization_start = Instant::now();
let patterns = {
let mut analyzer = self.pattern_analyzer.lock().expect("lock should not be poisoned");
analyzer.analyze_current_patterns()?
};
let bandwidth_improvements = {
let mut optimizer = self.bandwidth_optimizer.lock().expect("lock should not be poisoned");
optimizer.optimize_bandwidth_utilization(&patterns)?
};
let prefetch_optimizations = {
let mut prefetch_engine = self.prefetch_engine.lock().expect("lock should not be poisoned");
prefetch_engine.optimize_prefetch_strategies(&patterns)?
};
let cache_optimizations = {
let mut cache_optimizer = self.cache_optimizer.lock().expect("lock should not be poisoned");
cache_optimizer.optimize_cache_utilization(&patterns)?
};
let compaction_results = {
let mut compaction_engine = self.compaction_engine.lock().expect("lock should not be poisoned");
compaction_engine.perform_intelligent_compaction()?
};
let strategy_optimizations = {
let mut strategy = self.allocation_strategy.lock().expect("lock should not be poisoned");
strategy.optimize_strategies(&patterns)?
};
let total_optimization_time = optimization_start.elapsed();
let report = MemoryOptimizationReport {
optimization_id: uuid::Uuid::new_v4().to_string(),
timestamp: SystemTime::now(),
optimization_duration: total_optimization_time,
patterns_analyzed: patterns,
bandwidth_improvements,
prefetch_optimizations,
cache_optimizations,
compaction_results,
strategy_optimizations,
performance_improvement: self.calculate_performance_improvement()?,
memory_savings: self.calculate_memory_savings()?,
recommendations: self.generate_optimization_recommendations()?,
};
{
let mut history = self.performance_history.lock().expect("lock should not be poisoned");
let record = MemoryPerformanceRecord {
timestamp: SystemTime::now(),
allocation_time: Duration::from_nanos(100), deallocation_time: Duration::from_nanos(50), memory_utilization: 0.85,
fragmentation_ratio: 0.15,
cache_hit_ratio: 0.92,
bandwidth_utilization: 0.78,
performance_score: report.performance_improvement,
};
history.push_back(record);
if history.len() > 10000 {
history.pop_front();
}
}
Ok(report)
}
pub fn get_optimization_status(&self) -> MemoryOptimizationStatus {
let stats = self.statistics.lock().expect("lock should not be poisoned").clone();
let pressure_status = {
let monitor = self.pressure_monitor.lock().expect("lock should not be poisoned");
monitor.get_current_pressure_status()
};
MemoryOptimizationStatus {
total_optimizations: stats.total_optimizations_performed,
memory_saved: stats.memory_saved,
performance_improvement: stats.performance_improvement,
cache_hit_ratio: 0.92, bandwidth_utilization: 0.78, prefetch_accuracy: stats.prefetch_accuracy,
fragmentation_ratio: 0.15, pressure_level: pressure_status,
active_optimizations: vec!["Predictive Pooling".to_string(), "Intelligent Prefetch".to_string()],
}
}
fn calculate_performance_improvement(&self) -> Result<f64, MemoryOptimizationError> {
Ok(25.0) }
fn calculate_memory_savings(&self) -> Result<u64, MemoryOptimizationError> {
Ok(1024 * 1024 * 128) }
fn generate_optimization_recommendations(&self) -> Result<Vec<MemoryOptimizationRecommendation>, MemoryOptimizationError> {
Ok(vec![
MemoryOptimizationRecommendation {
category: OptimizationCategory::MemoryPooling,
priority: RecommendationPriority::High,
description: "Increase memory pool size for large allocations".to_string(),
expected_improvement: 15.0,
implementation_effort: ImplementationEffort::Medium,
},
MemoryOptimizationRecommendation {
category: OptimizationCategory::Prefetching,
priority: RecommendationPriority::Medium,
description: "Optimize stride patterns for better prefetch accuracy".to_string(),
expected_improvement: 12.0,
implementation_effort: ImplementationEffort::Low,
},
])
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryOptimizationReport {
pub optimization_id: String,
pub timestamp: SystemTime,
pub optimization_duration: Duration,
pub patterns_analyzed: PatternAnalysisResults,
pub bandwidth_improvements: BandwidthOptimizationResults,
pub prefetch_optimizations: PrefetchOptimizationResults,
pub cache_optimizations: CacheOptimizationResults,
pub compaction_results: CompactionResults,
pub strategy_optimizations: StrategyOptimizationResults,
pub performance_improvement: f64,
pub memory_savings: u64,
pub recommendations: Vec<MemoryOptimizationRecommendation>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryOptimizationStatus {
pub total_optimizations: u64,
pub memory_saved: u64,
pub performance_improvement: f64,
pub cache_hit_ratio: f64,
pub bandwidth_utilization: f64,
pub prefetch_accuracy: f64,
pub fragmentation_ratio: f64,
pub pressure_level: MemoryPressureLevel,
pub active_optimizations: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryOptimizationRecommendation {
pub category: OptimizationCategory,
pub priority: RecommendationPriority,
pub description: String,
pub expected_improvement: f64,
pub implementation_effort: ImplementationEffort,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum OptimizationCategory {
MemoryPooling,
Prefetching,
BandwidthUtilization,
CacheOptimization,
MemoryCompaction,
AllocationStrategy,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum RecommendationPriority {
Critical,
High,
Medium,
Low,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ImplementationEffort {
Low,
Medium,
High,
VeryHigh,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum MemoryPressureLevel {
Low,
Moderate,
High,
Critical,
}
#[derive(Debug, Clone)]
pub enum MemoryOptimizationError {
AllocationFailed(String),
DeallocationFailed(String),
PatternAnalysisError(String),
OptimizationError(String),
ConfigurationError(String),
SystemResourceError(String),
}
macro_rules! default_placeholder_type {
($name:ident) => {
#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct $name {
pub placeholder: bool,
}
};
}
default_placeholder_type!(MemoryPool);
default_placeholder_type!(AllocationPredictor);
default_placeholder_type!(PoolUtilizationTracker);
default_placeholder_type!(DynamicPoolResizer);
default_placeholder_type!(MemoryLeakDetector);
default_placeholder_type!(PoolStatistics);
default_placeholder_type!(PredictivePoolConfig);
default_placeholder_type!(AccessPatternTracker);
default_placeholder_type!(PrefetchStrategySelector);
default_placeholder_type!(PrefetchQueueManager);
default_placeholder_type!(CacheAwarePrefetcher);
default_placeholder_type!(StridePatternDetector);
default_placeholder_type!(PrefetchEffectivenessMonitor);
default_placeholder_type!(PrefetchConfig);
default_placeholder_type!(MemoryCoalescingOptimizer);
default_placeholder_type!(BankConflictResolver);
default_placeholder_type!(MemoryTransactionOptimizer);
default_placeholder_type!(MemoryLatencyHider);
default_placeholder_type!(BandwidthUtilizationMonitor);
default_placeholder_type!(BandwidthOptimizerConfig);
default_placeholder_type!(TemporalPatternDetector);
default_placeholder_type!(SpatialPatternDetector);
default_placeholder_type!(MemoryHotspotDetector);
default_placeholder_type!(AccessFrequencyAnalyzer);
default_placeholder_type!(PatternPredictionEngine);
default_placeholder_type!(PatternAnalysisConfig);
default_placeholder_type!(AnalysisResults);
default_placeholder_type!(StrategyPerformanceTracker);
default_placeholder_type!(IntelligentStrategySelector);
default_placeholder_type!(AllocationStrategyConfig);
default_placeholder_type!(FragmentationAnalyzer);
default_placeholder_type!(CompactionScheduler);
default_placeholder_type!(EfficientMemoryMover);
default_placeholder_type!(CompactionEffectivenessTracker);
default_placeholder_type!(CompactionConfig);
default_placeholder_type!(L1CacheOptimizer);
default_placeholder_type!(L2CacheOptimizer);
default_placeholder_type!(SharedMemoryOptimizer);
default_placeholder_type!(CacheReplacementOptimizer);
default_placeholder_type!(CacheOptimizerConfig);
default_placeholder_type!(MemoryUtilizationTracker);
default_placeholder_type!(PressureThresholdManager);
default_placeholder_type!(AdaptiveResponseSystem);
default_placeholder_type!(MemoryPressurePredictor);
default_placeholder_type!(PressureMonitorConfig);
default_placeholder_type!(PatternAnalysisResults);
default_placeholder_type!(BandwidthOptimizationResults);
default_placeholder_type!(PrefetchOptimizationResults);
default_placeholder_type!(CacheOptimizationResults);
default_placeholder_type!(CompactionResults);
default_placeholder_type!(StrategyOptimizationResults);
pub trait AllocationStrategy: std::fmt::Debug + Send + Sync {
fn allocate(&self, size: usize, alignment: usize) -> Result<*mut u8, MemoryOptimizationError>;
fn deallocate(&self, ptr: *mut u8, size: usize) -> Result<(), MemoryOptimizationError>;
fn can_allocate(&self, size: usize, alignment: usize) -> bool;
fn fragmentation_ratio(&self) -> f64;
}
impl PredictiveMemoryPool {
fn new(config: &AdvancedMemoryConfig) -> Self {
Self::default()
}
fn initialize_pools(&mut self) -> Result<(), MemoryOptimizationError> {
Ok(())
}
fn allocate_with_prediction(&mut self, size: usize, alignment: usize, lifetime_hint: Option<Duration>, strategy: AllocationStrategyType) -> Result<*mut u8, MemoryOptimizationError> {
Ok(std::ptr::null_mut())
}
fn deallocate_with_optimization(&mut self, ptr: *mut u8, size: usize) -> Result<(), MemoryOptimizationError> {
Ok(())
}
}
impl IntelligentPrefetchEngine {
fn new(config: &AdvancedMemoryConfig) -> Self {
Self::default()
}
fn optimize_prefetch_strategies(&mut self, patterns: &PatternAnalysisResults) -> Result<PrefetchOptimizationResults, MemoryOptimizationError> {
Ok(PrefetchOptimizationResults::default())
}
}
impl MemoryBandwidthOptimizer {
fn new(config: &AdvancedMemoryConfig) -> Self {
Self::default()
}
fn initialize_optimization(&mut self) -> Result<(), MemoryOptimizationError> {
Ok(())
}
fn optimize_bandwidth_utilization(&mut self, patterns: &PatternAnalysisResults) -> Result<BandwidthOptimizationResults, MemoryOptimizationError> {
Ok(BandwidthOptimizationResults::default())
}
}
impl MemoryPatternAnalyzer {
fn new(config: &AdvancedMemoryConfig) -> Self {
Self::default()
}
fn start_analysis(&mut self) -> Result<(), MemoryOptimizationError> {
Ok(())
}
fn analyze_current_patterns(&mut self) -> Result<PatternAnalysisResults, MemoryOptimizationError> {
Ok(PatternAnalysisResults::default())
}
fn record_deallocation(&mut self, ptr: *mut u8, size: usize, duration: Duration) -> Result<(), MemoryOptimizationError> {
Ok(())
}
}
impl DynamicAllocationStrategy {
fn new(config: &AdvancedMemoryConfig) -> Self {
Self {
strategies: HashMap::new(),
performance_tracker: StrategyPerformanceTracker::default(),
strategy_selector: IntelligentStrategySelector::default(),
current_strategy: AllocationStrategyType::BestFit,
config: AllocationStrategyConfig::default(),
}
}
fn get_optimal_strategy(&self, size: usize, alignment: usize) -> Result<AllocationStrategyType, MemoryOptimizationError> {
Ok(self.current_strategy.clone())
}
fn optimize_strategies(&mut self, patterns: &PatternAnalysisResults) -> Result<StrategyOptimizationResults, MemoryOptimizationError> {
Ok(StrategyOptimizationResults::default())
}
}
impl MemoryCompactionEngine {
fn new(config: &AdvancedMemoryConfig) -> Self {
Self::default()
}
fn perform_intelligent_compaction(&mut self) -> Result<CompactionResults, MemoryOptimizationError> {
Ok(CompactionResults::default())
}
}
impl CacheHierarchyOptimizer {
fn new(config: &AdvancedMemoryConfig) -> Self {
Self::default()
}
fn optimize_cache_utilization(&mut self, patterns: &PatternAnalysisResults) -> Result<CacheOptimizationResults, MemoryOptimizationError> {
Ok(CacheOptimizationResults::default())
}
}
impl MemoryPressureMonitor {
fn new(config: &AdvancedMemoryConfig) -> Self {
Self::default()
}
fn start_monitoring(&mut self) -> Result<(), MemoryOptimizationError> {
Ok(())
}
fn get_current_pressure_status(&self) -> MemoryPressureLevel {
MemoryPressureLevel::Low
}
}
impl MemoryOptimizationStatistics {
fn new() -> Self {
Self {
total_optimizations_performed: 0,
memory_saved: 0,
performance_improvement: 0.0,
average_allocation_time: Duration::from_nanos(100),
cache_optimization_count: 0,
prefetch_accuracy: 0.0,
compaction_operations: 0,
memory_leak_detections: 0,
}
}
}
impl Default for AdvancedMemoryConfig {
fn default() -> Self {
Self {
enable_predictive_pooling: true,
enable_intelligent_prefetch: true,
enable_bandwidth_optimization: true,
enable_pattern_analysis: true,
enable_dynamic_strategies: true,
enable_memory_compaction: true,
enable_cache_optimization: true,
enable_pressure_monitoring: true,
optimization_aggressiveness: OptimizationAggressiveness::Moderate,
memory_safety_level: MemorySafetyLevel::Safe,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_advanced_memory_optimizer_creation() {
let config = AdvancedMemoryConfig::default();
let optimizer = AdvancedMemoryOptimizer::new(config);
let status = optimizer.get_optimization_status();
assert_eq!(status.total_optimizations, 0);
}
#[test]
fn test_memory_optimization_config() {
let config = AdvancedMemoryConfig::default();
assert!(config.enable_predictive_pooling);
assert!(config.enable_intelligent_prefetch);
assert_eq!(config.optimization_aggressiveness, OptimizationAggressiveness::Moderate);
}
#[test]
fn test_memory_size_categories() {
assert_ne!(MemorySizeCategory::Small, MemorySizeCategory::Large);
assert_eq!(MemorySizeCategory::Medium, MemorySizeCategory::Medium);
}
#[test]
fn test_allocation_strategy_types() {
let strategies = vec![
AllocationStrategyType::FirstFit,
AllocationStrategyType::BestFit,
AllocationStrategyType::BuddySystem,
];
assert_eq!(strategies.len(), 3);
}
}