fulgurance 0.4.1

A blazing-fast, adaptive prefetching and caching library for Rust
Documentation
//! Prefetch Module
//!
//! This module provides the complete framework for prefetch strategies.
//! It organizes all traditional and ML-based prefetch strategies,
//! offers descriptive enums and factory functions for dynamic creation,
//! and exposes benchmark-related traits and utilities.

use crate::PrefetchStrategy;

// Submodule declarations for classic prefetchers
pub mod sequential;
pub mod markov;
pub mod stride;
pub mod history_based;
pub mod adaptive;

// Submodule declarations for machine learning and neural network prefetchers
pub mod neural;
pub mod lstm;
pub mod transformer;
pub mod reinforcement;

// Re-export all prefetcher types for easy external use
pub use sequential::SequentialPrefetch;
pub use markov::MarkovPrefetch;
pub use stride::StridePrefetch;
pub use history_based::HistoryBasedPrefetch;
pub use adaptive::{AdaptivePrefetch, NumericKey};
pub use neural::NeuralPrefetch;
pub use lstm::LSTMPrefetch;
pub use transformer::TransformerPrefetch;
pub use reinforcement::RLPrefetch;

/// Enum listing all available prefetch strategy types.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PrefetchType {
    // Traditional
    Sequential,
    Markov,
    Stride,
    HistoryBased,
    Adaptive,
    None,

    // Machine Learning / Neural Networks
    Neural,
    LSTM,
    Transformer,
    ReinforcementLearning,

    // Future/Advanced strategies
    ConvolutionalNeural,
    RecurrentNeural,
    GAN,
    AutoEncoder,
    DecisionTree,
    RandomForest,
    SVM,
    GeneticAlgorithm,
    SimulatedAnnealing,
    ParticleSwarm,
    NeuralMarkov,
    LSTMWithAttention,
    TransformerWithRL,
}

impl PrefetchType {
    /// Returns all available prefetch types for benchmarking and iteration.
    pub fn all() -> &'static [PrefetchType] {
        &[
            Self::Sequential,
            Self::Markov,
            Self::Stride,
            Self::HistoryBased,
            Self::Adaptive,
            Self::None,
            Self::Neural,
            Self::LSTM,
            Self::Transformer,
            Self::ReinforcementLearning,
        ]
    }

    /// Returns the string name of the prefetch type.
    pub fn name(self) -> &'static str {
        match self {
            Self::Sequential => "Sequential",
            Self::Markov => "Markov",
            Self::Stride => "Stride",
            Self::HistoryBased => "HistoryBased",
            Self::Adaptive => "Adaptive",
            Self::None => "None",
            Self::Neural => "Neural",
            Self::LSTM => "LSTM",
            Self::Transformer => "Transformer",
            Self::ReinforcementLearning => "ReinforcementLearning",
            Self::ConvolutionalNeural => "ConvolutionalNeural",
            Self::RecurrentNeural => "RecurrentNeural",
            Self::GAN => "GAN",
            Self::AutoEncoder => "AutoEncoder",
            Self::DecisionTree => "DecisionTree",
            Self::RandomForest => "RandomForest",
            Self::SVM => "SVM",
            Self::GeneticAlgorithm => "GeneticAlgorithm",
            Self::SimulatedAnnealing => "SimulatedAnnealing",
            Self::ParticleSwarm => "ParticleSwarm",
            Self::NeuralMarkov => "NeuralMarkov",
            Self::LSTMWithAttention => "LSTMWithAttention",
            Self::TransformerWithRL => "TransformerWithRL",
        }
    }

    /// Returns a short description for the prefetch type.
    pub fn description(self) -> &'static str {
        match self {
            Self::Sequential => "Predicts sequential access patterns with stride detection",
            Self::Markov => "Predicts with Markov chain access patterns",
            Self::Stride => "Detects and predicts multiple stride patterns simultaneously",
            Self::HistoryBased => "Learns from historical access sequences (n-grams)",
            Self::Adaptive => "Dynamically combines multiple strategies with performance weighting",
            Self::None => "No prefetching - baseline strategy",
            Self::Neural => "Neural network for complex non-linear patterns",
            Self::LSTM => "Long Short-Term Memory networks for temporal patterns",
            Self::Transformer => "Self-attention mechanisms for long-range dependencies",
            Self::ReinforcementLearning => "Q-learning for adaptive policies",
            _ => "Not yet implemented",
        }
    }
}

/// The complexity level of a prefetch strategy, useful for benchmarking and optimization.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ComplexityLevel {
    VeryLow,
    Low,
    Medium,
    High,
    VeryHigh,
    Optimization,
}

