use anyhow::Result; 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!("=== Multi-File Copy Performance Test ===\n"); println!("Configuration:"); println!(" Test files: 10,000"); println!(" File size: 1KB each (total ~10MB)"); println!(" Test 1: Traditional std::fs::copy"); println!(" Test 2: Hybrid Architecture + Cache Warmup"); println!(" Test 3: Comparison Analysis"); println!("\n=== Phase 1: Prepare Test Environment ==="); let test_dir = "/tmp/copy_test_source"; let target_traditional = "/tmp/copy_test_traditional"; let target_hybrid = "/tmp/copy_test_hybrid"; println!("\nStep 1: Create test files..."); create_test_files(test_dir, 10000)?; let test_files = collect_test_files(test_dir)?; println!(" ✓ Created {} test files", test_files.len()); println!("\n=== Phase 2: Traditional Copy Test ==="); fs::create_dir_all(target_traditional)?; let traditional_result = test_traditional_copy(&test_files, target_traditional)?; traditional_result.print_summary("Traditional std::fs::copy"); println!("\n=== Phase 3: Hybrid Copy Test (with Prepare) ==="); println!("\nStep 2: Initialize Hybrid Router..."); use filetree_hybrid::HybridRouter; let router = HybridRouter::init_user_db("copy_test")?; println!("\nStep 3: Prepare - Cache Warmup..."); let warmup_start = Instant::now(); for (idx, file_path) in test_files.iter().enumerate().take(1000) { let file_name = file_path.file_name().unwrap().to_str().unwrap(); let node = filetree_hybrid::HybridRouter::new_folder(file_name, None); router.insert_node(&node)?; if idx % 100 == 0 { println!(" Warmup progress: {}/1000 files", idx); } } let warmup_time = warmup_start.elapsed(); println!(" ✓ Cache warmed up: {:?}", warmup_time); println!("\nStep 4: Hybrid Copy (with cache lookup)..."); fs::create_dir_all(target_hybrid)?; let hybrid_start = Instant::now(); let mut copied_files = 0; let mut total_bytes = 0; for (idx, src_file) in test_files.iter().enumerate() { let file_name = src_file.file_name().unwrap().to_str().unwrap(); if let Some(_cache) = router.get_node(&file_name.replace(".", ""))? { 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; } else { let target_file = Path::new(target_hybrid).join(file_name); fs::copy(src_file, &target_file)?; copied_files += 1; total_bytes += src_file.metadata()?.len(); } if idx % 1000 == 0 { println!(" Copy progress: {}/10000 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 Copy (with Prepare)"); println!("\n=== Phase 4: Performance Comparison ==="); println!("\nComparison Table:"); println!("┌─────────────────────────────────────────┐"); println!("│ Metric │ Traditional │ Hybrid │"); println!("├─────────────────────────────────────────┤"); println!( "│ Copy time │ {:?} │ {:?} │", traditional_result.copy_time, hybrid_result.copy_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!( "│ Speedup │ 1.00x │ {:.2}x │", traditional_result.copy_time.as_nanos() as f64 / hybrid_result.copy_time.as_nanos() as f64 ); println!("└─────────────────────────────────────────┘"); let speedup = traditional_result.copy_time.as_nanos() as f64 / hybrid_result.copy_time.as_nanos() as f64; if speedup > 1.5 { println!("\n✅ SIGNIFICANT IMPROVEMENT: {:.2}x faster!", speedup); println!(" Hybrid architecture significantly improves multi-file copy performance."); } else if speedup > 1.1 { println!("\n✅ MODERATE IMPROVEMENT: {:.2}x faster", speedup); println!(" Hybrid architecture provides moderate improvement."); } else { println!("\n⚠️ NO SIGNIFICANT IMPROVEMENT: {:.2}x", speedup); println!(" Consider further optimizations:"); println!(" - Larger cache warmup (more files)"); println!(" - Batch copy operations"); println!(" - Parallel copy threads"); } println!("\n=== Phase 5: Cleanup ==="); fs::remove_dir_all(test_dir)?; fs::remove_dir_all(target_traditional)?; fs::remove_dir_all(target_hybrid)?; let db_path = filetree_hybrid::HybridRouter::user_db_path("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✅ Multi-File Copy Test completed successfully!"); Ok(()) } fn create_test_files(dir: &str, count: usize) -> Result<()> { fs::create_dir_all(dir)?; for i in 0..count { let file_path = Path::new(dir).join(format!("test_file_{:05}.txt", i)); let mut file = fs::File::create(&file_path)?; let content = format!("Test file {} content\n", i); file.write_all(content.as_bytes())?; if i % 1000 == 0 { println!(" Creating progress: {}/{} files", 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 % 1000 == 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, }) }