@@ -849,13 +849,11 @@ impl<'a> Scanner<'a> {
849849 }
850850
851851 // Update discovered files counter atomically (no lock!)
852- let count = files_discovered. fetch_add ( 1 , Ordering :: Relaxed ) ;
852+ files_discovered. fetch_add ( 1 , Ordering :: Relaxed ) ;
853853
854- // Send progress update every 1000 files to reduce channel overhead
854+ // Send discovery progress update (1 = discovery signal)
855855 if let Some ( ref progress_tx) = progress_sender {
856- if count % 1000 == 0 {
857- let _ = progress_tx. send ( 1000 ) ; // Send batch size
858- }
856+ let _ = progress_tx. send ( 1 ) ;
859857 }
860858
861859 ignore:: WalkState :: Continue
@@ -883,22 +881,36 @@ impl<'a> Scanner<'a> {
883881 batch. push ( path) ;
884882
885883 if batch. len ( ) >= BATCH_SIZE {
886- _processed_count += self . process_batch ( & batch, & findings_sender) ?;
884+ let ( processed, findings) = self . process_batch ( & batch, & findings_sender) ?;
885+ _processed_count += processed;
887886 batch. clear ( ) ;
888887
889- // Send progress update for the entire batch
888+ // Send processing progress update (2 = processing signal, repeated for batch size)
890889 if let Some ( ref progress_tx) = progress_sender {
891- let _ = progress_tx. send ( BATCH_SIZE ) ;
890+ for _ in 0 ..processed {
891+ let _ = progress_tx. send ( 2 ) ;
892+ }
893+ // Send findings progress updates (3 = findings signal)
894+ for _ in 0 ..findings {
895+ let _ = progress_tx. send ( 3 ) ;
896+ }
892897 }
893898 }
894899 }
895900
896901 // Process remaining files in the final batch
897902 if !batch. is_empty ( ) {
898- _processed_count += self . process_batch ( & batch, & findings_sender) ?;
903+ let ( processed, findings) = self . process_batch ( & batch, & findings_sender) ?;
904+ _processed_count += processed;
899905
900906 if let Some ( ref progress_tx) = progress_sender {
901- let _ = progress_tx. send ( batch. len ( ) ) ;
907+ for _ in 0 ..processed {
908+ let _ = progress_tx. send ( 2 ) ;
909+ }
910+ // Send findings progress updates (3 = findings signal)
911+ for _ in 0 ..findings {
912+ let _ = progress_tx. send ( 3 ) ;
913+ }
902914 }
903915 }
904916
@@ -910,27 +922,31 @@ impl<'a> Scanner<'a> {
910922 & self ,
911923 batch : & [ PathBuf ] ,
912924 findings_sender : & Sender < Finding >
913- ) -> Result < usize > {
925+ ) -> Result < ( usize , usize ) > {
914926 // Process the batch in parallel using rayon
915- batch
927+ let results : Vec < usize > = batch
916928 . par_iter ( )
917929 . map ( |path| {
918- if let Err ( e) = self . scan_file ( path, findings_sender) {
919- eprintln ! ( "Error scanning file {:?}: {}" , path, e) ;
930+ match self . scan_file ( path, findings_sender) {
931+ Ok ( findings_count) => findings_count,
932+ Err ( e) => {
933+ eprintln ! ( "Error scanning file {:?}: {}" , path, e) ;
934+ 0
935+ }
920936 }
921- 1 // Return 1 for each processed file
922937 } )
923- . sum :: < usize > ( ) ;
938+ . collect ( ) ;
924939
925- Ok ( batch. len ( ) )
940+ let total_findings = results. iter ( ) . sum ( ) ;
941+ Ok ( ( batch. len ( ) , total_findings) )
926942 }
927943
928944 /// Core file scanning logic - processes a single file
929- fn scan_file ( & self , path : & PathBuf , findings_sender : & Sender < Finding > ) -> Result < ( ) > {
945+ fn scan_file ( & self , path : & PathBuf , findings_sender : & Sender < Finding > ) -> Result < usize > {
930946 // Detect language from file extension
931947 let lang = match Self :: detect_language ( path) {
932948 Some ( lang) => lang,
933- None => return Ok ( ( ) ) , // Skip unsupported files
949+ None => return Ok ( 0 ) , // Skip unsupported files
934950 } ;
935951
936952 // Load file contents
@@ -975,13 +991,15 @@ impl<'a> Scanner<'a> {
975991
976992 // Drain emitter and forward findings to main channel
977993 drop ( emitter. tx ) ; // Close the emitter sender to stop receiving
994+ let mut findings_count = 0 ;
978995 for finding in emitter. rx . iter ( ) {
979996 if findings_sender. send ( finding) . is_err ( ) {
980997 break ; // Main receiver has been dropped, stop sending
981998 }
999+ findings_count += 1 ;
9821000 }
9831001
984- Ok ( ( ) )
1002+ Ok ( findings_count )
9851003 }
9861004
9871005 /// Simple file discovery for dry-run functionality - doesn't use the full producer-consumer architecture
@@ -1112,25 +1130,39 @@ impl<'a> Scanner<'a> {
11121130 Some ( thread:: spawn ( move || {
11131131 let mut files_discovered = 0 ;
11141132 let mut files_processed = 0 ;
1115- let findings_count = 0 ;
1133+ let mut findings_count = 0 ;
11161134
11171135 // Initial callback
11181136 callback ( 0 , 0 , 0 ) ;
11191137
1120- for batch_size in progress_rx. iter ( ) {
1121- if batch_size >= 1000 {
1122- // This is a discovery batch
1123- files_discovered += batch_size;
1124- // Update callback every 10k files discovered to reduce overhead
1125- if files_discovered % 10_000 == 0 {
1126- callback ( files_processed, files_discovered, findings_count) ;
1138+ for signal in progress_rx. iter ( ) {
1139+ match signal {
1140+ 1 => {
1141+ // File discovered
1142+ files_discovered += 1 ;
1143+ // Update callback every 1000 files discovered to reduce overhead
1144+ if files_discovered % 1000 == 0 {
1145+ callback ( files_processed, files_discovered, findings_count) ;
1146+ }
1147+ }
1148+ 2 => {
1149+ // File processed
1150+ files_processed += 1 ;
1151+ // Update callback every 500 files processed
1152+ if files_processed % 500 == 0 {
1153+ callback ( files_processed, files_discovered, findings_count) ;
1154+ }
1155+ }
1156+ 3 => {
1157+ // Finding discovered
1158+ findings_count += 1 ;
1159+ // Update callback every 10 findings
1160+ if findings_count % 10 == 0 {
1161+ callback ( files_processed, files_discovered, findings_count) ;
1162+ }
11271163 }
1128- } else {
1129- // This is a processing batch
1130- files_processed += batch_size;
1131- // Update callback every 5k files processed
1132- if files_processed % 5_000 == 0 {
1133- callback ( files_processed, files_discovered, findings_count) ;
1164+ _ => {
1165+ // Unknown signal, ignore
11341166 }
11351167 }
11361168 }
0 commit comments