impl ComplexityLevel {
    /// Returns a human-readable training time estimate.
    pub fn training_time(self) -> &'static str {
        match self {
            Self::VeryLow => "No training",
            Self::Low => "Minimal (< 0.1ms)",
            Self::Medium => "Low (0.1-1ms)",
            Self::High => "Moderate (1-10ms)",
            Self::VeryHigh => "High (10-100ms)",
            Self::Optimization => "Variable",
        }
    }

    /// Returns an estimate of memory usage.
    pub fn memory_usage(self) -> &'static str {
        match self {
            Self::VeryLow => "< 100B",
            Self::Low => "< 1KB",
            Self::Medium => "1-10KB",
            Self::High => "10-100KB",
            Self::VeryHigh => "100KB-1MB",
            Self::Optimization => "Variable",
        }
    }
}

/// Characteristics describing a prefetch strategy.
#[derive(Debug, Clone)]
pub struct PrefetchCharacteristics {
    pub prediction_accuracy: &'static str,
    pub memory_overhead: &'static str,
    pub cpu_overhead: &'static str,
    pub adaptability: &'static str,
    pub best_use_case: &'static str,
    pub training_required: bool,
    pub complexity_level: ComplexityLevel,
}

/// A no-op prefetch strategy for baseline and testing.
#[derive(Debug, Clone, Default)]
pub struct NoPrefetch;

impl<K> PrefetchStrategy<K> for NoPrefetch {
    fn predict_next(&mut self, _accessed_key: &K) -> Vec<K> {
        Vec::new()
    }
    fn update_access_pattern(&mut self, _key: &K) {}
    fn reset(&mut self) {}
}

/// Macro to generate factory functions for different key types
macro_rules! create_factory_function {
    ($func_name:ident, $key_type:ty) => {
        pub fn $func_name(prefetch_type: PrefetchType) -> Box<dyn PrefetchStrategy<$key_type>> {
            match prefetch_type {
                PrefetchType::Sequential => Box::new(SequentialPrefetch::<$key_type>::new()),
                PrefetchType::Markov => Box::new(MarkovPrefetch::<$key_type>::new()),
                PrefetchType::Stride => Box::new(StridePrefetch::<$key_type>::new()),
                PrefetchType::HistoryBased => Box::new(HistoryBasedPrefetch::<$key_type>::new()),
                PrefetchType::Adaptive => Box::new(AdaptivePrefetch::<$key_type>::new()),
                PrefetchType::None => Box::new(NoPrefetch),
                PrefetchType::Neural => Box::new(NeuralPrefetch::<$key_type>::new()),
                PrefetchType::LSTM => Box::new(LSTMPrefetch::<$key_type>::new()),
                PrefetchType::Transformer => Box::new(TransformerPrefetch::<$key_type>::new()),
                PrefetchType::ReinforcementLearning => Box::new(RLPrefetch::<$key_type>::new()),
                _ => {
                    eprintln!(
                        "Warning: {} not implemented for {}, using Sequential fallback", 
                        prefetch_type.name(),
                        stringify!($key_type)
                    );
                    Box::new(SequentialPrefetch::<$key_type>::new())
                }
            }
        }
    };
}

// Generate factory functions for all supported key types
create_factory_function!(create_prefetch_strategy_i32, i32);
create_factory_function!(create_prefetch_strategy_i64, i64);
create_factory_function!(create_prefetch_strategy_usize, usize);

/// Generic factory function that works with any key type that implements the required traits
/// This version only supports strategies that work with the basic KeyConvert trait
pub fn create_prefetch_strategy<K>(prefetch_type: PrefetchType) -> Box<dyn PrefetchStrategy<K>>
where
    K: Copy + neural::KeyConvert + 'static,
{
    match prefetch_type {
        // Only ML-based strategies that work with KeyConvert trait
        PrefetchType::Neural => Box::new(NeuralPrefetch::<K>::new()),
        PrefetchType::LSTM => Box::new(LSTMPrefetch::<K>::new()),
        PrefetchType::Transformer => Box::new(TransformerPrefetch::<K>::new()),
        PrefetchType::ReinforcementLearning => Box::new(RLPrefetch::<K>::new()),
        PrefetchType::None => Box::new(NoPrefetch),
        _ => {
            eprintln!("Warning: {} requires additional traits or is not implemented, using Neural fallback", prefetch_type.name());
            Box::new(NeuralPrefetch::<K>::new())
        }
    }
}

