Repository: read the blobs of a pack from one open stream
Restores and deep verifies requested every blob separately: a new file handle and a seek on the location each time. They read the blobs of a snapshot in the order they were written, so the stream of the pack read last now stays open and is read on; a jump backwards, to another pack, or more than 8 MiB ahead opens the pack again at the offset, as before. On a Hetzner Storage Box over SMB, restoring 86 MB in 202 files went from 0.78 MB/s to 4.2 MB/s.
This commit is contained in:
@@ -129,7 +129,7 @@ class VerifyTest extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
/** Delegates to a real backend, but getRange() throws for the first $failures calls. */
|
||||
/** Delegates to a real backend, but reading a pack throws for the first $failures reads. */
|
||||
final class FlakyRangeBackend implements IBackend {
|
||||
public function __construct(
|
||||
private IBackend $inner,
|
||||
@@ -143,15 +143,22 @@ final class FlakyRangeBackend implements IBackend {
|
||||
}
|
||||
|
||||
public function get(string $path) {
|
||||
if (str_starts_with($path, 'packs/')) {
|
||||
$this->fail();
|
||||
}
|
||||
return $this->inner->get($path);
|
||||
}
|
||||
|
||||
public function getRange(string $path, int $offset, int $length): string {
|
||||
$this->fail();
|
||||
return $this->inner->getRange($path, $offset, $length);
|
||||
}
|
||||
|
||||
private function fail(): void {
|
||||
if ($this->failures > 0) {
|
||||
$this->failures--;
|
||||
throw $this->error ?? new BackendException('connection reset');
|
||||
}
|
||||
return $this->inner->getRange($path, $offset, $length);
|
||||
}
|
||||
|
||||
public function exists(string $path): bool {
|
||||
|
||||
Reference in New Issue
Block a user