mirror of
https://github.com/octoleo/restic.git
synced 2024-12-28 13:00:53 +00:00
LoadBlob: use buffer as scratch space
benchmark old bytes new bytes delta BenchmarkLoadBlob-4 1010128 2256 -99.78%
This commit is contained in:
parent
215af5c60a
commit
9a5b9253c4
@ -81,17 +81,6 @@ func (r *Repository) LoadAndDecrypt(t restic.FileType, id restic.ID) ([]byte, er
|
||||
func (r *Repository) loadBlob(id restic.ID, t restic.BlobType, plaintextBuf []byte) (int, error) {
|
||||
debug.Log("load %v with id %v (buf %p, len %d)", t, id.Str(), plaintextBuf, len(plaintextBuf))
|
||||
|
||||
// lookup plaintext size of blob
|
||||
size, err := r.idx.LookupSize(id, t)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// make sure the plaintext buffer is large enough, extend otherwise
|
||||
if len(plaintextBuf) < int(size) {
|
||||
return 0, errors.Errorf("buffer is too small: %d < %d", len(plaintextBuf), size)
|
||||
}
|
||||
|
||||
// lookup packs
|
||||
blobs, err := r.idx.Lookup(id, t)
|
||||
if err != nil {
|
||||
@ -109,8 +98,8 @@ func (r *Repository) loadBlob(id restic.ID, t restic.BlobType, plaintextBuf []by
|
||||
|
||||
// load blob from pack
|
||||
h := restic.Handle{Type: restic.DataFile, Name: blob.PackID.String()}
|
||||
ciphertextBuf := make([]byte, blob.Length)
|
||||
n, err := r.be.Load(h, ciphertextBuf, int64(blob.Offset))
|
||||
plaintextBuf = plaintextBuf[:cap(plaintextBuf)]
|
||||
n, err := r.be.Load(h, plaintextBuf, int64(blob.Offset))
|
||||
if err != nil {
|
||||
debug.Log("error loading blob %v: %v", blob, err)
|
||||
lastError = err
|
||||
@ -125,7 +114,7 @@ func (r *Repository) loadBlob(id restic.ID, t restic.BlobType, plaintextBuf []by
|
||||
}
|
||||
|
||||
// decrypt
|
||||
n, err = r.decryptTo(plaintextBuf, ciphertextBuf)
|
||||
n, err = r.decryptTo(plaintextBuf, plaintextBuf)
|
||||
if err != nil {
|
||||
lastError = errors.Errorf("decrypting blob %v failed: %v", id, err)
|
||||
continue
|
||||
@ -528,7 +517,9 @@ func (r *Repository) Close() error {
|
||||
return r.be.Close()
|
||||
}
|
||||
|
||||
// LoadBlob loads a blob of type t from the repository to the buffer.
|
||||
// LoadBlob loads a blob of type t from the repository to the buffer. buf must
|
||||
// be large enough to hold the encrypted blob, since it is used as scratch
|
||||
// space.
|
||||
func (r *Repository) LoadBlob(t restic.BlobType, id restic.ID, buf []byte) (int, error) {
|
||||
debug.Log("load blob %v into buf %p", id.Str(), buf)
|
||||
size, err := r.idx.LookupSize(id, t)
|
||||
@ -536,8 +527,9 @@ func (r *Repository) LoadBlob(t restic.BlobType, id restic.ID, buf []byte) (int,
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if len(buf) < int(size) {
|
||||
return 0, errors.Errorf("buffer is too small for data blob (%d < %d)", len(buf), size)
|
||||
buf = buf[:cap(buf)]
|
||||
if len(buf) < int(size)+crypto.Extension {
|
||||
return 0, errors.Errorf("buffer is too small for data blob (%d < %d)", len(buf), size+crypto.Extension)
|
||||
}
|
||||
|
||||
n, err := r.loadBlob(id, t, buf)
|
||||
@ -571,7 +563,7 @@ func (r *Repository) LoadTree(id restic.ID) (*restic.Tree, error) {
|
||||
}
|
||||
|
||||
debug.Log("size is %d, create buffer", size)
|
||||
buf := make([]byte, size)
|
||||
buf := make([]byte, size+crypto.Extension)
|
||||
|
||||
n, err := r.loadBlob(id, restic.TreeBlob, buf)
|
||||
if err != nil {
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
|
||||
"restic"
|
||||
"restic/archiver"
|
||||
"restic/crypto"
|
||||
"restic/repository"
|
||||
. "restic/test"
|
||||
)
|
||||
@ -152,7 +153,7 @@ func BenchmarkLoadBlob(b *testing.B) {
|
||||
defer cleanup()
|
||||
|
||||
length := 1000000
|
||||
buf := make([]byte, length)
|
||||
buf := make([]byte, length, length+crypto.Extension)
|
||||
_, err := io.ReadFull(rnd, buf)
|
||||
OK(b, err)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user