anya-core 1.2.0

Enterprise-grade Bitcoin Infrastructure Platform
Documentation
use std::error::Error;
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::{RwLock, Mutex};
use serde::{Serialize, Deserialize};

/// Adaptive Data Replication Strategy
#[derive(Debug, Clone)]
pub struct AdaptiveReplicationManager {
    /// System-wide replication configuration
    config: ReplicationConfig,
    
    /// Tracked data states across different nodes/systems
    data_states: Arc<RwLock<HashMap<String, DataReplicationState>>>,
    
    /// Hardware resource tracker
    resource_tracker: Arc<Mutex<HardwareResourceTracker>>,
}

/// Replication Configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReplicationConfig {
    /// Maximum number of replicas
    pub max_replicas: usize,
    
    /// Minimum number of replicas for critical data
    pub min_critical_replicas: usize,
    
    /// Pruning strategy
    pub pruning_strategy: PruningStrategy,
    
    /// State preservation thresholds
    pub state_preservation_rules: StatePreservationRules,
}

/// Pruning Strategies
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum PruningStrategy {
    /// Time-based pruning
    TimeBased {
        /// Maximum age of data before pruning
        max_data_age_seconds: u64,
    },
    
    /// Size-based pruning
    SizeBased {
        /// Maximum total storage allocation
        max_storage_bytes: u64,
    },
    
    /// Hybrid pruning considering multiple factors
    Adaptive {
        /// Time threshold
        max_data_age_seconds: u64,
        /// Storage threshold
        max_storage_bytes: u64,
        /// Usage frequency weight
        usage_frequency_weight: f64,
    },
}

/// State Preservation Rules
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StatePreservationRules {
    /// Critical data never pruned
    pub preserve_critical_data: bool,
    
    /// Minimum state retention period
    pub min_state_retention_seconds: u64,
    
    /// State compression strategies
    pub compression_strategy: CompressionStrategy,
}

/// Data Compression Strategies
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CompressionStrategy {
    /// No compression
    None,
    /// Lightweight compression
    Light,
    /// Heavy compression with potential performance impact
    Aggressive,
}

/// Replication State for Individual Data Entities
#[derive(Debug, Clone)]
struct DataReplicationState {
    /// Unique identifier for the data
    id: String,
    
    /// Current number of replicas
    replica_count: usize,
    
    /// Timestamp of last access
    last_accessed: std::time::SystemTime,
    
    /// Data criticality level
    criticality: DataCriticality,
    
    /// Current state preservation status
    preservation_status: PreservationStatus,
}

/// Data Criticality Levels
#[derive(Debug, Clone, PartialEq)]
enum DataCriticality {
    Critical,
    High,
    Medium,
    Low,
}

/// State Preservation Status
#[derive(Debug, Clone)]
enum PreservationStatus {
    FullyPreserved,
    Compressed,
    Prunable,
}

impl AdaptiveReplicationManager {
    /// Create a new adaptive replication manager
    pub fn new(config: ReplicationConfig) -> Self {
        Self {
            config,
            data_states: Arc::new(RwLock::new(HashMap::new())),
            resource_tracker: Arc::new(Mutex::new(HardwareResourceTracker::new())),
        }
    }
    
    /// Determine replication strategy based on system resources
    pub async fn determine_replication_strategy(&self, data_id: &str) -> Result<ReplicationAction, String> {
        let resources = self.resource_tracker.lock().await;
        let mut data_states = self.data_states.write().await;
        
        // Get or create data state
        let data_state = data_states.entry(data_id.to_string())
            .or_insert(DataReplicationState {
                id: data_id.to_string(),
                replica_count: 0,
                last_accessed: std::time::SystemTime::now(),
                criticality: DataCriticality::Medium,
                preservation_status: PreservationStatus::FullyPreserved,
            });
        
        // Adaptive replication decision
        let action = match self.config.pruning_strategy {
            PruningStrategy::Adaptive { 
                max_data_age_seconds, 
                max_storage_bytes, 
                usage_frequency_weight 
            } => {
                // Complex decision logic
                if resources.available_storage() > max_storage_bytes {
                    ReplicationAction::Replicate
                } else if self.is_data_old_and_unused(data_state, max_data_age_seconds, usage_frequency_weight) {
                    ReplicationAction::Prune
                } else {
                    ReplicationAction::Compress
                }
            },
            PruningStrategy::TimeBased { max_data_age_seconds } => {
                if self.is_data_old(data_state, max_data_age_seconds) {
                    ReplicationAction::Prune
                } else {
                    ReplicationAction::Maintain
                }
            },
            PruningStrategy::SizeBased { max_storage_bytes } => {
                if resources.available_storage() > max_storage_bytes {
                    ReplicationAction::Prune
                } else {
                    ReplicationAction::Maintain
                }
            },
        };
        
        Ok(action)
    }
    
    /// Check if data is old and unused
    fn is_data_old_and_unused(&self, 
        data_state: &DataReplicationState, 
        max_age: u64, 
        usage_weight: f64
    ) -> bool {
        let age = std::time::SystemTime::now()
            .duration_since(data_state.last_accessed)
            .map(|d| d.as_secs())
            .unwrap_or(0);
        
        // Complex aging calculation
        age > max_age && (data_state.replica_count as f64 * usage_weight) < 1.0
    }
    
    /// Simple age check
    fn is_data_old(&self, 
        data_state: &DataReplicationState, 
        max_age: u64
    ) -> bool {
        std::time::SystemTime::now()
            .duration_since(data_state.last_accessed)
            .map(|d| d.as_secs() > max_age)
            .unwrap_or(false)
    }
}

/// Replication Actions
#[derive(Debug)]
enum ReplicationAction {
    /// Create additional replicas
    Replicate,
    /// Remove unnecessary replicas
    Prune,
    /// Compress existing data
    Compress,
    /// Maintain current state
    Maintain,
}

/// Hardware Resource Tracking
#[derive(Debug)]
struct HardwareResourceTracker {
    /// Total available storage
    total_storage: u64,
    /// Used storage
    used_storage: u64,
    /// Available RAM
    available_ram: u64,
    /// CPU cores
    cpu_cores: usize,
}

impl HardwareResourceTracker {
    fn new() -> Self {
        // In a real implementation, this would query system resources
        Self {
            total_storage: 1_000_000_000_000, // 1TB
            used_storage: 0,
            available_ram: 32_000_000_000, // 32GB
            cpu_cores: 8,
        }
    }
    
    /// Calculate available storage
    fn available_storage(&self) -> u64 {
        self.total_storage - self.used_storage
    }
}

/// Example usage and configuration
impl AdaptiveReplicationManager {
    /// Create a default configuration optimized for most systems
    pub fn default_config() -> ReplicationConfig {
        ReplicationConfig {
            max_replicas: 5,
            min_critical_replicas: 3,
            pruning_strategy: PruningStrategy::Adaptive {
                max_data_age_seconds: 30 * 24 * 60 * 60, // 30 days
                max_storage_bytes: 500_000_000_000, // 500GB
                usage_frequency_weight: 0.7,
            },
            state_preservation_rules: StatePreservationRules {
                preserve_critical_data: true,
                min_state_retention_seconds: 7 * 24 * 60 * 60, // 7 days
                compression_strategy: CompressionStrategy::Light,
            },
        }
    }
}