@@ -646,31 +646,59 @@ function unserializeFromFile_gen(string $filename): Generator {
646646 throw new RuntimeException ("Cannot open file: $ filename " );
647647 }
648648
649- $ buffer = '' ;
649+ $ parts = [];
650+ $ marker_len = strlen (CHUNK_MARKER );
651+
650652 while (!feof ($ handle )) {
651- $ buffer .= fread ($ handle , 1024 *1024 ); // Read in 1Mb chunks
653+ $ data = fread ($ handle , 4 * 1024 * 1024 ); // Larger reads to reduce array size and concatenations
654+ if ($ data === '' ) {
655+ break ;
656+ }
657+
658+ $ offset = 0 ;
659+ while (($ pos = strpos ($ data , CHUNK_MARKER , $ offset )) !== false ) {
660+ $ part_len = $ pos - $ offset ;
661+ if ($ part_len > 0 ) {
662+ $ parts [] = substr ($ data , $ offset , $ part_len ); // Copy only the pre-marker part (< read size)
663+ }
652664
653- while (( $ pos = strpos ( $ buffer , CHUNK_MARKER )) !== false ) {
654- $ chunk = substr ( $ buffer , 0 , $ pos );
655- $ buffer = substr ( $ buffer , $ pos + strlen ( CHUNK_MARKER )); // Remove processed part
665+ // Chunk complete; implode to minimize temp allocs
666+ $ chunk = implode ( '' , $ parts );
667+ $ parts = [];
656668
657669 if ($ chunk !== '' ) {
658- $ data = myUnSerialize ($ chunk );
659- if ($ data !== false && $ data !== null ) {
660- yield $ data ;
661- } else
670+ $ data_unser = myUnSerialize ($ chunk );
671+ if ($ data_unser !== false && $ data_unser !== null ) {
672+ yield $ data_unser ;
673+ } else {
662674 yield false ;
675+ }
676+ }
677+
678+ $ offset = $ pos + $ marker_len ;
679+ }
680+
681+ // Add remaining (partial chunk or full read if no marker)
682+ if ($ offset < strlen ($ data )) {
683+ if ($ offset === 0 ) {
684+ $ parts [] = $ data ; // Direct ref, no copy
685+ } else {
686+ $ parts [] = substr ($ data , $ offset ); // Copy only the remainder (< read size)
663687 }
664688 }
665689 }
666690
667- // Handle any remaining data
668- if ($ buffer !== '' && $ buffer !== CHUNK_MARKER ) {
669- $ data = myUnSerialize ($ buffer );
670- if ($ data !== false && $ data !== null ) {
671- yield $ data ;
672- } else
673- yield false ;
691+ // Handle any remaining chunk
692+ if (!empty ($ parts )) {
693+ $ chunk = implode ('' , $ parts );
694+ if ($ chunk !== '' ) {
695+ $ data_unser = myUnSerialize ($ chunk );
696+ if ($ data_unser !== false && $ data_unser !== null ) {
697+ yield $ data_unser ;
698+ } else {
699+ yield false ;
700+ }
701+ }
674702 }
675703
676704 fclose ($ handle );
@@ -862,15 +890,6 @@ function fileGrimReaper ($dirToScan)
862890 // The log file is named after the directory being checked so...
863891 unlogged_cprint ("\nℹ️ Now considering files in: " , $ dirPath , '... ' );
864892
865- // get previous scan datas
866- if (false === ($ knownDatas = getDirectoryScannedDatas ($ dirPath , $ lastScanned ))) {
867- cprint ("🔴 Error: Unserialize failed, skipping " , $ dirPath );
868- continue ;
869- }
870-
871- printStatus ();
872-
873-
874893
875894 // Check if another instance is already scanning this directory
876895 $ pathPidFile = $ pid_file .". " .crc32 ($ dirPath );
@@ -893,7 +912,18 @@ function fileGrimReaper ($dirToScan)
893912 if ( (NOW - $ lastScanned ) < RESPITE * 60 * 60 && $ dirParam ['duration ' ] > 2 * RESPITE * 60 * 60 ) {
894913 unlogged_cprint ("ℹ️ Skipping (snapshot is just " , sprintf ("%0.1f " , (NOW - $ lastScanned ) / 3600 )," hours and life is " , sprintf ("%0.1f " , $ dirParam ['duration ' ] / 86400 ), " days) " );
895914 continue ;
896- }
915+ }
916+
917+
918+ // get previous scan datas
919+ if (false === ($ knownDatas = getDirectoryScannedDatas ($ dirPath , $ lastScanned ))) {
920+ cprint ("🔴 Error: Unserialize failed, skipping " , $ dirPath );
921+ continue ;
922+ }
923+
924+ gc_collect_cycles ();
925+
926+ printStatus ();
897927
898928 /* ########################################
899929 * # Take a new snapshot of the directory #
@@ -957,7 +987,7 @@ function fileGrimReaper ($dirToScan)
957987 if (! ($ FoundFilesCounter % 500_000 ))
958988 printStatus ();
959989
960- if (false && $ FoundFilesCounter == 10000000 ) {
990+ if ($ FoundFilesCounter == 10000000 ) {
961991 $ limitTripped = true ;
962992 cprint ("⚠️ Warning: 10M files limit tripped, stopping there... " );
963993 break ;
0 commit comments