1use std::cell::RefCell;
27use std::collections::HashMap;
28use std::path::{Path, PathBuf};
29use std::rc::Rc;
30use std::sync::Arc;
31
32type BuiltinDispatchTable =
34 Arc<RwLock<Vec<fn(&[runmat_builtins::Value]) -> runmat_builtins::BuiltinFuture>>>;
35use std::time::Duration;
36
37use parking_lot::RwLock;
38use serde::{Deserialize, Serialize};
39
40pub mod builder;
41pub mod compression;
42pub mod format;
43pub mod loader;
44pub mod presets;
45pub mod validation;
46
47pub use builder::SnapshotBuilder;
48pub use format::{SnapshotFormat, SnapshotHeader, SnapshotMetadata};
49pub use loader::SnapshotLoader;
50
51#[derive(Debug, Clone, Serialize, Deserialize)]
53pub struct Snapshot {
54 pub metadata: SnapshotMetadata,
56
57 pub builtins: BuiltinRegistry,
59
60 pub hir_cache: HirCache,
62
63 pub bytecode_cache: BytecodeCache,
65
66 pub gc_presets: GcPresetCache,
68
69 pub optimization_hints: OptimizationHints,
71}
72
73#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct BuiltinRegistry {
76 pub name_index: HashMap<String, usize>,
78
79 pub functions: Vec<BuiltinMetadata>,
81
82 #[serde(skip)]
84 pub dispatch_table: BuiltinDispatchTable,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct BuiltinMetadata {
90 pub name: String,
91 pub arity: BuiltinArity,
92 pub category: BuiltinCategory,
93 pub complexity: ComputationalComplexity,
94 pub optimization_level: OptimizationLevel,
95}
96
97#[derive(Debug, Clone, Serialize, Deserialize)]
99pub enum BuiltinArity {
100 Exact(usize),
102 Range(usize, usize),
104 Variadic(usize),
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize)]
110pub enum BuiltinCategory {
111 Math,
112 LinearAlgebra,
113 Statistics,
114 MatrixOps,
115 Trigonometric,
116 Comparison,
117 Utility,
118}
119
120#[derive(Debug, Clone, Serialize, Deserialize)]
122pub enum ComputationalComplexity {
123 Constant,
124 Linear,
125 Quadratic,
126 Cubic,
127 Exponential,
128}
129
130#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
132pub enum OptimizationLevel {
133 None,
134 Basic,
135 Aggressive,
136 MaxPerformance,
137}
138
139#[derive(Debug, Clone, Serialize, Deserialize)]
141pub struct HirCache {
142 pub functions: HashMap<String, runmat_hir::HirAssembly>,
144
145 pub patterns: Vec<HirPattern>,
147
148 pub type_cache: HashMap<String, runmat_hir::Type>,
150}
151
152#[derive(Debug, Clone, Serialize, Deserialize)]
154pub struct HirPattern {
155 pub name: String,
156 pub pattern: runmat_hir::HirAssembly,
157 pub frequency: u32,
158 pub optimization_priority: OptimizationLevel,
159}
160
161#[derive(Debug, Clone, Serialize, Deserialize)]
163pub struct BytecodeCache {
164 pub stdlib_bytecode: HashMap<String, runmat_vm::Bytecode>,
166
167 pub operation_sequences: Vec<BytecodeSequence>,
169
170 pub hotspots: Vec<HotspotBytecode>,
172}
173
174#[derive(Debug, Clone, Serialize, Deserialize)]
176pub struct BytecodeSequence {
177 pub name: String,
178 pub bytecode: runmat_vm::Bytecode,
179 pub usage_count: u64,
180 pub average_execution_time: Duration,
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize)]
185pub struct HotspotBytecode {
186 pub name: String,
187 pub bytecode: runmat_vm::Bytecode,
188 pub execution_frequency: u64,
189 pub jit_compilation_threshold: u32,
190 pub optimization_hints: Vec<OptimizationHint>,
191}
192
193#[derive(Debug, Clone, Serialize, Deserialize)]
195pub struct GcPresetCache {
196 pub presets: HashMap<String, runmat_gc::GcConfig>,
198
199 pub default_preset: String,
201
202 pub performance_profiles: HashMap<String, GcPerformanceProfile>,
204}
205
206#[derive(Debug, Clone, Serialize, Deserialize)]
208pub struct GcPerformanceProfile {
209 pub average_allocation_rate: f64,
210 pub average_collection_time: Duration,
211 pub memory_overhead: f64,
212 pub throughput_impact: f64,
213}
214
215#[derive(Debug, Clone, Serialize, Deserialize)]
217pub struct OptimizationHints {
218 pub jit_hints: Vec<JitHint>,
220
221 pub memory_hints: Vec<MemoryHint>,
223
224 pub execution_hints: Vec<ExecutionHint>,
226}
227
228#[derive(Debug, Clone, Serialize, Deserialize)]
230pub struct JitHint {
231 pub pattern: String,
232 pub hint_type: JitHintType,
233 pub priority: OptimizationLevel,
234 pub expected_performance_gain: f64,
235}
236
237#[derive(Debug, Clone, Serialize, Deserialize)]
239pub enum JitHintType {
240 InlineCandidate,
241 LoopOptimization,
242 VectorizeCandidate,
243 ConstantFolding,
244 DeadCodeElimination,
245}
246
247#[derive(Debug, Clone, Serialize, Deserialize)]
249pub struct MemoryHint {
250 pub data_structure: String,
251 pub hint_type: MemoryHintType,
252 pub alignment: usize,
253 pub prefetch_pattern: PrefetchPattern,
254}
255
256#[derive(Debug, Clone, Serialize, Deserialize)]
258pub enum MemoryHintType {
259 CacheLocalityOptimization,
260 PrefetchOptimization,
261 AlignmentOptimization,
262 CompressionCandidate,
263}
264
265#[derive(Debug, Clone, Serialize, Deserialize)]
267pub enum PrefetchPattern {
268 Sequential,
269 Random,
270 Strided(usize),
271 Hierarchical,
272}
273
274#[derive(Debug, Clone, Serialize, Deserialize)]
276pub struct ExecutionHint {
277 pub pattern: String,
278 pub hint_type: ExecutionHintType,
279 pub frequency: u64,
280 pub optimization_potential: f64,
281}
282
283#[derive(Debug, Clone, Serialize, Deserialize)]
285pub enum ExecutionHintType {
286 HotPath,
287 ColdPath,
288 BranchPrediction,
289 ParallelizationCandidate,
290}
291
292#[derive(Debug, Clone, Serialize, Deserialize)]
294pub struct OptimizationHint {
295 pub hint_type: String,
296 pub parameters: HashMap<String, String>,
297 pub expected_speedup: f64,
298}
299
300#[derive(Debug, Clone)]
302pub struct LoadingStats {
303 pub load_time: Duration,
304 pub decompression_time: Duration,
305 pub validation_time: Duration,
306 pub initialization_time: Duration,
307 pub total_size: u64,
308 pub compressed_size: u64,
309 pub compression_ratio: f64,
310 pub builtin_count: u64,
311 pub cache_hit_rate: f64,
312}
313
314impl LoadingStats {
315 pub fn compression_efficiency(&self) -> f64 {
316 1.0 - (self.compressed_size as f64 / self.total_size as f64)
317 }
318
319 pub fn loading_throughput(&self) -> f64 {
320 self.total_size as f64 / self.load_time.as_secs_f64()
321 }
322}
323
324#[derive(thiserror::Error, Debug)]
326pub enum SnapshotError {
327 #[error("IO error: {0}")]
328 Io(#[from] std::io::Error),
329
330 #[error("Serialization error: {0}")]
331 Serialization(#[from] bincode::Error),
332
333 #[error("Compression error: {message}")]
334 Compression { message: String },
335
336 #[error("Validation error: {message}")]
337 Validation { message: String },
338
339 #[error("Version mismatch: expected {expected}, found {found}")]
340 VersionMismatch { expected: String, found: String },
341
342 #[error("Corrupted snapshot: {reason}")]
343 Corrupted { reason: String },
344
345 #[error("Configuration error: {message}")]
346 Configuration { message: String },
347}
348
349pub type SnapshotResult<T> = std::result::Result<T, SnapshotError>;
351
352#[derive(Debug, Clone)]
354pub struct SnapshotConfig {
355 pub compression_enabled: bool,
357
358 pub compression_algorithm: CompressionAlgorithm,
360
361 pub compression_level: u32,
363
364 pub validation_enabled: bool,
366
367 pub memory_mapping_enabled: bool,
369
370 pub parallel_loading: bool,
372
373 pub progress_reporting: bool,
375
376 pub max_optimization_level: OptimizationLevel,
378
379 pub max_cache_size: usize,
381
382 pub cache_eviction_policy: CacheEvictionPolicy,
384}
385
386#[derive(Debug, Clone)]
388pub enum CompressionAlgorithm {
389 None,
390 Lz4,
391 Zstd,
392 Auto, }
394
395#[derive(Debug, Clone)]
397pub enum CacheEvictionPolicy {
398 LeastRecentlyUsed,
399 LeastFrequentlyUsed,
400 TimeToLive(Duration),
401 Adaptive,
402}
403
404impl Default for SnapshotConfig {
405 fn default() -> Self {
406 Self {
407 compression_enabled: true,
408 compression_algorithm: CompressionAlgorithm::Auto,
409 compression_level: 6,
410 validation_enabled: true,
411 memory_mapping_enabled: true,
412 parallel_loading: true,
413 progress_reporting: false,
414 max_optimization_level: OptimizationLevel::MaxPerformance,
415 max_cache_size: 128 * 1024 * 1024, cache_eviction_policy: CacheEvictionPolicy::Adaptive,
417 }
418 }
419}
420
421pub struct SnapshotManager {
423 config: SnapshotConfig,
424 cache: RefCell<HashMap<PathBuf, Rc<Snapshot>>>,
425 stats: RefCell<HashMap<PathBuf, LoadingStats>>,
426}
427
428impl SnapshotManager {
429 pub fn new(config: SnapshotConfig) -> Self {
431 Self {
432 config,
433 cache: RefCell::new(HashMap::new()),
434 stats: RefCell::new(HashMap::new()),
435 }
436 }
437
438 pub fn create_snapshot<P: AsRef<Path>>(&self, output_path: P) -> SnapshotResult<()> {
440 let builder = SnapshotBuilder::new(self.config.clone());
441 builder.build_and_save(output_path)
442 }
443
444 pub fn load_snapshot<P: AsRef<Path>>(&self, snapshot_path: P) -> SnapshotResult<Rc<Snapshot>> {
446 let path = snapshot_path.as_ref().to_path_buf();
447
448 {
450 let cache = self.cache.borrow();
451 if let Some(snapshot) = cache.get(&path) {
452 return Ok(Rc::clone(snapshot));
453 }
454 }
455
456 let mut loader = SnapshotLoader::new(self.config.clone());
458 let (snapshot, stats) = loader.load(&path)?;
459 let snapshot = Rc::new(snapshot);
460
461 {
463 let mut cache = self.cache.borrow_mut();
464 cache.insert(path.clone(), Rc::clone(&snapshot));
465 }
466 {
467 let mut stats_map = self.stats.borrow_mut();
468 stats_map.insert(path, stats);
469 }
470
471 Ok(snapshot)
472 }
473
474 pub fn get_stats<P: AsRef<Path>>(&self, snapshot_path: P) -> Option<LoadingStats> {
476 let stats = self.stats.borrow();
477 stats.get(snapshot_path.as_ref()).cloned()
478 }
479
480 pub fn clear_cache(&self) {
482 let mut cache = self.cache.borrow_mut();
483 cache.clear();
484 let mut stats = self.stats.borrow_mut();
485 stats.clear();
486 }
487
488 pub fn cache_stats(&self) -> (usize, usize) {
490 let cache = self.cache.borrow();
491 let total_size = cache
492 .values()
493 .map(|snapshot| bincode::serialized_size(&**snapshot).unwrap_or(0) as usize)
494 .sum();
495 (cache.len(), total_size)
496 }
497}
498
499impl Default for SnapshotManager {
500 fn default() -> Self {
501 Self::new(SnapshotConfig::default())
502 }
503}
504
505#[cfg(test)]
506mod tests {
507 use super::*;
508
509 #[test]
510 fn test_snapshot_config_default() {
511 let config = SnapshotConfig::default();
512 assert!(config.compression_enabled);
513 assert!(config.validation_enabled);
514 assert!(config.memory_mapping_enabled);
515 assert!(config.parallel_loading);
516 }
517
518 #[test]
519 fn test_snapshot_manager_creation() {
520 let manager = SnapshotManager::default();
521 let (cache_entries, cache_size) = manager.cache_stats();
522 assert_eq!(cache_entries, 0);
523 assert_eq!(cache_size, 0);
524 }
525
526 #[test]
527 fn test_loading_stats_calculations() {
528 let stats = LoadingStats {
529 load_time: Duration::from_millis(100),
530 decompression_time: Duration::from_millis(20),
531 validation_time: Duration::from_millis(10),
532 initialization_time: Duration::from_millis(5),
533 total_size: 1000,
534 compressed_size: 600,
535 compression_ratio: 0.4,
536 builtin_count: 50,
537 cache_hit_rate: 0.8,
538 };
539
540 assert_eq!(stats.compression_efficiency(), 0.4);
541 assert_eq!(stats.loading_throughput(), 10000.0); }
543}