/// Trait combining `PrefetchStrategy` with benchmarking metadata.
pub trait BenchmarkablePrefetch<K>: PrefetchStrategy<K>
where
    K: Clone,
{
    fn prefetch_type(&self) -> PrefetchType;

    fn benchmark_name(&self) -> String {
        format!("{}_prefetch", self.prefetch_type().name())
    }

    fn characteristics(&self) -> PrefetchCharacteristics {
        match self.prefetch_type() {
            PrefetchType::Sequential => PrefetchCharacteristics {
                prediction_accuracy: "High for sequential patterns",
                memory_overhead: "Very Low",
                cpu_overhead: "Very Low",
                adaptability: "Low",
                best_use_case: "Sequential data access with consistent strides",
                training_required: false,
                complexity_level: ComplexityLevel::VeryLow,
            },
            PrefetchType::Markov => PrefetchCharacteristics {
                prediction_accuracy: "High for complex patterns",
                memory_overhead: "Medium",
                cpu_overhead: "Medium",
                adaptability: "High",
                best_use_case: "Complex non-sequential patterns with state dependencies",
                training_required: false,
                complexity_level: ComplexityLevel::Medium,
            },
            PrefetchType::Stride => PrefetchCharacteristics {
                prediction_accuracy: "High for stride patterns",
                memory_overhead: "Low",
                cpu_overhead: "Low",
                adaptability: "Medium",
                best_use_case: "Regular stride access patterns",
                training_required: false,
                complexity_level: ComplexityLevel::Low,
            },
            PrefetchType::HistoryBased => PrefetchCharacteristics {
                prediction_accuracy: "High for repetitive patterns",
                memory_overhead: "Medium",
                cpu_overhead: "Medium",
                adaptability: "High",
                best_use_case: "Repetitive access sequences with n-gram patterns",
                training_required: false,
                complexity_level: ComplexityLevel::Medium,
            },
            PrefetchType::Adaptive => PrefetchCharacteristics {
                prediction_accuracy: "Very High - combines multiple strategies",
                memory_overhead: "High",
                cpu_overhead: "High",
                adaptability: "Very High",
                best_use_case: "Mixed workloads with varying access patterns",
                training_required: false,
                complexity_level: ComplexityLevel::High,
            },
            PrefetchType::Neural => PrefetchCharacteristics {
                prediction_accuracy: "Very High for complex non-linear patterns",
                memory_overhead: "Medium-High",
                cpu_overhead: "High",
                adaptability: "Very High",
                best_use_case: "Complex multi-variate access dependencies",
                training_required: true,
                complexity_level: ComplexityLevel::High,
            },
            PrefetchType::LSTM => PrefetchCharacteristics {
                prediction_accuracy: "Very High for temporal patterns",
                memory_overhead: "High",
                cpu_overhead: "Very High",
                adaptability: "Very High",
                best_use_case: "Long-term temporal dependencies in access patterns",
                training_required: true,
                complexity_level: ComplexityLevel::VeryHigh,
            },
            PrefetchType::Transformer => PrefetchCharacteristics {
                prediction_accuracy: "Excellent for long-range dependencies",
                memory_overhead: "Very High",
                cpu_overhead: "Very High",
                adaptability: "Excellent",
                best_use_case: "Complex long-range access pattern dependencies",
                training_required: true,
                complexity_level: ComplexityLevel::VeryHigh,
            },
            PrefetchType::ReinforcementLearning => PrefetchCharacteristics {
                prediction_accuracy: "High - learns optimal policies",
                memory_overhead: "Medium",
                cpu_overhead: "Medium-High",
                adaptability: "Very High",
                best_use_case: "Dynamic environments requiring adaptive policies",
                training_required: true,
                complexity_level: ComplexityLevel::High,
            },
            PrefetchType::None => PrefetchCharacteristics {
                prediction_accuracy: "None - baseline",
                memory_overhead: "None",
                cpu_overhead: "None",
                adaptability: "None",
                best_use_case: "Baseline for performance comparison",
                training_required: false,
                complexity_level: ComplexityLevel::VeryLow,
            },
            _ => PrefetchCharacteristics {
                prediction_accuracy: "Unknown",
                memory_overhead: "Unknown",
                cpu_overhead: "Unknown",
                adaptability: "Unknown",
                best_use_case: "Unknown",
                training_required: false,
                complexity_level: ComplexityLevel::VeryLow,
            },
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn prefetch_type_name() {
        assert_eq!(PrefetchType::Sequential.name(), "Sequential");
        assert_eq!(PrefetchType::Neural.name(), "Neural");
        assert_eq!(PrefetchType::Transformer.name(), "Transformer");
    }

    #[test]
    fn no_prefetch_returns_empty_vec() {
        let mut no_prefetch = NoPrefetch;
        assert!(no_prefetch.predict_next(&42_i32).is_empty());
    }

    #[test]
    fn factory_functions_work() {
        let _strategy_i32 = create_prefetch_strategy_i32(PrefetchType::Sequential);
        let _strategy_i64 = create_prefetch_strategy_i64(PrefetchType::Neural);
        let _strategy_usize = create_prefetch_strategy_usize(PrefetchType::LSTM);
    }

    #[test]
    fn generic_factory_function_works() {
        let _strategy: Box<dyn PrefetchStrategy<i32>> = create_prefetch_strategy(PrefetchType::Transformer);
        let _strategy: Box<dyn PrefetchStrategy<usize>> = create_prefetch_strategy(PrefetchType::ReinforcementLearning);
    }
}