use std::collections::HashMap;
use std::path::{Path, PathBuf};
use std::sync::Arc;
type BuiltinDispatchTable =
Arc<RwLock<Vec<fn(&[runmat_builtins::Value]) -> runmat_builtins::BuiltinFuture>>>;
use std::time::Duration;
use parking_lot::RwLock;
use serde::{Deserialize, Serialize};
pub mod builder;
pub mod compression;
pub mod format;
pub mod loader;
pub mod presets;
pub mod validation;
pub use builder::SnapshotBuilder;
pub use format::{SnapshotFormat, SnapshotHeader, SnapshotMetadata};
pub use loader::SnapshotLoader;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Snapshot {
pub metadata: SnapshotMetadata,
pub builtins: BuiltinRegistry,
pub hir_cache: HirCache,
pub bytecode_cache: BytecodeCache,
pub gc_presets: GcPresetCache,
pub optimization_hints: OptimizationHints,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BuiltinRegistry {
pub name_index: HashMap<String, usize>,
pub functions: Vec<BuiltinMetadata>,
#[serde(skip)]
pub dispatch_table: BuiltinDispatchTable,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BuiltinMetadata {
pub name: String,
pub arity: BuiltinArity,
pub category: BuiltinCategory,
pub complexity: ComputationalComplexity,
pub optimization_level: OptimizationLevel,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum BuiltinArity {
Exact(usize),
Range(usize, usize),
Variadic(usize),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum BuiltinCategory {
Math,
LinearAlgebra,
Statistics,
MatrixOps,
Trigonometric,
Comparison,
Utility,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ComputationalComplexity {
Constant,
Linear,
Quadratic,
Cubic,
Exponential,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum OptimizationLevel {
None,
Basic,
Aggressive,
MaxPerformance,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HirCache {
pub functions: HashMap<String, runmat_hir::HirAssembly>,
pub patterns: Vec<HirPattern>,
pub type_cache: HashMap<String, runmat_hir::Type>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HirPattern {
pub name: String,
pub pattern: runmat_hir::HirAssembly,
pub frequency: u32,
pub optimization_priority: OptimizationLevel,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BytecodeCache {
pub stdlib_bytecode: HashMap<String, runmat_vm::Bytecode>,
pub operation_sequences: Vec<BytecodeSequence>,
pub hotspots: Vec<HotspotBytecode>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BytecodeSequence {
pub name: String,
pub bytecode: runmat_vm::Bytecode,
pub usage_count: u64,
pub average_execution_time: Duration,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HotspotBytecode {
pub name: String,
pub bytecode: runmat_vm::Bytecode,
pub execution_frequency: u64,
pub jit_compilation_threshold: u32,
pub optimization_hints: Vec<OptimizationHint>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GcPresetCache {
pub presets: HashMap<String, runmat_gc::GcConfig>,
pub default_preset: String,
pub performance_profiles: HashMap<String, GcPerformanceProfile>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GcPerformanceProfile {
pub average_allocation_rate: f64,
pub average_collection_time: Duration,
pub memory_overhead: f64,
pub throughput_impact: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OptimizationHints {
pub jit_hints: Vec<JitHint>,
pub memory_hints: Vec<MemoryHint>,
pub execution_hints: Vec<ExecutionHint>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JitHint {
pub pattern: String,
pub hint_type: JitHintType,
pub priority: OptimizationLevel,
pub expected_performance_gain: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum JitHintType {
InlineCandidate,
LoopOptimization,
VectorizeCandidate,
ConstantFolding,
DeadCodeElimination,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryHint {
pub data_structure: String,
pub hint_type: MemoryHintType,
pub alignment: usize,
pub prefetch_pattern: PrefetchPattern,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum MemoryHintType {
CacheLocalityOptimization,
PrefetchOptimization,
AlignmentOptimization,
CompressionCandidate,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum PrefetchPattern {
Sequential,
Random,
Strided(usize),
Hierarchical,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExecutionHint {
pub pattern: String,
pub hint_type: ExecutionHintType,
pub frequency: u64,
pub optimization_potential: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ExecutionHintType {
HotPath,
ColdPath,
BranchPrediction,
ParallelizationCandidate,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OptimizationHint {
pub hint_type: String,
pub parameters: HashMap<String, String>,
pub expected_speedup: f64,
}
#[derive(Debug, Clone)]
pub struct LoadingStats {
pub load_time: Duration,
pub decompression_time: Duration,
pub validation_time: Duration,
pub initialization_time: Duration,
pub total_size: u64,
pub compressed_size: u64,
pub compression_ratio: f64,
pub builtin_count: u64,
pub cache_hit_rate: f64,
}
impl LoadingStats {
pub fn compression_efficiency(&self) -> f64 {
1.0 - (self.compressed_size as f64 / self.total_size as f64)
}
pub fn loading_throughput(&self) -> f64 {
self.total_size as f64 / self.load_time.as_secs_f64()
}
}
#[derive(thiserror::Error, Debug)]
pub enum SnapshotError {
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("Serialization error: {0}")]
Serialization(#[from] bincode::Error),
#[error("Compression error: {message}")]
Compression { message: String },
#[error("Validation error: {message}")]
Validation { message: String },
#[error("Version mismatch: expected {expected}, found {found}")]
VersionMismatch { expected: String, found: String },
#[error("Corrupted snapshot: {reason}")]
Corrupted { reason: String },
#[error("Configuration error: {message}")]
Configuration { message: String },
}
pub type SnapshotResult<T> = std::result::Result<T, SnapshotError>;
#[derive(Debug, Clone)]
pub struct SnapshotConfig {
pub compression_enabled: bool,
pub compression_algorithm: CompressionAlgorithm,
pub compression_level: u32,
pub validation_enabled: bool,
pub memory_mapping_enabled: bool,
pub parallel_loading: bool,
pub progress_reporting: bool,
pub max_optimization_level: OptimizationLevel,
pub max_cache_size: usize,
pub cache_eviction_policy: CacheEvictionPolicy,
}
#[derive(Debug, Clone)]
pub enum CompressionAlgorithm {
None,
Lz4,
Zstd,
Auto, }
#[derive(Debug, Clone)]
pub enum CacheEvictionPolicy {
LeastRecentlyUsed,
LeastFrequentlyUsed,
TimeToLive(Duration),
Adaptive,
}
impl Default for SnapshotConfig {
fn default() -> Self {
Self {
compression_enabled: true,
compression_algorithm: CompressionAlgorithm::Auto,
compression_level: 6,
validation_enabled: true,
memory_mapping_enabled: true,
parallel_loading: true,
progress_reporting: false,
max_optimization_level: OptimizationLevel::MaxPerformance,
max_cache_size: 128 * 1024 * 1024, cache_eviction_policy: CacheEvictionPolicy::Adaptive,
}
}
}
pub struct SnapshotManager {
config: SnapshotConfig,
cache: Arc<RwLock<HashMap<PathBuf, Arc<Snapshot>>>>,
stats: Arc<RwLock<HashMap<PathBuf, LoadingStats>>>,
}
impl SnapshotManager {
pub fn new(config: SnapshotConfig) -> Self {
Self {
config,
cache: Arc::new(RwLock::new(HashMap::new())),
stats: Arc::new(RwLock::new(HashMap::new())),
}
}
pub fn create_snapshot<P: AsRef<Path>>(&self, output_path: P) -> SnapshotResult<()> {
let builder = SnapshotBuilder::new(self.config.clone());
builder.build_and_save(output_path)
}
pub fn load_snapshot<P: AsRef<Path>>(&self, snapshot_path: P) -> SnapshotResult<Arc<Snapshot>> {
let path = snapshot_path.as_ref().to_path_buf();
{
let cache = self.cache.read();
if let Some(snapshot) = cache.get(&path) {
return Ok(Arc::clone(snapshot));
}
}
let mut loader = SnapshotLoader::new(self.config.clone());
let (snapshot, stats) = loader.load(&path)?;
let snapshot = Arc::new(snapshot);
{
let mut cache = self.cache.write();
cache.insert(path.clone(), Arc::clone(&snapshot));
}
{
let mut stats_map = self.stats.write();
stats_map.insert(path, stats);
}
Ok(snapshot)
}
pub fn get_stats<P: AsRef<Path>>(&self, snapshot_path: P) -> Option<LoadingStats> {
let stats = self.stats.read();
stats.get(snapshot_path.as_ref()).cloned()
}
pub fn clear_cache(&self) {
let mut cache = self.cache.write();
cache.clear();
let mut stats = self.stats.write();
stats.clear();
}
pub fn cache_stats(&self) -> (usize, usize) {
let cache = self.cache.read();
let total_size = cache
.values()
.map(|snapshot| bincode::serialized_size(&**snapshot).unwrap_or(0) as usize)
.sum();
(cache.len(), total_size)
}
}
impl Default for SnapshotManager {
fn default() -> Self {
Self::new(SnapshotConfig::default())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_snapshot_config_default() {
let config = SnapshotConfig::default();
assert!(config.compression_enabled);
assert!(config.validation_enabled);
assert!(config.memory_mapping_enabled);
assert!(config.parallel_loading);
}
#[test]
fn test_snapshot_manager_creation() {
let manager = SnapshotManager::default();
let (cache_entries, cache_size) = manager.cache_stats();
assert_eq!(cache_entries, 0);
assert_eq!(cache_size, 0);
}
#[test]
fn test_loading_stats_calculations() {
let stats = LoadingStats {
load_time: Duration::from_millis(100),
decompression_time: Duration::from_millis(20),
validation_time: Duration::from_millis(10),
initialization_time: Duration::from_millis(5),
total_size: 1000,
compressed_size: 600,
compression_ratio: 0.4,
builtin_count: 50,
cache_hit_rate: 0.8,
};
assert_eq!(stats.compression_efficiency(), 0.4);
assert_eq!(stats.loading_throughput(), 10000.0); }
}