Skip to content

Commit 0cc1727

Browse files
committed
Improve deserialization and add 10_000_000 files limit when scanning for files.
This limit ensures that the script will eventually delete the files, even if it takes longer than the defined period...
1 parent 6a7da05 commit 0cc1727

1 file changed

Lines changed: 57 additions & 27 deletions

File tree

‎core.php‎

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)