Estimate workload for quick scan (file) mode
(
input_file_path: &str,
prefix: &str,
suffix: &str,
infix: Option<&str>
)
| 23 | |
| 24 | /// Estimate workload for quick scan (file) mode |
| 25 | async fn estimate_file_workload( |
| 26 | input_file_path: &str, |
| 27 | prefix: &str, |
| 28 | suffix: &str, |
| 29 | infix: Option<&str> |
| 30 | ) -> Result<u64, Error> { |
| 31 | // Check if file exists |
| 32 | if !Path::new(input_file_path).exists() { |
| 33 | return Err(anyhow!("File not found: {}", input_file_path)); |
| 34 | } |
| 35 | |
| 36 | // Get file size for estimation |
| 37 | let metadata = tokio::fs::metadata(input_file_path).await?; |
| 38 | let file_size = metadata.len(); |
| 39 | |
| 40 | // Check if file is empty |
| 41 | if file_size == 0 { |
| 42 | return Err(anyhow!("File is empty: {}", input_file_path)); |
| 43 | } |
| 44 | |
| 45 | // Sample a portion of the file for better accuracy |
| 46 | const SAMPLE_SIZE: u64 = 50_000; |
| 47 | let (sample_matched, sample_count, sample_bytes_read) = sample_file( |
| 48 | input_file_path, |
| 49 | SAMPLE_SIZE, |
| 50 | prefix, |
| 51 | suffix, |
| 52 | infix |
| 53 | ).await?; |
| 54 | |
| 55 | // Handle the case where no valid lines were found |
| 56 | if sample_count == 0 { |
| 57 | return Err(anyhow!("No valid phone numbers found in file: {}", input_file_path)); |
| 58 | } |
| 59 | |
| 60 | // Calculate total estimate |
| 61 | let match_ratio = sample_matched as f64 / sample_count as f64; |
| 62 | let bytes_per_line = if sample_count > 0 { |
| 63 | sample_bytes_read as f64 / sample_count as f64 |
| 64 | } else { |
| 65 | 50.0 // Default estimate |
| 66 | }; |
| 67 | |
| 68 | let estimated_total_lines = (file_size as f64 / bytes_per_line).ceil() as u64; |
| 69 | let estimated_matches = (estimated_total_lines as f64 * match_ratio).ceil() as u64; |
| 70 | |
| 71 | // Add a buffer to ensure we don't underestimate (increase by 10%) |
| 72 | let estimated_matches = (estimated_matches as f64 * 1.1).ceil() as u64; |
| 73 | |
| 74 | // Ensure a reasonable minimum |
| 75 | let estimated_matches = std::cmp::max(estimated_matches, 1000); |
| 76 | |
| 77 | Ok(estimated_matches) |
| 78 | } |
| 79 | |
| 80 | /// Sample a file to get an estimate of matching lines |
| 81 | async fn sample_file( |
no test coverage detected