use anyhow::Result; use filetree_hybrid::HybridRouter; use std::fs; use std::io::Write; use std::path::Path; use std::time::{Duration, Instant}; struct CopyTestResult { total_files: usize, total_size: u64, copy_time: Duration, throughput: f64, avg_latency: Duration, } impl CopyTestResult { fn print_summary(&self, label: &str) { println!("\n{} Results:", label); println!(" Files copied: {}", self.total_files); println!( " Total size: {:.2} MB", self.total_size as f64 / 1024.0 / 1024.0 ); println!(" Copy time: {:?}", self.copy_time); println!(" Throughput: {:.2} MB/sec", self.throughput); println!(" Avg latency: {:?}", self.avg_latency); } } fn main() -> Result<()> { println!("=== Large File Copy Performance Test ===\n"); println!("Configuration:"); println!(" Test files: 100"); println!(" File size: 10MB each (total ~1GB)"); println!(" Test 1: Traditional std::fs::copy"); println!(" Test 2: Hybrid Architecture (Smart Warmup)"); println!(" Test 3: Repeated Copy (Cache Hit Benefit)"); println!("\n=== Phase 1: Prepare Large Files ==="); let test_dir = "/tmp/large_copy_test_source"; let target_traditional = "/tmp/large_copy_test_traditional"; let target_hybrid = "/tmp/large_copy_test_hybrid"; println!("\nStep 1: Create large test files (10MB each)..."); create_large_test_files(test_dir, 100, 10)?; let test_files = collect_test_files(test_dir)?; println!(" ✓ Created {} large files", test_files.len()); println!("\n=== Phase 2: Traditional Large File Copy ==="); fs::create_dir_all(target_traditional)?; let traditional_result = test_traditional_copy(&test_files, target_traditional)?; traditional_result.print_summary("Traditional Large File Copy"); println!("\n=== Phase 3: Hybrid Large File Copy (Smart Warmup) ==="); println!("\nStep 2: Initialize Hybrid Router..."); let router = HybridRouter::init_user_db("large_copy_test")?; println!("\nStep 3: Smart Warmup (only top 10 hot files)..."); let warmup_start = Instant::now(); // Smart warmup: only warmup top 10 files (not all 100) for (idx, file_path) in test_files.iter().enumerate().take(10) { let file_name = file_path.file_name().unwrap().to_str().unwrap(); let node = HybridRouter::new_folder(file_name, None); router.insert_node(&node)?; if idx % 10 == 0 { println!(" Warmup progress: {}/10 hot files", idx); } } let warmup_time = warmup_start.elapsed(); println!(" ✓ Smart warmup time: {:?}", warmup_time); println!(" (vs previous 346ms for 1000 files)"); println!( " Reduction: {:.1}x faster warmup", 346.0 / warmup_time.as_millis() as f64 ); println!("\nStep 4: Hybrid Large File Copy..."); fs::create_dir_all(target_hybrid)?; let hybrid_start = Instant::now(); let mut copied_files = 0; let mut total_bytes = 0; let mut cache_hits = 0; for (idx, src_file) in test_files.iter().enumerate() { let file_name = src_file.file_name().unwrap().to_str().unwrap(); // Hybrid copy with cache lookup if router.get_node(&file_name.replace(".", ""))?.is_some() { cache_hits += 1; } let target_file = Path::new(target_hybrid).join(file_name); let file_size = src_file.metadata()?.len(); fs::copy(src_file, &target_file)?; copied_files += 1; total_bytes += file_size; if idx % 20 == 0 { println!(" Copy progress: {}/100 files", idx); } } let hybrid_time = hybrid_start.elapsed(); let hybrid_result = CopyTestResult { total_files: copied_files, total_size: total_bytes, copy_time: hybrid_time, throughput: total_bytes as f64 / hybrid_time.as_secs_f64(), avg_latency: hybrid_time / copied_files as u32, }; hybrid_result.print_summary("Hybrid Large File Copy (Smart Warmup)"); println!("\n Cache statistics:"); println!(" Cache hits: {}", cache_hits); println!( " Cache hit rate: {:.1}%", cache_hits as f64 / copied_files as f64 * 100.0 ); println!("\n=== Phase 4: Repeated Copy Test (Cache Benefit) ==="); println!("\nTest repeated copy of same file (10 times):"); let test_file = &test_files[0]; let file_name = test_file.file_name().unwrap().to_str().unwrap(); // First, add to cache let node = HybridRouter::new_folder(file_name, None); router.insert_node(&node)?; let mut copy_times = Vec::new(); for i in 0..10 { let target_file = Path::new(target_hybrid).join(format!("repeat_{}.dat", i)); let start = Instant::now(); fs::copy(test_file, &target_file)?; let elapsed = start.elapsed(); copy_times.push(elapsed); if i < 5 || i == 9 { println!(" Copy {}: {:?}", i, elapsed); } } println!("\nRepeated copy analysis:"); println!(" First copy: {:?}", copy_times[0]); println!(" Avg subsequent copies: {:?}", { let sum: Duration = copy_times[1..].iter().sum(); sum / (copy_times.len() - 1) as u32 }); let first_copy_ns = copy_times[0].as_nanos(); let avg_subsequent_ns = copy_times[1..].iter().map(|d| d.as_nanos()).sum::() / (copy_times.len() - 1) as u128; if first_copy_ns > avg_subsequent_ns { let speedup = first_copy_ns as f64 / avg_subsequent_ns as f64; println!(" Speedup: {:.2}x faster after first copy", speedup); } println!("\n=== Phase 5: Performance Comparison ==="); println!("\nComparison Table:"); println!("┌─────────────────────────────────────────┐"); println!("│ Metric │ Traditional │ Hybrid │"); println!("├─────────────────────────────────────────┤"); println!( "│ Copy time │ {:?} │ {:?} │", traditional_result.copy_time, hybrid_result.copy_time ); println!("│ Warmup overhead │ 0ms │ {:?} │", warmup_time); println!( "│ Total time │ {:?} │ {:?} │", traditional_result.copy_time, hybrid_time + warmup_time ); println!( "│ Throughput │ {:.2} MB/s │ {:.2} MB/s │", traditional_result.throughput / 1024.0 / 1024.0, hybrid_result.throughput / 1024.0 / 1024.0 ); println!( "│ Avg latency │ {:?} │ {:?} │", traditional_result.avg_latency, hybrid_result.avg_latency ); println!("└─────────────────────────────────────────┘"); let total_traditional = traditional_result.copy_time; let total_hybrid = hybrid_time + warmup_time; let speedup = total_traditional.as_nanos() as f64 / total_hybrid.as_nanos() as f64; println!("\nOverall Speedup: {:.2}x", speedup); if speedup > 1.5 { println!("\n✅ SIGNIFICANT IMPROVEMENT!"); println!( " Hybrid architecture with smart warmup significantly improves large file copy." ); } else if speedup > 1.1 { println!("\n✅ MODERATE IMPROVEMENT!"); println!(" Hybrid architecture provides moderate improvement for large files."); } else { println!("\n⚠️ NO IMPROVEMENT"); println!(" Further optimizations needed:"); println!(" - Batch copy operations"); println!(" - Parallel copy threads"); println!(" - Cache hit optimization"); } println!("\n=== Phase 6: Cleanup ==="); fs::remove_dir_all(test_dir)?; fs::remove_dir_all(target_traditional)?; fs::remove_dir_all(target_hybrid)?; let db_path = HybridRouter::user_db_path("large_copy_test"); let sqlite_path = format!("{}.sqlite", db_path); let sled_path = format!("{}.sled", db_path); fs::remove_file(&sqlite_path)?; fs::remove_dir_all(&sled_path)?; println!(" ✓ Test environment cleaned up"); println!("\n✅ Large File Copy Test completed successfully!"); Ok(()) } fn create_large_test_files(dir: &str, count: usize, size_mb: usize) -> Result<()> { fs::create_dir_all(dir)?; println!(" Creating {} large files ({}MB each)...", count, size_mb); for i in 0..count { let file_path = Path::new(dir).join(format!("large_file_{:05}.dat", i)); let mut file = fs::File::create(&file_path)?; // Write specified size of data let size_bytes = size_mb * 1024 * 1024; let chunk_size = 1024 * 1024; // 1MB chunks let data = vec![0u8; chunk_size]; for _ in 0..(size_bytes / chunk_size) { file.write_all(&data)?; } if i % 20 == 0 { println!(" Progress: {}/{} files created", i, count); } } Ok(()) } fn collect_test_files(dir: &str) -> Result> { let mut files = Vec::new(); for entry in fs::read_dir(dir)? { let entry = entry?; if entry.file_type()?.is_file() { files.push(entry.path()); } } Ok(files) } fn test_traditional_copy(files: &[std::path::PathBuf], target: &str) -> Result { let start = Instant::now(); let mut copied_files = 0; let mut total_bytes = 0; for (idx, src_file) in files.iter().enumerate() { let file_name = src_file.file_name().unwrap().to_str().unwrap(); let target_file = Path::new(target).join(file_name); let file_size = src_file.metadata()?.len(); fs::copy(src_file, &target_file)?; copied_files += 1; total_bytes += file_size; if idx % 20 == 0 { println!(" Copy progress: {}/{} files", idx, files.len()); } } let elapsed = start.elapsed(); Ok(CopyTestResult { total_files: copied_files, total_size: total_bytes, copy_time: elapsed, throughput: total_bytes as f64 / elapsed.as_secs_f64(), avg_latency: elapsed / copied_files as u32, }) }