Run the backup job at every cron run; skip deflate on compressed data
This commit is contained in:
@@ -28,6 +28,10 @@ final class Repository {
|
||||
public const FORMAT = 1;
|
||||
public const BLOB_SIZE = 4 * 1048576;
|
||||
private const FLAG_DEFLATE = 1;
|
||||
/** Blobs from this size on get a quick compression test before the full compression. */
|
||||
private const DEFLATE_PROBE_FROM = 256 * 1024;
|
||||
/** Bytes of each of the three slices (start, middle, end) in that test. */
|
||||
private const DEFLATE_PROBE_SLICE = 32 * 1024;
|
||||
/** Reads per blob in a deep verify before it is reported as unreadable (not corrupted). */
|
||||
private const VERIFY_READ_ATTEMPTS = 3;
|
||||
/** Largest read that loadBlobs() makes of blobs that follow each other in a pack. */
|
||||
@@ -703,7 +707,7 @@ final class Repository {
|
||||
}
|
||||
$flags = 0;
|
||||
$payload = $data;
|
||||
$deflated = gzdeflate($data, 6);
|
||||
$deflated = self::worthDeflating($data) ? gzdeflate($data, 6) : false;
|
||||
if ($deflated !== false && strlen($deflated) < strlen($data) * 0.95) {
|
||||
$payload = $deflated;
|
||||
$flags |= self::FLAG_DEFLATE;
|
||||
@@ -713,6 +717,23 @@ final class Repository {
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Photos, video and archives are compressed already: deflating them takes most of a backup's
|
||||
* CPU time (about 24 MiB/s) only to be thrown away, as it saves less than the 5% that keeps
|
||||
* it. A fast deflate of three small slices tells first; below 10% savings there, the full
|
||||
* deflate is skipped.
|
||||
*/
|
||||
private static function worthDeflating(string $data): bool {
|
||||
$n = strlen($data);
|
||||
if ($n < self::DEFLATE_PROBE_FROM) {
|
||||
return true;
|
||||
}
|
||||
$k = self::DEFLATE_PROBE_SLICE;
|
||||
$probe = substr($data, 0, $k) . substr($data, intdiv($n - $k, 2), $k) . substr($data, $n - $k);
|
||||
$deflated = gzdeflate($probe, 1);
|
||||
return $deflated !== false && strlen($deflated) * 10 < strlen($probe) * 9;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blobs spread over many packs (the tree segments of a run, one per step), through
|
||||
* IBackend::getRanges(): on a remote location one at a time is a round trip each, which for
|
||||
|
||||
Reference in New Issue
Block a user