mirror of
https://github.com/octoleo/restic.git
synced 2024-11-02 19:49:44 +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) {
|
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))
|
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
|
// lookup packs
|
||||||
blobs, err := r.idx.Lookup(id, t)
|
blobs, err := r.idx.Lookup(id, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -109,8 +98,8 @@ func (r *Repository) loadBlob(id restic.ID, t restic.BlobType, plaintextBuf []by
|
|||||||
|
|
||||||
// load blob from pack
|
// load blob from pack
|
||||||
h := restic.Handle{Type: restic.DataFile, Name: blob.PackID.String()}
|
h := restic.Handle{Type: restic.DataFile, Name: blob.PackID.String()}
|
||||||
ciphertextBuf := make([]byte, blob.Length)
|
plaintextBuf = plaintextBuf[:cap(plaintextBuf)]
|
||||||
n, err := r.be.Load(h, ciphertextBuf, int64(blob.Offset))
|
n, err := r.be.Load(h, plaintextBuf, int64(blob.Offset))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
debug.Log("error loading blob %v: %v", blob, err)
|
debug.Log("error loading blob %v: %v", blob, err)
|
||||||
lastError = err
|
lastError = err
|
||||||
@ -125,7 +114,7 @@ func (r *Repository) loadBlob(id restic.ID, t restic.BlobType, plaintextBuf []by
|
|||||||
}
|
}
|
||||||
|
|
||||||
// decrypt
|
// decrypt
|
||||||
n, err = r.decryptTo(plaintextBuf, ciphertextBuf)
|
n, err = r.decryptTo(plaintextBuf, plaintextBuf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
lastError = errors.Errorf("decrypting blob %v failed: %v", id, err)
|
lastError = errors.Errorf("decrypting blob %v failed: %v", id, err)
|
||||||
continue
|
continue
|
||||||
@ -528,7 +517,9 @@ func (r *Repository) Close() error {
|
|||||||
return r.be.Close()
|
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) {
|
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)
|
debug.Log("load blob %v into buf %p", id.Str(), buf)
|
||||||
size, err := r.idx.LookupSize(id, t)
|
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
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(buf) < int(size) {
|
buf = buf[:cap(buf)]
|
||||||
return 0, errors.Errorf("buffer is too small for data blob (%d < %d)", len(buf), size)
|
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)
|
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)
|
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)
|
n, err := r.loadBlob(id, restic.TreeBlob, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"restic"
|
"restic"
|
||||||
"restic/archiver"
|
"restic/archiver"
|
||||||
|
"restic/crypto"
|
||||||
"restic/repository"
|
"restic/repository"
|
||||||
. "restic/test"
|
. "restic/test"
|
||||||
)
|
)
|
||||||
@ -152,7 +153,7 @@ func BenchmarkLoadBlob(b *testing.B) {
|
|||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
length := 1000000
|
length := 1000000
|
||||||
buf := make([]byte, length)
|
buf := make([]byte, length, length+crypto.Extension)
|
||||||
_, err := io.ReadFull(rnd, buf)
|
_, err := io.ReadFull(rnd, buf)
|
||||||
OK(b, err)
|
OK(b, err)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user