1use crate::core::types::TrackingResult;
7use crate::export::data_localizer::{DataGatheringStats, DataLocalizer, LocalizedExportData};
8use crate::export::error_handling::{LogLevel, PerformanceLogger, ResourceMonitor};
9use crate::export::error_recovery::{ErrorContext, ErrorRecoveryManager, RecoveryConfig};
10use crate::export::high_speed_buffered_writer::{
11 HighSpeedBufferedWriter, HighSpeedWriterConfig, WritePerformanceStats,
12};
13use crate::export::parallel_shard_processor::{
14 ParallelProcessingStats, ParallelShardConfig, ParallelShardProcessor,
15};
16use crate::export::progress_monitor::{
17 ExportStage, ProgressCallback, ProgressConfig, ProgressMonitor,
18};
19use crate::export::quality_validator::{
20 AsyncValidator, DeferredValidation, ExportConfig, ExportMode, QualityValidator,
21 ValidationConfig, ValidationTiming,
22};
23use std::path::Path;
24use std::time::Instant;
25
26#[derive(Debug, Clone)]
28pub struct FastExportConfig {
29 pub enable_data_localization: bool,
31 pub data_cache_ttl_ms: u64,
33
34 pub shard_config: ParallelShardConfig,
36
37 pub writer_config: HighSpeedWriterConfig,
39
40 pub enable_performance_monitoring: bool,
42 pub verbose_logging: bool,
44
45 pub progress_config: ProgressConfig,
47
48 pub enable_auto_optimization: bool,
50 pub auto_adjust_for_system: bool,
52
53 pub error_recovery_config: RecoveryConfig,
55 pub validation_config: ValidationConfig,
57 pub enable_resource_monitoring: bool,
59 pub memory_limit_mb: usize,
61 pub disk_limit_mb: usize,
63 pub cpu_limit_percent: f64,
65}
66
67impl Default for FastExportConfig {
68 fn default() -> Self {
69 Self {
70 enable_data_localization: true,
71 data_cache_ttl_ms: 100,
72
73 shard_config: ParallelShardConfig::default(),
74 writer_config: HighSpeedWriterConfig::default(),
75
76 enable_performance_monitoring: true,
77 verbose_logging: false,
78
79 progress_config: ProgressConfig::default(),
80
81 enable_auto_optimization: true,
82 auto_adjust_for_system: true,
83
84 error_recovery_config: RecoveryConfig::default(),
85 validation_config: ValidationConfig::default(),
86 enable_resource_monitoring: true,
87 memory_limit_mb: 1024, disk_limit_mb: 2048, cpu_limit_percent: 80.0, }
91 }
92}
93
94#[derive(Debug, Clone)]
96pub struct CompleteExportStats {
97 pub data_gathering: DataGatheringStats,
99 pub parallel_processing: ParallelProcessingStats,
101 pub write_performance: WritePerformanceStats,
103
104 pub total_export_time_ms: u64,
106 pub total_allocations_processed: usize,
108 pub total_output_size_bytes: usize,
110 pub overall_throughput_allocations_per_sec: f64,
112 pub overall_write_speed_mbps: f64,
114
115 pub data_gathering_percentage: f64,
117 pub processing_percentage: f64,
119 pub writing_percentage: f64,
121
122 pub estimated_traditional_time_ms: u64,
124 pub performance_improvement_factor: f64,
126}
127
128pub struct FastExportCoordinator {
130 config: FastExportConfig,
132 data_localizer: DataLocalizer,
134 shard_processor: ParallelShardProcessor,
136 performance_logger: PerformanceLogger,
138 error_recovery_manager: ErrorRecoveryManager,
140 quality_validator: QualityValidator,
142 async_validator: AsyncValidator,
144 export_config: ExportConfig,
146 resource_monitor: Option<ResourceMonitor>,
148}
149
150impl FastExportCoordinator {
151 pub fn new(config: FastExportConfig) -> Self {
153 let data_localizer = if config.enable_data_localization {
155 DataLocalizer::with_cache_ttl(std::time::Duration::from_millis(
156 config.data_cache_ttl_ms,
157 ))
158 } else {
159 DataLocalizer::new()
160 };
161
162 let shard_processor = ParallelShardProcessor::new(config.shard_config.clone());
164
165 let log_level = if config.verbose_logging {
167 LogLevel::Debug
168 } else {
169 LogLevel::Info
170 };
171 let performance_logger = PerformanceLogger::new(log_level);
172
173 let error_recovery_manager =
175 ErrorRecoveryManager::new(config.error_recovery_config.clone());
176
177 let quality_validator = QualityValidator::new(config.validation_config.clone());
179
180 let resource_monitor = if config.enable_resource_monitoring {
182 Some(ResourceMonitor::new(
183 config.memory_limit_mb,
184 config.disk_limit_mb,
185 config.cpu_limit_percent,
186 ))
187 } else {
188 None
189 };
190
191 let async_validator = AsyncValidator::new(config.validation_config.clone());
193
194 let export_config = ExportConfig::fast();
196
197 Self {
198 config,
199 data_localizer,
200 shard_processor,
201 performance_logger,
202 error_recovery_manager,
203 quality_validator,
204 async_validator,
205 export_config,
206 resource_monitor,
207 }
208 }
209
210 pub fn new_fast_mode() -> Self {
212 let mut config = FastExportConfig::default();
213 config.validation_config.enable_json_validation = false;
215 config.validation_config.enable_encoding_validation = false;
216 config.validation_config.enable_integrity_validation = false;
217 config.verbose_logging = false;
218 Self::new(config)
219 }
220
221 pub fn new_normal_mode() -> Self {
223 let mut config = FastExportConfig::default();
224 config.validation_config.enable_json_validation = true;
226 config.validation_config.enable_encoding_validation = true;
227 config.validation_config.enable_integrity_validation = true;
228 config.verbose_logging = true;
229 Self::new(config)
230 }
231
232 pub fn new_with_export_config(export_config: ExportConfig) -> Self {
234 let verbose_logging = match export_config.mode {
235 ExportMode::Fast => false,
236 ExportMode::Slow => true,
237 ExportMode::Auto => false,
238 };
239
240 let fast_config = FastExportConfig {
241 validation_config: export_config.validation_config.clone(),
242 verbose_logging,
243 ..Default::default()
244 };
245
246 let mut coordinator = Self::new(fast_config);
247 coordinator.export_config = export_config;
248 coordinator
249 }
250
251 pub async fn export_without_validation<P: AsRef<Path>>(
253 &mut self,
254 output_path: P,
255 ) -> TrackingResult<CompleteExportStats> {
256 let total_start = Instant::now();
258
259 if self.config.verbose_logging {
260 tracing::info!("🚀 Starting export mode without validation");
261 }
262
263 let (localized_data, data_stats) = self.gather_data()?;
265
266 let (processed_shards, processing_stats) = self.process_data_parallel(&localized_data)?;
268
269 let write_stats =
271 self.write_data_fast_without_validation(&output_path, &processed_shards)?;
272
273 let total_time = total_start.elapsed();
274
275 let complete_stats = self.calculate_complete_stats(
277 data_stats,
278 processing_stats,
279 write_stats,
280 total_time.as_millis() as u64,
281 );
282
283 if self.config.verbose_logging {
284 tracing::info!(
285 "✅ Export without validation completed, total time: {:?}",
286 total_time
287 );
288 }
289
290 Ok(complete_stats)
291 }
292
293 pub async fn export_with_mode<P: AsRef<Path>>(
295 &mut self,
296 output_path: P,
297 ) -> TrackingResult<(CompleteExportStats, Option<DeferredValidation>)> {
298 let path = output_path.as_ref();
299
300 if self.export_config.validation_timing == ValidationTiming::Disabled {
301 let stats = self.export_without_validation(path).await?;
303 return Ok((stats, None));
304 }
305
306 match (
307 &self.export_config.mode,
308 &self.export_config.validation_timing,
309 ) {
310 (ExportMode::Fast, _) => {
311 let stats = self.export_without_validation(path).await?;
313
314 let deferred_validation =
315 if self.export_config.validation_timing == ValidationTiming::Deferred {
316 Some(
317 self.create_deferred_validation(
318 path,
319 stats.parallel_processing.total_allocations,
320 )
321 .await?,
322 )
323 } else {
324 None
325 };
326
327 Ok((stats, deferred_validation))
328 }
329 (ExportMode::Slow, ValidationTiming::Inline) => {
330 let stats = self.export_with_inline_validation(path).await?;
332 Ok((stats, None))
333 }
334 (ExportMode::Slow, ValidationTiming::Deferred)
335 | (ExportMode::Auto, ValidationTiming::Deferred) => {
336 let stats = self.export_without_validation(path).await?;
338 let deferred_validation = self
339 .create_deferred_validation(path, stats.parallel_processing.total_allocations)
340 .await?;
341 Ok((stats, Some(deferred_validation)))
342 }
343 _ => {
344 let stats = self.export_without_validation(path).await?;
346 Ok((stats, None))
347 }
348 }
349 }
350
351 async fn create_deferred_validation<P: AsRef<Path>>(
353 &mut self,
354 file_path: P,
355 expected_count: usize,
356 ) -> TrackingResult<DeferredValidation> {
357 let deferred_validation = DeferredValidation::new(
359 &file_path,
360 expected_count,
361 self.export_config.validation_config.clone(),
362 );
363
364 Ok(deferred_validation)
365 }
366
367 async fn export_with_inline_validation<P: AsRef<Path>>(
369 &mut self,
370 output_path: P,
371 ) -> TrackingResult<CompleteExportStats> {
372 let total_start = std::time::Instant::now();
373
374 if self.config.verbose_logging {
375 tracing::info!("🚀 Starting export with inline validation");
376 }
377
378 let (localized_data, data_stats) = self.gather_data()?;
380
381 if self
383 .export_config
384 .validation_config
385 .enable_integrity_validation
386 {
387 let validation_result = self
388 .quality_validator
389 .validate_source_data(&localized_data)?;
390 if !validation_result.is_valid && self.config.verbose_logging {
391 tracing::info!(
392 "⚠️ Source data validation failed: {}",
393 validation_result.message
394 );
395 }
396 }
397
398 let (processed_shards, processing_stats) = self.process_data_parallel(&localized_data)?;
400
401 if self.export_config.validation_config.enable_json_validation {
403 let validation_result = self
404 .quality_validator
405 .validate_processed_shards(&processed_shards, localized_data.allocations.len())?;
406 if !validation_result.is_valid && self.config.verbose_logging {
407 tracing::info!(
408 "⚠️ Processed shard validation failed: {}",
409 validation_result.message
410 );
411 }
412 }
413
414 let write_stats =
416 self.write_data_fast_without_validation(&output_path, &processed_shards)?;
417
418 if self.export_config.validation_config.enable_size_validation {
420 let validation_result = self.quality_validator.validate_output_file(
421 &output_path.as_ref().to_string_lossy(),
422 localized_data.allocations.len(),
423 )?;
424 if !validation_result.is_valid && self.config.verbose_logging {
425 tracing::info!(
426 "⚠️ Output file validation failed: {}",
427 validation_result.message
428 );
429 }
430 }
431
432 let total_time = total_start.elapsed();
433
434 let complete_stats = self.calculate_complete_stats(
436 data_stats,
437 processing_stats,
438 write_stats,
439 total_time.as_millis() as u64,
440 );
441
442 if self.config.verbose_logging {
443 tracing::info!(
444 "✅ Export with inline validation completed, total time: {:?}",
445 total_time
446 );
447 }
448
449 Ok(complete_stats)
450 }
451
452 pub fn export_fast<P: AsRef<Path>>(
454 &mut self,
455 output_path: P,
456 ) -> TrackingResult<CompleteExportStats> {
457 self.export_fast_with_progress(output_path, None)
458 }
459
460 pub fn export_fast_with_progress<P: AsRef<Path>>(
462 &mut self,
463 output_path: P,
464 progress_callback: Option<ProgressCallback>,
465 ) -> TrackingResult<CompleteExportStats> {
466 let total_start = Instant::now();
467 let operation_id = format!(
468 "export_{}",
469 std::time::SystemTime::now()
470 .duration_since(std::time::UNIX_EPOCH)
471 .unwrap_or_default()
472 .as_secs()
473 );
474
475 self.performance_logger.log_operation_start(
477 "fast_export",
478 &format!("Output path: {}", output_path.as_ref().display()),
479 );
480
481 if self.config.verbose_logging {
482 tracing::info!("🚀 Fast export coordinator starting execution");
483 tracing::info!(" Output path: {}", output_path.as_ref().display());
484 tracing::info!(" Operation ID: {}", operation_id);
485 }
486
487 let mut error_context = ErrorContext {
489 current_config: self.config.clone(),
490 progress_percentage: 0.0,
491 processed_data_size: 0,
492 operation_start_time: total_start,
493 current_stats: None,
494 };
495
496 let mut progress_monitor = if self.config.progress_config.enabled {
498 Some(ProgressMonitor::new(1000)) } else {
500 None
501 };
502
503 if let Some(ref mut monitor) = progress_monitor {
505 monitor.set_stage(ExportStage::Initializing);
506 }
507
508 if let Some(ref monitor) = self.resource_monitor {
510 if let Err(e) = monitor.check_resource_usage() {
511 let export_error =
512 crate::export::error_handling::ExportError::InsufficientResources {
513 required_memory: 0,
514 available_memory: 0,
515 required_disk: 0,
516 available_disk: 0,
517 };
518 self.performance_logger.log_error(&export_error);
519 return Err(e);
520 }
521 }
522
523 error_context.progress_percentage = 10.0;
525 if let Some(ref mut monitor) = progress_monitor {
526 monitor.set_stage(ExportStage::DataLocalization);
527 if monitor.should_cancel() {
528 monitor.cancel();
529 return Err(std::io::Error::new(
530 std::io::ErrorKind::Interrupted,
531 "Export cancelled during data localization",
532 )
533 .into());
534 }
535 }
536
537 let (localized_data, data_stats) = match self
538 .gather_data_with_progress(progress_monitor.as_mut())
539 {
540 Ok(result) => result,
541 Err(e) => {
542 let export_error = crate::export::error_handling::ExportError::DataQualityError {
543 validation_type: crate::export::error_handling::ValidationType::DataIntegrity,
544 expected: "valid data".to_string(),
545 actual: "error occurred".to_string(),
546 affected_records: 0,
547 };
548 self.performance_logger.log_operation_failure(
549 "fast_export",
550 &export_error,
551 total_start.elapsed(),
552 );
553
554 if let Ok(recovery_result) = self.error_recovery_manager.handle_export_error(
556 &export_error,
557 "data_localization",
558 &error_context,
559 ) {
560 if recovery_result.success {
561 self.performance_logger.log_debug("data localization error recovery successful, still returning original error");
562 }
563 }
564
565 return Err(e);
566 }
567 };
568
569 if let Err(validation_error) = self.quality_validator.validate_source_data(&localized_data)
571 {
572 self.performance_logger.log_warning(&format!(
573 "Data quality validation failed: {validation_error}"
574 ));
575 }
576
577 error_context.processed_data_size = localized_data.allocations.len();
579 error_context.progress_percentage = 30.0;
580
581 if let Some(ref mut monitor) = progress_monitor {
583 let mut new_monitor = ProgressMonitor::new(localized_data.allocations.len());
584 if let Some(callback) = progress_callback {
585 new_monitor.set_callback(callback);
586 }
587 *monitor = new_monitor;
588 }
589
590 error_context.progress_percentage = 50.0;
592 if let Some(ref mut monitor) = progress_monitor {
593 monitor.set_stage(ExportStage::ParallelProcessing);
594 if monitor.should_cancel() {
595 monitor.cancel();
596 return Err(std::io::Error::new(
597 std::io::ErrorKind::Interrupted,
598 "Export cancelled during parallel processing",
599 )
600 .into());
601 }
602 }
603
604 let (processed_shards, processing_stats) = match self
605 .process_data_parallel_with_progress(&localized_data, progress_monitor.as_mut())
606 {
607 Ok(result) => result,
608 Err(e) => {
609 let export_error =
610 crate::export::error_handling::ExportError::ParallelProcessingError {
611 shard_index: 0,
612 thread_id: "unknown".to_string(),
613 error_message: e.to_string(),
614 partial_results: None,
615 };
616 self.performance_logger.log_operation_failure(
617 "fast_export",
618 &export_error,
619 total_start.elapsed(),
620 );
621
622 if let Ok(recovery_result) = self.error_recovery_manager.handle_export_error(
624 &export_error,
625 "parallel_processing",
626 &error_context,
627 ) {
628 if recovery_result.success {
629 self.performance_logger.log_debug("Parallel processing error recovery successful, but still returning original error");
630 }
631 }
632
633 return Err(e);
634 }
635 };
636
637 if let Err(validation_error) = self
639 .quality_validator
640 .validate_processed_shards(&processed_shards, localized_data.allocations.len())
641 {
642 self.performance_logger.log_warning(&format!(
643 "Processed shards validation failed: {validation_error}"
644 ));
645 }
646
647 error_context.progress_percentage = 80.0;
649 if let Some(ref mut monitor) = progress_monitor {
650 monitor.set_stage(ExportStage::Writing);
651 if monitor.should_cancel() {
652 monitor.cancel();
653 return Err(std::io::Error::new(
654 std::io::ErrorKind::Interrupted,
655 "Export cancelled during writing",
656 )
657 .into());
658 }
659 }
660
661 let write_stats = match self.write_data_fast_with_progress(
662 &output_path,
663 &processed_shards,
664 progress_monitor.as_mut(),
665 ) {
666 Ok(result) => result,
667 Err(e) => {
668 let export_error = crate::export::error_handling::ExportError::DataQualityError {
669 validation_type: crate::export::error_handling::ValidationType::FileSize,
670 expected: "successful write".to_string(),
671 actual: "write failed".to_string(),
672 affected_records: 0,
673 };
674 self.performance_logger.log_operation_failure(
675 "fast_export",
676 &export_error,
677 total_start.elapsed(),
678 );
679
680 if let Ok(recovery_result) = self.error_recovery_manager.handle_export_error(
682 &export_error,
683 "high_speed_writing",
684 &error_context,
685 ) {
686 if recovery_result.success {
687 self.performance_logger.log_debug("High-speed writing error recovery successful, but still returning original error");
688 }
689 }
690
691 return Err(e);
692 }
693 };
694
695 let total_time = total_start.elapsed();
696
697 if let Err(validation_error) = self.quality_validator.validate_output_file(
699 output_path.as_ref().to_str().unwrap_or("unknown"),
700 localized_data.allocations.len(),
701 ) {
702 self.performance_logger.log_warning(&format!(
703 "Output file validation failed: {validation_error}"
704 ));
705 }
706
707 if let Some(ref mut monitor) = progress_monitor {
709 monitor.complete();
710 }
711
712 let complete_stats = self.calculate_complete_stats(
714 data_stats,
715 processing_stats,
716 write_stats,
717 total_time.as_millis() as u64,
718 );
719
720 self.performance_logger.log_operation_success(
722 "fast_export",
723 total_time,
724 &format!(
725 "Successfully exported {} allocations",
726 complete_stats.total_allocations_processed
727 ),
728 );
729
730 self.performance_logger.log_performance_metric(
732 crate::export::error_handling::PerformanceMetric::ExportTime,
733 total_time.as_millis() as f64,
734 Some(5000.0), );
736
737 self.performance_logger.log_performance_metric(
738 crate::export::error_handling::PerformanceMetric::ThroughputRate,
739 complete_stats.overall_throughput_allocations_per_sec,
740 Some(1000.0), );
742
743 if self.config.enable_performance_monitoring {
744 self.print_complete_stats(&complete_stats);
745
746 let performance_report = self.performance_logger.generate_performance_report();
748 performance_report.print_detailed_report();
749
750 let recovery_report = self.error_recovery_manager.generate_recovery_report();
751 if recovery_report.total_errors > 0 {
752 recovery_report.print_detailed_report();
753 }
754
755 let validation_report = self.quality_validator.generate_validation_report();
756 validation_report.print_detailed_report();
757 }
758
759 Ok(complete_stats)
760 }
761
762 fn gather_data(&mut self) -> TrackingResult<(LocalizedExportData, DataGatheringStats)> {
764 self.gather_data_with_progress(None)
765 }
766
767 fn gather_data_with_progress(
769 &mut self,
770 mut progress_monitor: Option<&mut ProgressMonitor>,
771 ) -> TrackingResult<(LocalizedExportData, DataGatheringStats)> {
772 let stage_start = Instant::now();
773
774 if self.config.verbose_logging {
775 tracing::info!("📊 Stage 1: Data localization");
776 }
777
778 if let Some(ref mut monitor) = progress_monitor {
779 monitor.update_progress(0.1, Some("Starting data localization".to_string()));
780 }
781
782 let result = self.data_localizer.gather_all_export_data()?;
783
784 if let Some(ref mut monitor) = progress_monitor {
785 monitor.update_progress(1.0, Some("Data localization completed".to_string()));
786 }
787
788 if self.config.verbose_logging {
789 tracing::info!(
790 " ✅ Data localization completed, time elapsed: {:?}",
791 stage_start.elapsed()
792 );
793 }
794
795 Ok(result)
796 }
797
798 fn process_data_parallel(
800 &self,
801 data: &LocalizedExportData,
802 ) -> TrackingResult<(
803 Vec<crate::export::parallel_shard_processor::ProcessedShard>,
804 ParallelProcessingStats,
805 )> {
806 self.process_data_parallel_with_progress(data, None)
807 }
808
809 fn process_data_parallel_with_progress(
811 &self,
812 data: &LocalizedExportData,
813 mut progress_monitor: Option<&mut ProgressMonitor>,
814 ) -> TrackingResult<(
815 Vec<crate::export::parallel_shard_processor::ProcessedShard>,
816 ParallelProcessingStats,
817 )> {
818 let stage_start = Instant::now();
819
820 if self.config.verbose_logging {
821 tracing::info!("⚡ Stage 2: Parallel shard processing");
822 }
823
824 if let Some(ref mut monitor) = progress_monitor {
825 monitor.update_progress(0.1, Some("Starting parallel shard processing".to_string()));
826 }
827
828 let result = self.shard_processor.process_allocations_parallel(data)?;
829
830 if let Some(ref mut monitor) = progress_monitor {
831 monitor.update_progress(1.0, Some("Parallel shard processing completed".to_string()));
832 }
833
834 if self.config.verbose_logging {
835 tracing::info!(
836 " ✅ Parallel shard processing completed, time elapsed: {:?}",
837 stage_start.elapsed()
838 );
839 }
840
841 Ok(result)
842 }
843
844 fn write_data_fast_without_validation<P: AsRef<Path>>(
846 &self,
847 output_path: P,
848 shards: &[crate::export::parallel_shard_processor::ProcessedShard],
849 ) -> TrackingResult<WritePerformanceStats> {
850 let stage_start = Instant::now();
851
852 if self.config.verbose_logging {
853 tracing::info!("💾 High-speed write phase (validation skipped)");
854 }
855
856 let total_size: usize = shards.iter().map(|s| s.data.len()).sum();
858 let mut writer_config = self.config.writer_config.clone();
859 writer_config.estimated_total_size = Some(total_size + 1024);
860
861 let mut writer = HighSpeedBufferedWriter::new(output_path, writer_config)?;
862 let result = writer.write_processed_shards(shards)?;
863
864 if self.config.verbose_logging {
865 tracing::info!(
866 " ✅ High-speed write completed (validation skipped), time: {:?}",
867 stage_start.elapsed()
868 );
869 }
870
871 Ok(result)
872 }
873
874 fn write_data_fast_with_progress<P: AsRef<Path>>(
876 &self,
877 output_path: P,
878 shards: &[crate::export::parallel_shard_processor::ProcessedShard],
879 mut progress_monitor: Option<&mut ProgressMonitor>,
880 ) -> TrackingResult<WritePerformanceStats> {
881 let stage_start = Instant::now();
882
883 if self.config.verbose_logging {
884 tracing::info!("💾 Stage 3: High-speed buffered writing");
885 }
886
887 if let Some(ref mut monitor) = progress_monitor {
888 monitor.update_progress(
889 0.1,
890 Some("Starting high-speed buffered writing".to_string()),
891 );
892 }
893
894 let total_size: usize = shards.iter().map(|s| s.data.len()).sum();
896 let mut writer_config = self.config.writer_config.clone();
897 writer_config.estimated_total_size = Some(total_size + 1024);
898
899 let mut writer = HighSpeedBufferedWriter::new(output_path, writer_config)?;
900 let result = writer.write_processed_shards(shards)?;
901
902 if let Some(ref mut monitor) = progress_monitor {
903 monitor.update_progress(
904 1.0,
905 Some("High-speed buffered writing completed".to_string()),
906 );
907 }
908
909 if self.config.verbose_logging {
910 tracing::info!(
911 " ✅ High-speed buffered writing completed, time elapsed: {:?}",
912 stage_start.elapsed()
913 );
914 }
915
916 Ok(result)
917 }
918
919 fn calculate_complete_stats(
921 &self,
922 data_stats: DataGatheringStats,
923 processing_stats: ParallelProcessingStats,
924 write_stats: WritePerformanceStats,
925 total_time_ms: u64,
926 ) -> CompleteExportStats {
927 let total_allocations = processing_stats.total_allocations;
928 let total_output_size = write_stats.total_bytes_written;
929
930 let overall_throughput = if total_time_ms > 0 {
932 (total_allocations as f64 * 1000.0) / total_time_ms as f64
933 } else {
934 0.0
935 };
936
937 let overall_write_speed = if total_time_ms > 0 {
939 (total_output_size as f64 / 1024.0 / 1024.0 * 1000.0) / total_time_ms as f64
940 } else {
941 0.0
942 };
943
944 let data_percentage = if total_time_ms > 0 {
946 (data_stats.total_time_ms as f64 / total_time_ms as f64) * 100.0
947 } else {
948 0.0
949 };
950
951 let processing_percentage = if total_time_ms > 0 {
952 (processing_stats.total_processing_time_ms as f64 / total_time_ms as f64) * 100.0
953 } else {
954 0.0
955 };
956
957 let writing_percentage = if total_time_ms > 0 {
958 (write_stats.total_write_time_ms as f64 / total_time_ms as f64) * 100.0
959 } else {
960 0.0
961 };
962
963 let estimated_traditional_time = total_time_ms * 3; let performance_improvement = if total_time_ms > 0 {
966 estimated_traditional_time as f64 / total_time_ms as f64
967 } else {
968 1.0
969 };
970
971 CompleteExportStats {
972 data_gathering: data_stats,
973 parallel_processing: processing_stats,
974 write_performance: write_stats,
975
976 total_export_time_ms: total_time_ms,
977 total_allocations_processed: total_allocations,
978 total_output_size_bytes: total_output_size,
979 overall_throughput_allocations_per_sec: overall_throughput,
980 overall_write_speed_mbps: overall_write_speed,
981
982 data_gathering_percentage: data_percentage,
983 processing_percentage,
984 writing_percentage,
985
986 estimated_traditional_time_ms: estimated_traditional_time,
987 performance_improvement_factor: performance_improvement,
988 }
989 }
990
991 fn print_complete_stats(&self, stats: &CompleteExportStats) {
993 tracing::info!("\n🎯 Fast export completed - Performance Statistics");
994 tracing::info!("================================");
995
996 tracing::info!("📊 Overall Performance:");
997 tracing::info!(" total_export_time_ms: {}ms", stats.total_export_time_ms);
998 tracing::info!(
999 " total_allocations_processed: {}",
1000 stats.total_allocations_processed
1001 );
1002 tracing::info!(
1003 " total_output_size_bytes: {:.2} MB",
1004 stats.total_output_size_bytes as f64 / 1024.0 / 1024.0
1005 );
1006 tracing::info!(
1007 " overall_throughput_allocations_per_sec: {:.0} allocations/second",
1008 stats.overall_throughput_allocations_per_sec
1009 );
1010 tracing::info!(
1011 " overall_write_speed_mbps: {:.2} MB/s",
1012 stats.overall_write_speed_mbps
1013 );
1014
1015 tracing::info!("\n⏱️ Stage time analysis:");
1016 tracing::info!(
1017 " data_gathering: {}ms ({:.1}%)",
1018 stats.data_gathering.total_time_ms,
1019 stats.data_gathering_percentage
1020 );
1021 tracing::info!(
1022 " parallel_processing: {}ms ({:.1}%)",
1023 stats.parallel_processing.total_processing_time_ms,
1024 stats.processing_percentage
1025 );
1026 tracing::info!(
1027 " write_performance: {}ms ({:.1}%)",
1028 stats.write_performance.total_write_time_ms,
1029 stats.writing_percentage
1030 );
1031
1032 tracing::info!("\n🚀 Performance Improvement:");
1033 tracing::info!(
1034 " estimated_traditional_time_ms: {}ms",
1035 stats.estimated_traditional_time_ms
1036 );
1037 tracing::info!(
1038 " performance_improvement_factor: {:.2}x",
1039 stats.performance_improvement_factor
1040 );
1041 tracing::info!(
1042 " time_saved: {}ms ({:.1}%)",
1043 stats.estimated_traditional_time_ms - stats.total_export_time_ms,
1044 (1.0 - 1.0 / stats.performance_improvement_factor) * 100.0
1045 );
1046
1047 if stats.parallel_processing.used_parallel_processing {
1048 tracing::info!("\n⚡ Parallel Processing Effect:");
1049 tracing::info!(
1050 " threads_used: {}",
1051 stats.parallel_processing.threads_used
1052 );
1053 tracing::info!(
1054 " parallel_efficiency: {:.1}%",
1055 stats.parallel_processing.parallel_efficiency * 100.0
1056 );
1057 tracing::info!(" shard_count: {}", stats.parallel_processing.shard_count);
1058 }
1059
1060 tracing::info!("\n💾 Write Performance:");
1061 tracing::info!(
1062 " buffer_utilization: {:.1}%",
1063 stats.write_performance.buffer_utilization * 100.0
1064 );
1065 tracing::info!(
1066 " preallocation_effective: {}",
1067 stats.write_performance.preallocation_effective
1068 );
1069 tracing::info!(" flush_count: {}", stats.write_performance.flush_count);
1070 }
1071
1072 pub fn get_config(&self) -> &FastExportConfig {
1074 &self.config
1075 }
1076
1077 pub fn get_export_config(&self) -> &ExportConfig {
1079 &self.export_config
1080 }
1081
1082 pub fn update_export_config(&mut self, export_config: ExportConfig) {
1084 self.config.validation_config = export_config.validation_config.clone();
1086
1087 self.async_validator = AsyncValidator::new(export_config.validation_config.clone());
1089
1090 self.export_config = export_config;
1092 }
1093
1094 pub fn update_config(&mut self, config: FastExportConfig) {
1096 self.config = config.clone();
1097
1098 self.data_localizer = if config.enable_data_localization {
1100 DataLocalizer::with_cache_ttl(std::time::Duration::from_millis(
1101 config.data_cache_ttl_ms,
1102 ))
1103 } else {
1104 DataLocalizer::new()
1105 };
1106
1107 self.shard_processor = ParallelShardProcessor::new(config.shard_config.clone());
1108
1109 let log_level = if config.verbose_logging {
1111 LogLevel::Debug
1112 } else {
1113 LogLevel::Info
1114 };
1115 self.performance_logger = PerformanceLogger::new(log_level);
1116
1117 self.error_recovery_manager =
1119 ErrorRecoveryManager::new(config.error_recovery_config.clone());
1120
1121 self.quality_validator = QualityValidator::new(config.validation_config.clone());
1123
1124 self.resource_monitor = if config.enable_resource_monitoring {
1126 Some(ResourceMonitor::new(
1127 config.memory_limit_mb,
1128 config.disk_limit_mb,
1129 config.cpu_limit_percent,
1130 ))
1131 } else {
1132 None
1133 };
1134 }
1135
1136 pub fn get_cache_stats(&self) -> crate::export::data_localizer::CacheStats {
1138 self.data_localizer.get_cache_stats()
1139 }
1140
1141 pub fn clear_cache(&mut self) {
1143 self.data_localizer.invalidate_cache();
1144 }
1145}
1146
1147impl Default for FastExportCoordinator {
1148 fn default() -> Self {
1149 Self::new(FastExportConfig::default())
1150 }
1151}
1152
1153pub fn export_fast<P: AsRef<Path>>(output_path: P) -> TrackingResult<CompleteExportStats> {
1155 let mut coordinator = FastExportCoordinator::default();
1156 coordinator.export_fast(output_path)
1157}
1158
1159pub fn export_fast_with_config<P: AsRef<Path>>(
1161 output_path: P,
1162 config: FastExportConfig,
1163) -> TrackingResult<CompleteExportStats> {
1164 let mut coordinator = FastExportCoordinator::new(config);
1165 coordinator.export_fast(output_path)
1166}
1167
1168pub struct FastExportConfigBuilder {
1170 config: FastExportConfig,
1171}
1172
1173impl FastExportConfigBuilder {
1174 pub fn new() -> Self {
1176 Self {
1177 config: FastExportConfig::default(),
1178 }
1179 }
1180
1181 pub fn data_localization(mut self, enabled: bool) -> Self {
1183 self.config.enable_data_localization = enabled;
1184 self
1185 }
1186
1187 pub fn cache_ttl_ms(mut self, ttl_ms: u64) -> Self {
1189 self.config.data_cache_ttl_ms = ttl_ms;
1190 self
1191 }
1192
1193 pub fn shard_size(mut self, size: usize) -> Self {
1195 self.config.shard_config.shard_size = size;
1196 self
1197 }
1198
1199 pub fn parallel_threshold(mut self, threshold: usize) -> Self {
1201 self.config.shard_config.parallel_threshold = threshold;
1202 self
1203 }
1204
1205 pub fn max_threads(mut self, threads: Option<usize>) -> Self {
1207 self.config.shard_config.max_threads = threads;
1208 self
1209 }
1210
1211 pub fn buffer_size(mut self, size: usize) -> Self {
1213 self.config.writer_config.buffer_size = size;
1214 self
1215 }
1216
1217 pub fn performance_monitoring(mut self, enabled: bool) -> Self {
1219 self.config.enable_performance_monitoring = enabled;
1220 self
1221 }
1222
1223 pub fn verbose_logging(mut self, enabled: bool) -> Self {
1225 self.config.verbose_logging = enabled;
1226 self
1227 }
1228
1229 pub fn progress_config(mut self, config: ProgressConfig) -> Self {
1231 self.config.progress_config = config;
1232 self
1233 }
1234
1235 pub fn progress_monitoring(mut self, enabled: bool) -> Self {
1237 self.config.progress_config.enabled = enabled;
1238 self
1239 }
1240
1241 pub fn error_recovery_config(mut self, config: RecoveryConfig) -> Self {
1243 self.config.error_recovery_config = config;
1244 self
1245 }
1246
1247 pub fn validation_config(mut self, config: ValidationConfig) -> Self {
1249 self.config.validation_config = config;
1250 self
1251 }
1252
1253 pub fn resource_monitoring(mut self, enabled: bool) -> Self {
1255 self.config.enable_resource_monitoring = enabled;
1256 self
1257 }
1258
1259 pub fn memory_limit_mb(mut self, limit: usize) -> Self {
1261 self.config.memory_limit_mb = limit;
1262 self
1263 }
1264
1265 pub fn disk_limit_mb(mut self, limit: usize) -> Self {
1267 self.config.disk_limit_mb = limit;
1268 self
1269 }
1270
1271 pub fn cpu_limit_percent(mut self, limit: f64) -> Self {
1273 self.config.cpu_limit_percent = limit;
1274 self
1275 }
1276
1277 pub fn build(self) -> FastExportConfig {
1279 self.config
1280 }
1281}
1282
1283impl Default for FastExportConfigBuilder {
1284 fn default() -> Self {
1285 Self::new()
1286 }
1287}
1288
1289#[cfg(test)]
1290mod tests {
1291 use super::*;
1292
1293 fn create_test_coordinator() -> FastExportCoordinator {
1294 let config = FastExportConfigBuilder::new()
1295 .data_localization(false) .performance_monitoring(false)
1297 .verbose_logging(false)
1298 .resource_monitoring(false)
1299 .build();
1300 FastExportCoordinator::new(config)
1301 }
1302
1303 #[test]
1304 fn test_fast_export_coordinator_creation() {
1305 let config = FastExportConfig::default();
1306 let coordinator = FastExportCoordinator::new(config);
1307 assert!(coordinator.get_config().enable_data_localization);
1308 assert!(coordinator.get_config().enable_performance_monitoring);
1309 assert!(coordinator.get_config().enable_auto_optimization);
1310 }
1311
1312 #[test]
1313 fn test_fast_export_coordinator_default() {
1314 let coordinator = FastExportCoordinator::default();
1315 assert!(coordinator.get_config().enable_data_localization);
1316 assert!(coordinator.get_config().enable_performance_monitoring);
1317 assert_eq!(coordinator.get_config().data_cache_ttl_ms, 100);
1318 assert_eq!(coordinator.get_config().memory_limit_mb, 1024);
1319 assert_eq!(coordinator.get_config().disk_limit_mb, 2048);
1320 assert_eq!(coordinator.get_config().cpu_limit_percent, 80.0);
1321 }
1322
1323 #[test]
1324 fn test_fast_export_coordinator_fast_mode() {
1325 let coordinator = FastExportCoordinator::new_fast_mode();
1326 let config = coordinator.get_config();
1327
1328 assert!(!config.validation_config.enable_json_validation);
1329 assert!(!config.validation_config.enable_encoding_validation);
1330 assert!(!config.validation_config.enable_integrity_validation);
1331 assert!(!config.verbose_logging);
1332 }
1333
1334 #[test]
1335 fn test_fast_export_coordinator_normal_mode() {
1336 let coordinator = FastExportCoordinator::new_normal_mode();
1337 let config = coordinator.get_config();
1338
1339 assert!(config.validation_config.enable_json_validation);
1340 assert!(config.validation_config.enable_encoding_validation);
1341 assert!(config.validation_config.enable_integrity_validation);
1342 assert!(config.verbose_logging);
1343 }
1344
1345 #[test]
1346 fn test_fast_export_coordinator_with_export_config() {
1347 let export_config = ExportConfig::fast();
1348 let coordinator = FastExportCoordinator::new_with_export_config(export_config.clone());
1349
1350 assert_eq!(coordinator.get_export_config().mode, export_config.mode);
1351 assert!(!coordinator.get_config().verbose_logging); }
1353
1354 #[test]
1355 fn test_fast_export_coordinator_with_slow_export_config() {
1356 let export_config = ExportConfig::slow();
1357 let coordinator = FastExportCoordinator::new_with_export_config(export_config.clone());
1358
1359 assert_eq!(coordinator.get_export_config().mode, export_config.mode);
1360 assert!(coordinator.get_config().verbose_logging); }
1362
1363 #[test]
1364 fn test_fast_export_config_default() {
1365 let config = FastExportConfig::default();
1366
1367 assert!(config.enable_data_localization);
1368 assert_eq!(config.data_cache_ttl_ms, 100);
1369 assert!(config.enable_performance_monitoring);
1370 assert!(!config.verbose_logging);
1371 assert!(config.enable_auto_optimization);
1372 assert!(config.auto_adjust_for_system);
1373 assert!(config.enable_resource_monitoring);
1374 assert_eq!(config.memory_limit_mb, 1024);
1375 assert_eq!(config.disk_limit_mb, 2048);
1376 assert_eq!(config.cpu_limit_percent, 80.0);
1377 }
1378
1379 #[test]
1380 fn test_complete_export_stats_default() {
1381 let stats = CompleteExportStats {
1382 data_gathering: crate::export::data_localizer::DataGatheringStats {
1383 total_time_ms: 100,
1384 basic_data_time_ms: 50,
1385 ffi_data_time_ms: 30,
1386 scope_data_time_ms: 20,
1387 allocation_count: 100,
1388 ffi_allocation_count: 10,
1389 scope_count: 5,
1390 },
1391 parallel_processing: crate::export::parallel_shard_processor::ParallelProcessingStats {
1392 total_allocations: 100,
1393 shard_count: 2,
1394 threads_used: 4,
1395 total_processing_time_ms: 200,
1396 avg_shard_processing_time_ms: 100.0,
1397 parallel_efficiency: 0.8,
1398 throughput_allocations_per_sec: 500.0,
1399 used_parallel_processing: true,
1400 total_output_size_bytes: 50000,
1401 },
1402 write_performance: crate::export::high_speed_buffered_writer::WritePerformanceStats {
1403 total_bytes_written: 50000,
1404 shards_written: 2,
1405 total_write_time_ms: 100,
1406 avg_write_speed_bps: 500000.0,
1407 flush_count: 1,
1408 preallocation_effective: true,
1409 buffer_utilization: 0.8,
1410 },
1411 total_export_time_ms: 1000,
1412 total_allocations_processed: 100,
1413 total_output_size_bytes: 50000,
1414 overall_throughput_allocations_per_sec: 100.0,
1415 overall_write_speed_mbps: 50.0,
1416 data_gathering_percentage: 20.0,
1417 processing_percentage: 50.0,
1418 writing_percentage: 30.0,
1419 estimated_traditional_time_ms: 3000,
1420 performance_improvement_factor: 3.0,
1421 };
1422
1423 assert_eq!(stats.total_export_time_ms, 1000);
1424 assert_eq!(stats.total_allocations_processed, 100);
1425 assert_eq!(stats.performance_improvement_factor, 3.0);
1426 }
1427
1428 #[test]
1429 fn test_config_builder() {
1430 let config = FastExportConfigBuilder::new()
1431 .shard_size(500)
1432 .parallel_threshold(1000)
1433 .buffer_size(1024 * 1024)
1434 .performance_monitoring(false)
1435 .build();
1436
1437 assert_eq!(config.shard_config.shard_size, 500);
1438 assert_eq!(config.shard_config.parallel_threshold, 1000);
1439 assert_eq!(config.writer_config.buffer_size, 1024 * 1024);
1440 assert!(!config.enable_performance_monitoring);
1441 }
1442
1443 #[test]
1444 fn test_config_builder_all_methods() {
1445 let progress_config = ProgressConfig::default();
1446 let recovery_config = RecoveryConfig::default();
1447 let validation_config = ValidationConfig::default();
1448
1449 let config = FastExportConfigBuilder::new()
1450 .data_localization(false)
1451 .cache_ttl_ms(500)
1452 .shard_size(200)
1453 .parallel_threshold(500)
1454 .max_threads(Some(8))
1455 .buffer_size(2 * 1024 * 1024)
1456 .performance_monitoring(true)
1457 .verbose_logging(true)
1458 .progress_config(progress_config.clone())
1459 .progress_monitoring(true)
1460 .error_recovery_config(recovery_config.clone())
1461 .validation_config(validation_config.clone())
1462 .resource_monitoring(true)
1463 .memory_limit_mb(2048)
1464 .disk_limit_mb(4096)
1465 .cpu_limit_percent(90.0)
1466 .build();
1467
1468 assert!(!config.enable_data_localization);
1469 assert_eq!(config.data_cache_ttl_ms, 500);
1470 assert_eq!(config.shard_config.shard_size, 200);
1471 assert_eq!(config.shard_config.parallel_threshold, 500);
1472 assert_eq!(config.shard_config.max_threads, Some(8));
1473 assert_eq!(config.writer_config.buffer_size, 2 * 1024 * 1024);
1474 assert!(config.enable_performance_monitoring);
1475 assert!(config.verbose_logging);
1476 assert!(config.progress_config.enabled);
1477 assert!(config.enable_resource_monitoring);
1478 assert_eq!(config.memory_limit_mb, 2048);
1479 assert_eq!(config.disk_limit_mb, 4096);
1480 assert_eq!(config.cpu_limit_percent, 90.0);
1481 }
1482
1483 #[test]
1484 fn test_config_builder_default() {
1485 let builder1 = FastExportConfigBuilder::new();
1486 let builder2 = FastExportConfigBuilder::default();
1487
1488 let config1 = builder1.build();
1489 let config2 = builder2.build();
1490
1491 assert_eq!(
1492 config1.enable_data_localization,
1493 config2.enable_data_localization
1494 );
1495 assert_eq!(config1.data_cache_ttl_ms, config2.data_cache_ttl_ms);
1496 assert_eq!(
1497 config1.enable_performance_monitoring,
1498 config2.enable_performance_monitoring
1499 );
1500 }
1501
1502 #[test]
1503 fn test_config_update() {
1504 let mut coordinator = FastExportCoordinator::default();
1505
1506 let new_config = FastExportConfigBuilder::new()
1507 .shard_size(200)
1508 .verbose_logging(true)
1509 .data_localization(false)
1510 .performance_monitoring(false)
1511 .build();
1512
1513 coordinator.update_config(new_config);
1514 assert_eq!(coordinator.get_config().shard_config.shard_size, 200);
1515 assert!(coordinator.get_config().verbose_logging);
1516 assert!(!coordinator.get_config().enable_data_localization);
1517 assert!(!coordinator.get_config().enable_performance_monitoring);
1518 }
1519
1520 #[test]
1521 fn test_export_config_update() {
1522 let mut coordinator = FastExportCoordinator::default();
1523 let original_mode = coordinator.get_export_config().mode;
1524
1525 let new_export_config = ExportConfig::slow();
1526 coordinator.update_export_config(new_export_config.clone());
1527
1528 assert_eq!(coordinator.get_export_config().mode, new_export_config.mode);
1529 assert_ne!(coordinator.get_export_config().mode, original_mode);
1530 assert_eq!(
1531 coordinator
1532 .get_config()
1533 .validation_config
1534 .enable_json_validation,
1535 new_export_config.validation_config.enable_json_validation
1536 );
1537 }
1538
1539 #[test]
1540 fn test_cache_operations() {
1541 let mut coordinator = create_test_coordinator();
1542
1543 let cache_stats = coordinator.get_cache_stats();
1545 assert!(!cache_stats.is_cached); coordinator.clear_cache(); let cache_stats_after = coordinator.get_cache_stats();
1552 assert!(!cache_stats_after.is_cached);
1553 }
1554
1555 #[test]
1559 fn test_calculate_complete_stats() {
1560 let coordinator = create_test_coordinator();
1561
1562 let data_stats = crate::export::data_localizer::DataGatheringStats {
1563 total_time_ms: 100,
1564 basic_data_time_ms: 40,
1565 ffi_data_time_ms: 30,
1566 scope_data_time_ms: 30,
1567 allocation_count: 50,
1568 ffi_allocation_count: 5,
1569 scope_count: 3,
1570 };
1571
1572 let processing_stats = crate::export::parallel_shard_processor::ParallelProcessingStats {
1573 total_processing_time_ms: 200,
1574 total_allocations: 50,
1575 shard_count: 4,
1576 threads_used: 4,
1577 parallel_efficiency: 0.8,
1578 used_parallel_processing: true,
1579 avg_shard_processing_time_ms: 50.0,
1580 throughput_allocations_per_sec: 250.0,
1581 total_output_size_bytes: 10000,
1582 };
1583
1584 let write_stats = crate::export::high_speed_buffered_writer::WritePerformanceStats {
1585 total_write_time_ms: 150,
1586 total_bytes_written: 10000,
1587 buffer_utilization: 0.75,
1588 preallocation_effective: true,
1589 flush_count: 3,
1590 avg_write_speed_bps: 66670.0,
1591 shards_written: 4,
1592 };
1593
1594 let total_time_ms = 500;
1595
1596 let complete_stats = coordinator.calculate_complete_stats(
1597 data_stats,
1598 processing_stats,
1599 write_stats,
1600 total_time_ms,
1601 );
1602
1603 assert_eq!(complete_stats.total_export_time_ms, 500);
1604 assert_eq!(complete_stats.total_allocations_processed, 50);
1605 assert_eq!(complete_stats.total_output_size_bytes, 10000);
1606 assert_eq!(complete_stats.overall_throughput_allocations_per_sec, 100.0); assert_eq!(complete_stats.overall_write_speed_mbps, 0.019073486328125); assert_eq!(complete_stats.data_gathering_percentage, 20.0); assert_eq!(complete_stats.processing_percentage, 40.0); assert_eq!(complete_stats.writing_percentage, 30.0); assert_eq!(complete_stats.estimated_traditional_time_ms, 1500); assert_eq!(complete_stats.performance_improvement_factor, 3.0); }
1614
1615 #[test]
1616 fn test_calculate_complete_stats_zero_time() {
1617 let coordinator = create_test_coordinator();
1618
1619 let data_stats = crate::export::data_localizer::DataGatheringStats {
1620 total_time_ms: 0,
1621 basic_data_time_ms: 0,
1622 ffi_data_time_ms: 0,
1623 scope_data_time_ms: 0,
1624 allocation_count: 0,
1625 ffi_allocation_count: 0,
1626 scope_count: 0,
1627 };
1628 let processing_stats = crate::export::parallel_shard_processor::ParallelProcessingStats {
1629 total_allocations: 0,
1630 shard_count: 0,
1631 threads_used: 1,
1632 total_processing_time_ms: 0,
1633 avg_shard_processing_time_ms: 0.0,
1634 parallel_efficiency: 1.0,
1635 throughput_allocations_per_sec: 0.0,
1636 used_parallel_processing: false,
1637 total_output_size_bytes: 0,
1638 };
1639 let write_stats = crate::export::high_speed_buffered_writer::WritePerformanceStats {
1640 total_bytes_written: 0,
1641 shards_written: 0,
1642 total_write_time_ms: 0,
1643 avg_write_speed_bps: 0.0,
1644 flush_count: 0,
1645 preallocation_effective: false,
1646 buffer_utilization: 0.0,
1647 };
1648
1649 let complete_stats = coordinator.calculate_complete_stats(
1650 data_stats,
1651 processing_stats,
1652 write_stats,
1653 0, );
1655
1656 assert_eq!(complete_stats.total_export_time_ms, 0);
1657 assert_eq!(complete_stats.overall_throughput_allocations_per_sec, 0.0);
1658 assert_eq!(complete_stats.overall_write_speed_mbps, 0.0);
1659 assert_eq!(complete_stats.data_gathering_percentage, 0.0);
1660 assert_eq!(complete_stats.processing_percentage, 0.0);
1661 assert_eq!(complete_stats.writing_percentage, 0.0);
1662 assert_eq!(complete_stats.performance_improvement_factor, 1.0);
1663 }
1664
1665 #[test]
1666 fn test_print_complete_stats() {
1667 let coordinator = create_test_coordinator();
1668
1669 let stats = CompleteExportStats {
1670 data_gathering: crate::export::data_localizer::DataGatheringStats {
1671 total_time_ms: 200,
1672 basic_data_time_ms: 100,
1673 ffi_data_time_ms: 50,
1674 scope_data_time_ms: 50,
1675 allocation_count: 1000,
1676 ffi_allocation_count: 100,
1677 scope_count: 10,
1678 },
1679 parallel_processing: crate::export::parallel_shard_processor::ParallelProcessingStats {
1680 total_allocations: 1000,
1681 shard_count: 8,
1682 threads_used: 4,
1683 total_processing_time_ms: 500,
1684 avg_shard_processing_time_ms: 62.5,
1685 parallel_efficiency: 0.85,
1686 throughput_allocations_per_sec: 2000.0,
1687 used_parallel_processing: true,
1688 total_output_size_bytes: 1024 * 1024,
1689 },
1690 write_performance: crate::export::high_speed_buffered_writer::WritePerformanceStats {
1691 total_bytes_written: 1024 * 1024,
1692 shards_written: 8,
1693 total_write_time_ms: 300,
1694 avg_write_speed_bps: 3500000.0,
1695 flush_count: 5,
1696 preallocation_effective: true,
1697 buffer_utilization: 0.9,
1698 },
1699 total_export_time_ms: 1000,
1700 total_allocations_processed: 1000,
1701 total_output_size_bytes: 1024 * 1024, overall_throughput_allocations_per_sec: 1000.0,
1703 overall_write_speed_mbps: 1.0,
1704 data_gathering_percentage: 20.0,
1705 processing_percentage: 50.0,
1706 writing_percentage: 30.0,
1707 estimated_traditional_time_ms: 3000,
1708 performance_improvement_factor: 3.0,
1709 };
1710
1711 coordinator.print_complete_stats(&stats);
1713 }
1714
1715 #[test]
1716 fn test_debug_implementations() {
1717 let config = FastExportConfig::default();
1718 let debug_str = format!("{:?}", config);
1719 assert!(debug_str.contains("FastExportConfig"));
1720
1721 let stats = CompleteExportStats {
1722 data_gathering: crate::export::data_localizer::DataGatheringStats {
1723 total_time_ms: 100,
1724 basic_data_time_ms: 50,
1725 ffi_data_time_ms: 30,
1726 scope_data_time_ms: 20,
1727 allocation_count: 100,
1728 ffi_allocation_count: 10,
1729 scope_count: 5,
1730 },
1731 parallel_processing: crate::export::parallel_shard_processor::ParallelProcessingStats {
1732 total_allocations: 100,
1733 shard_count: 2,
1734 threads_used: 4,
1735 total_processing_time_ms: 500,
1736 avg_shard_processing_time_ms: 250.0,
1737 parallel_efficiency: 0.8,
1738 throughput_allocations_per_sec: 200.0,
1739 used_parallel_processing: true,
1740 total_output_size_bytes: 50000,
1741 },
1742 write_performance: crate::export::high_speed_buffered_writer::WritePerformanceStats {
1743 total_bytes_written: 50000,
1744 shards_written: 2,
1745 total_write_time_ms: 300,
1746 avg_write_speed_bps: 166666.0,
1747 flush_count: 1,
1748 preallocation_effective: true,
1749 buffer_utilization: 0.7,
1750 },
1751 total_export_time_ms: 1000,
1752 total_allocations_processed: 100,
1753 total_output_size_bytes: 50000,
1754 overall_throughput_allocations_per_sec: 100.0,
1755 overall_write_speed_mbps: 50.0,
1756 data_gathering_percentage: 20.0,
1757 processing_percentage: 50.0,
1758 writing_percentage: 30.0,
1759 estimated_traditional_time_ms: 3000,
1760 performance_improvement_factor: 3.0,
1761 };
1762 let debug_str = format!("{:?}", stats);
1763 assert!(debug_str.contains("CompleteExportStats"));
1764 }
1765
1766 #[test]
1767 fn test_clone_implementations() {
1768 let config = FastExportConfig::default();
1769 let cloned_config = config.clone();
1770 assert_eq!(
1771 config.enable_data_localization,
1772 cloned_config.enable_data_localization
1773 );
1774 assert_eq!(config.data_cache_ttl_ms, cloned_config.data_cache_ttl_ms);
1775 assert_eq!(
1776 config.enable_performance_monitoring,
1777 cloned_config.enable_performance_monitoring
1778 );
1779
1780 let stats = CompleteExportStats {
1781 data_gathering: crate::export::data_localizer::DataGatheringStats {
1782 total_time_ms: 100,
1783 basic_data_time_ms: 50,
1784 ffi_data_time_ms: 30,
1785 scope_data_time_ms: 20,
1786 allocation_count: 100,
1787 ffi_allocation_count: 10,
1788 scope_count: 5,
1789 },
1790 parallel_processing: crate::export::parallel_shard_processor::ParallelProcessingStats {
1791 total_allocations: 100,
1792 shard_count: 2,
1793 threads_used: 4,
1794 total_processing_time_ms: 500,
1795 avg_shard_processing_time_ms: 250.0,
1796 parallel_efficiency: 0.8,
1797 throughput_allocations_per_sec: 200.0,
1798 used_parallel_processing: true,
1799 total_output_size_bytes: 50000,
1800 },
1801 write_performance: crate::export::high_speed_buffered_writer::WritePerformanceStats {
1802 total_bytes_written: 50000,
1803 shards_written: 2,
1804 total_write_time_ms: 300,
1805 avg_write_speed_bps: 166666.0,
1806 flush_count: 1,
1807 preallocation_effective: true,
1808 buffer_utilization: 0.7,
1809 },
1810 total_export_time_ms: 1000,
1811 total_allocations_processed: 100,
1812 total_output_size_bytes: 50000,
1813 overall_throughput_allocations_per_sec: 100.0,
1814 overall_write_speed_mbps: 50.0,
1815 data_gathering_percentage: 20.0,
1816 processing_percentage: 50.0,
1817 writing_percentage: 30.0,
1818 estimated_traditional_time_ms: 3000,
1819 performance_improvement_factor: 3.0,
1820 };
1821 let cloned_stats = stats.clone();
1822 assert_eq!(
1823 stats.total_export_time_ms,
1824 cloned_stats.total_export_time_ms
1825 );
1826 assert_eq!(
1827 stats.total_allocations_processed,
1828 cloned_stats.total_allocations_processed
1829 );
1830 assert_eq!(
1831 stats.performance_improvement_factor,
1832 cloned_stats.performance_improvement_factor
1833 );
1834 }
1835
1836 }