mirror of
https://github.com/restic/restic.git
synced 2026-06-17 06:04:17 +00:00
repository: change LoadBlob, LookupBlob and LookupBlobSize to BlobHandles (#21857)
This commit is contained in:
@@ -177,11 +177,11 @@ func runCat(ctx context.Context, gopts global.Options, args []string, term ui.Te
|
||||
}
|
||||
|
||||
for _, t := range []restic.BlobType{restic.DataBlob, restic.TreeBlob} {
|
||||
if _, ok := repo.LookupBlobSize(t, id); !ok {
|
||||
if _, ok := repo.LookupBlobSize(restic.BlobHandle{Type: t, ID: id}); !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
buf, err := repo.LoadBlob(ctx, t, id, nil)
|
||||
buf, err := repo.LoadBlob(ctx, restic.BlobHandle{Type: t, ID: id}, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -208,7 +208,7 @@ func runCat(ctx context.Context, gopts global.Options, args []string, term ui.Te
|
||||
return err
|
||||
}
|
||||
|
||||
buf, err := repo.LoadBlob(ctx, restic.TreeBlob, *sn.Tree, nil)
|
||||
buf, err := repo.LoadBlob(ctx, restic.BlobHandle{Type: restic.TreeBlob, ID: *sn.Tree}, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -264,8 +264,8 @@ func copyTree(ctx context.Context, srcRepo *repository.Repository, dstRepo resti
|
||||
enqueue := func(h restic.BlobHandle) {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
if _, ok := dstRepo.LookupBlobSize(h.Type, h.ID); !ok {
|
||||
pb := srcRepo.LookupBlob(h.Type, h.ID)
|
||||
if _, ok := dstRepo.LookupBlobSize(h); !ok {
|
||||
pb := srcRepo.LookupBlob(h)
|
||||
copyBlobs.Insert(h)
|
||||
for _, p := range pb {
|
||||
packList.Insert(p.PackID())
|
||||
@@ -317,7 +317,7 @@ func copyStats(srcRepo restic.Repository, copyBlobs restic.AssociatedBlobSet, pa
|
||||
countBlobs := 0
|
||||
sizeBlobs := uint64(0)
|
||||
for blob := range copyBlobs.Keys() {
|
||||
for _, pb := range srcRepo.LookupBlob(blob.Type, blob.ID) {
|
||||
for _, pb := range srcRepo.LookupBlob(blob) {
|
||||
countBlobs++
|
||||
sizeBlobs += uint64(pb.CiphertextLength())
|
||||
break
|
||||
|
||||
@@ -167,7 +167,7 @@ func updateBlobs(repo restic.Loader, blobs restic.AssociatedBlobSet, stats *Diff
|
||||
stats.TreeBlobs++
|
||||
}
|
||||
|
||||
size, found := repo.LookupBlobSize(h.Type, h.ID)
|
||||
size, found := repo.LookupBlobSize(h)
|
||||
if !found {
|
||||
printError("unable to find blob size for %v", h)
|
||||
continue
|
||||
|
||||
@@ -571,7 +571,7 @@ func (f *Finder) findObjectPack(id string, t restic.BlobType) {
|
||||
return
|
||||
}
|
||||
|
||||
blobs := f.repo.LookupBlob(t, rid)
|
||||
blobs := f.repo.LookupBlob(restic.BlobHandle{Type: t, ID: rid})
|
||||
if len(blobs) == 0 {
|
||||
f.printer.S("Object %s with type %s not found in the index", t.String(), rid.Str())
|
||||
return
|
||||
|
||||
@@ -115,7 +115,7 @@ func runRepairSnapshots(ctx context.Context, gopts global.Options, opts RepairOp
|
||||
var newSize uint64
|
||||
// check all contents and remove if not available
|
||||
for _, id := range node.Content {
|
||||
if size, found := repo.LookupBlobSize(restic.DataBlob, id); !found {
|
||||
if size, found := repo.LookupBlobSize(restic.BlobHandle{Type: restic.DataBlob, ID: id}); !found {
|
||||
ok = false
|
||||
} else {
|
||||
newContent = append(newContent, id)
|
||||
|
||||
@@ -155,7 +155,7 @@ func runStats(ctx context.Context, opts StatsOptions, gopts global.Options, args
|
||||
if opts.countMode == countModeRawData {
|
||||
// the blob handles have been collected, but not yet counted
|
||||
for blobHandle := range stats.blobs.Keys() {
|
||||
pbs := repo.LookupBlob(blobHandle.Type, blobHandle.ID)
|
||||
pbs := repo.LookupBlob(blobHandle)
|
||||
if len(pbs) == 0 {
|
||||
return fmt.Errorf("blob %v not found", blobHandle)
|
||||
}
|
||||
@@ -274,7 +274,7 @@ func statsWalkTree(repo restic.Loader, opts StatsOptions, stats *statsContainer,
|
||||
}
|
||||
if _, ok := stats.fileBlobs[nodePath][blobID]; !ok {
|
||||
// is always a data blob since we're accessing it via a file's Content array
|
||||
blobSize, found := repo.LookupBlobSize(restic.DataBlob, blobID)
|
||||
blobSize, found := repo.LookupBlobSize(restic.BlobHandle{Type: restic.DataBlob, ID: blobID})
|
||||
if !found {
|
||||
return fmt.Errorf("blob %s not found for tree %s", blobID, parentTreeID)
|
||||
}
|
||||
|
||||
@@ -297,7 +297,7 @@ func (arch *Archiver) loadSubtree(ctx context.Context, node *data.Node) (data.Tr
|
||||
}
|
||||
|
||||
func (arch *Archiver) wrapLoadTreeError(id restic.ID, err error) error {
|
||||
if _, ok := arch.Repo.LookupBlobSize(restic.TreeBlob, id); ok {
|
||||
if _, ok := arch.Repo.LookupBlobSize(restic.BlobHandle{Type: restic.TreeBlob, ID: id}); ok {
|
||||
err = errors.Errorf("tree %v could not be loaded; the repository could be damaged: %v", id, err)
|
||||
} else {
|
||||
err = errors.Errorf("tree %v is not known; the repository could be damaged, run `repair index` to try to repair it", id)
|
||||
@@ -435,7 +435,7 @@ func (fn *futureNode) take(ctx context.Context) futureNodeResult {
|
||||
func (arch *Archiver) allBlobsPresent(previous *data.Node) bool {
|
||||
// check if all blobs are contained in index
|
||||
for _, id := range previous.Content {
|
||||
if _, ok := arch.Repo.LookupBlobSize(restic.DataBlob, id); !ok {
|
||||
if _, ok := arch.Repo.LookupBlobSize(restic.BlobHandle{Type: restic.DataBlob, ID: id}); !ok {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ func TestEnsureFileContent(ctx context.Context, t testing.TB, repo restic.BlobLo
|
||||
content := make([]byte, len(file.Content))
|
||||
pos := 0
|
||||
for _, id := range node.Content {
|
||||
part, err := repo.LoadBlob(ctx, restic.DataBlob, id, content[pos:])
|
||||
part, err := repo.LoadBlob(ctx, restic.BlobHandle{Type: restic.DataBlob, ID: id}, content[pos:])
|
||||
if err != nil {
|
||||
t.Fatalf("error loading blob %v: %v", id.Str(), err)
|
||||
return
|
||||
|
||||
@@ -217,7 +217,7 @@ func (c *Checker) checkTree(id restic.ID, tree data.TreeNodeIterator) (errs []er
|
||||
// unfortunately fails in some cases that are not resolvable
|
||||
// by users, so we omit this check, see #1887
|
||||
|
||||
_, found := c.repo.LookupBlobSize(restic.DataBlob, blobID)
|
||||
_, found := c.repo.LookupBlobSize(restic.BlobHandle{Type: restic.DataBlob, ID: blobID})
|
||||
if !found {
|
||||
debug.Log("tree %v references blob %v which isn't contained in index", id, blobID)
|
||||
errs = append(errs, &Error{TreeID: id, Err: errors.Errorf("file %q blob %v not found in index", node.Name, blobID)})
|
||||
@@ -306,7 +306,7 @@ func (c *Checker) ReadPacks(ctx context.Context, filter func(packs map[restic.ID
|
||||
|
||||
// convert used blobs into their encompassing packfiles
|
||||
for bh := range c.blobRefs.M.Keys() {
|
||||
for _, pb := range c.repo.LookupBlob(bh.Type, bh.ID) {
|
||||
for _, pb := range c.repo.LookupBlob(bh) {
|
||||
filteredPacks[pb.PackID()] = allPacks[pb.PackID()]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,20 +397,20 @@ type loadTreesOnceRepository struct {
|
||||
DuplicateTree bool
|
||||
}
|
||||
|
||||
func (r *loadTreesOnceRepository) LoadBlob(ctx context.Context, t restic.BlobType, id restic.ID, buf []byte) ([]byte, error) {
|
||||
if t != restic.TreeBlob {
|
||||
return r.Repository.LoadBlob(ctx, t, id, buf)
|
||||
func (r *loadTreesOnceRepository) LoadBlob(ctx context.Context, bh restic.BlobHandle, buf []byte) ([]byte, error) {
|
||||
if bh.Type != restic.TreeBlob {
|
||||
return r.Repository.LoadBlob(ctx, bh, buf)
|
||||
}
|
||||
r.mutex.Lock()
|
||||
defer r.mutex.Unlock()
|
||||
|
||||
if r.loadedTrees.Has(id) {
|
||||
if r.loadedTrees.Has(bh.ID) {
|
||||
// additionally store error to ensure that it cannot be swallowed
|
||||
r.DuplicateTree = true
|
||||
return nil, errors.Errorf("trying to load tree with id %v twice", id)
|
||||
return nil, errors.Errorf("trying to load tree with id %v twice", bh.ID)
|
||||
}
|
||||
r.loadedTrees.Insert(id)
|
||||
return r.Repository.LoadBlob(ctx, t, id, buf)
|
||||
r.loadedTrees.Insert(bh.ID)
|
||||
return r.Repository.LoadBlob(ctx, bh, buf)
|
||||
}
|
||||
|
||||
func TestCheckerNoDuplicateTreeDecodes(t *testing.T) {
|
||||
@@ -442,18 +442,18 @@ type delayRepository struct {
|
||||
Triggered bool
|
||||
}
|
||||
|
||||
func (r *delayRepository) LoadBlob(ctx context.Context, t restic.BlobType, id restic.ID, buf []byte) ([]byte, error) {
|
||||
if t == restic.TreeBlob && id == r.DelayTree {
|
||||
func (r *delayRepository) LoadBlob(ctx context.Context, bh restic.BlobHandle, buf []byte) ([]byte, error) {
|
||||
if bh.Type == restic.TreeBlob && bh.ID == r.DelayTree {
|
||||
<-r.UnblockChannel
|
||||
}
|
||||
return r.Repository.LoadBlob(ctx, t, id, buf)
|
||||
return r.Repository.LoadBlob(ctx, bh, buf)
|
||||
}
|
||||
|
||||
func (r *delayRepository) LookupBlobSize(t restic.BlobType, id restic.ID) (uint, bool) {
|
||||
if id == r.DelayTree && t == restic.DataBlob {
|
||||
func (r *delayRepository) LookupBlobSize(bh restic.BlobHandle) (uint, bool) {
|
||||
if bh.ID == r.DelayTree && bh.Type == restic.DataBlob {
|
||||
r.Unblock()
|
||||
}
|
||||
return r.Repository.LookupBlobSize(t, id)
|
||||
return r.Repository.LookupBlobSize(bh)
|
||||
}
|
||||
|
||||
func (r *delayRepository) Unblock() {
|
||||
@@ -484,7 +484,7 @@ func TestCheckerBlobTypeConfusion(t *testing.T) {
|
||||
return nil
|
||||
}))
|
||||
|
||||
buf, err := repo.LoadBlob(ctx, restic.TreeBlob, id, nil)
|
||||
buf, err := repo.LoadBlob(ctx, restic.BlobHandle{Type: restic.TreeBlob, ID: id}, nil)
|
||||
test.OK(t, err)
|
||||
|
||||
test.OK(t, repo.WithBlobUploader(ctx, func(ctx context.Context, uploader restic.BlobSaverWithAsync) error {
|
||||
|
||||
@@ -163,11 +163,11 @@ func TestMultiFindUsedBlobs(t *testing.T) {
|
||||
|
||||
type ForbiddenRepo struct{}
|
||||
|
||||
func (r ForbiddenRepo) LoadBlob(context.Context, restic.BlobType, restic.ID, []byte) ([]byte, error) {
|
||||
func (r ForbiddenRepo) LoadBlob(context.Context, restic.BlobHandle, []byte) ([]byte, error) {
|
||||
return nil, errors.New("should not be called")
|
||||
}
|
||||
|
||||
func (r ForbiddenRepo) LookupBlobSize(_ restic.BlobType, _ restic.ID) (uint, bool) {
|
||||
func (r ForbiddenRepo) LookupBlobSize(_ restic.BlobHandle) (uint, bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
|
||||
@@ -202,11 +202,11 @@ func TestLoadAllSnapshots(ctx context.Context, repo restic.ListerLoaderUnpacked,
|
||||
// TestTreeMap returns the trees from the map on LoadTree.
|
||||
type TestTreeMap map[restic.ID][]byte
|
||||
|
||||
func (t TestTreeMap) LoadBlob(_ context.Context, tpe restic.BlobType, id restic.ID, _ []byte) ([]byte, error) {
|
||||
if tpe != restic.TreeBlob {
|
||||
func (t TestTreeMap) LoadBlob(_ context.Context, bh restic.BlobHandle, _ []byte) ([]byte, error) {
|
||||
if bh.Type != restic.TreeBlob {
|
||||
return nil, fmt.Errorf("can only load trees")
|
||||
}
|
||||
tree, ok := t[id]
|
||||
tree, ok := t[bh.ID]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("tree not found")
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ func (t *treeIterator) assertToken(token json.Token) error {
|
||||
}
|
||||
|
||||
func LoadTree(ctx context.Context, loader restic.BlobLoader, content restic.ID) (TreeNodeIterator, error) {
|
||||
rd, err := loader.LoadBlob(ctx, restic.TreeBlob, content, nil)
|
||||
rd, err := loader.LoadBlob(ctx, restic.BlobHandle{Type: restic.TreeBlob, ID: content}, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ func filterTrees(ctx context.Context, repo restic.Loader, trees restic.IDs, load
|
||||
continue
|
||||
}
|
||||
|
||||
treeSize, found := repo.LookupBlobSize(restic.TreeBlob, nextTreeID.ID)
|
||||
treeSize, found := repo.LookupBlobSize(restic.BlobHandle{Type: restic.TreeBlob, ID: nextTreeID.ID})
|
||||
if found && treeSize > 50*1024*1024 {
|
||||
loadCh = hugeTreeLoaderChan
|
||||
} else {
|
||||
|
||||
@@ -142,7 +142,7 @@ loop:
|
||||
|
||||
wg.Go(func() error {
|
||||
blob, err := d.cache.GetOrCompute(id, func() ([]byte, error) {
|
||||
return d.repo.LoadBlob(ctx, restic.DataBlob, id, nil)
|
||||
return d.repo.LoadBlob(ctx, restic.BlobHandle{Type: restic.DataBlob, ID: id}, nil)
|
||||
})
|
||||
|
||||
if err == nil {
|
||||
|
||||
@@ -82,7 +82,7 @@ func (f *file) Open(ctx context.Context, _ *fuse.OpenRequest, _ *fuse.OpenRespon
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
|
||||
size, found := f.root.repo.LookupBlobSize(restic.DataBlob, id)
|
||||
size, found := f.root.repo.LookupBlobSize(restic.BlobHandle{Type: restic.DataBlob, ID: id})
|
||||
if !found {
|
||||
return nil, errors.Errorf("id %v not found in repository", id)
|
||||
}
|
||||
@@ -107,7 +107,7 @@ func (f *file) Open(ctx context.Context, _ *fuse.OpenRequest, _ *fuse.OpenRespon
|
||||
|
||||
func (f *openFile) getBlobAt(ctx context.Context, i int) (blob []byte, err error) {
|
||||
blob, err = f.root.blobCache.GetOrCompute(f.node.Content[i], func() ([]byte, error) {
|
||||
return f.root.repo.LoadBlob(ctx, restic.DataBlob, f.node.Content[i], nil)
|
||||
return f.root.repo.LoadBlob(ctx, restic.BlobHandle{Type: restic.DataBlob, ID: f.node.Content[i]}, nil)
|
||||
})
|
||||
if err != nil {
|
||||
debug.Log("LoadBlob(%v, %v) failed: %v", f.node.Name, f.node.Content[i], err)
|
||||
|
||||
@@ -91,11 +91,11 @@ func TestFuseFile(t *testing.T) {
|
||||
memfile []byte
|
||||
)
|
||||
for _, id := range content {
|
||||
size, found := repo.LookupBlobSize(restic.DataBlob, id)
|
||||
size, found := repo.LookupBlobSize(restic.BlobHandle{Type: restic.DataBlob, ID: id})
|
||||
rtest.Assert(t, found, "Expected to find blob id %v", id)
|
||||
filesize += uint64(size)
|
||||
|
||||
buf, err := repo.LoadBlob(context.TODO(), restic.DataBlob, id, nil)
|
||||
buf, err := repo.LoadBlob(context.TODO(), restic.BlobHandle{Type: restic.DataBlob, ID: id}, nil)
|
||||
rtest.OK(t, err)
|
||||
|
||||
if len(buf) != int(size) {
|
||||
|
||||
@@ -25,7 +25,7 @@ func FuzzSaveLoadBlob(f *testing.F) {
|
||||
return err
|
||||
}))
|
||||
|
||||
buf, err := repo.LoadBlob(context.TODO(), restic.DataBlob, id, make([]byte, buflen))
|
||||
buf, err := repo.LoadBlob(context.TODO(), restic.BlobHandle{Type: restic.DataBlob, ID: id}, make([]byte, buflen))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ func testPrune(t *testing.T, opts repository.PruneOptions, errOnUnused bool) {
|
||||
rtest.OK(t, repo.WithBlobUploader(context.TODO(), func(ctx context.Context, uploader restic.BlobSaverWithAsync) error {
|
||||
// duplicate a few blobs to exercise those code paths
|
||||
for blob := range keep {
|
||||
buf, err := repo.LoadBlob(ctx, blob.Type, blob.ID, nil)
|
||||
buf, err := repo.LoadBlob(ctx, blob, nil)
|
||||
rtest.OK(t, err)
|
||||
_, _, _, err = uploader.SaveBlob(ctx, blob.Type, buf, blob.ID, true)
|
||||
rtest.OK(t, err)
|
||||
@@ -180,7 +180,7 @@ func TestPruneSmall(t *testing.T) {
|
||||
|
||||
// load all blobs
|
||||
for blob := range keep {
|
||||
_, err := repo.LoadBlob(context.TODO(), blob.Type, blob.ID, nil)
|
||||
_, err := repo.LoadBlob(context.TODO(), blob, nil)
|
||||
rtest.OK(t, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ func findPacksForBlobs(t *testing.T, repo restic.Repository, blobs restic.BlobSe
|
||||
packs := restic.NewIDSet()
|
||||
|
||||
for h := range blobs {
|
||||
list := repo.LookupBlob(h.Type, h.ID)
|
||||
list := repo.LookupBlob(h)
|
||||
if len(list) == 0 {
|
||||
t.Fatal("Failed to find blob", h.ID.Str(), "with type", h.Type)
|
||||
}
|
||||
@@ -208,7 +208,7 @@ func testRepack(t *testing.T, version uint) {
|
||||
}
|
||||
|
||||
for h := range keepBlobs {
|
||||
list := repo.LookupBlob(h.Type, h.ID)
|
||||
list := repo.LookupBlob(h)
|
||||
if len(list) == 0 {
|
||||
t.Errorf("unable to find blob %v in repo", h.ID.Str())
|
||||
continue
|
||||
@@ -227,7 +227,7 @@ func testRepack(t *testing.T, version uint) {
|
||||
}
|
||||
|
||||
for h := range removeBlobs {
|
||||
if _, found := repo.LookupBlobSize(h.Type, h.ID); found {
|
||||
if _, found := repo.LookupBlobSize(h); found {
|
||||
t.Errorf("blob %v still contained in the repo", h)
|
||||
}
|
||||
}
|
||||
@@ -277,7 +277,7 @@ func testRepackCopy(t *testing.T, version uint) {
|
||||
rebuildAndReloadIndex(t, dstRepo)
|
||||
|
||||
for h := range keepBlobs {
|
||||
list := dstRepo.LookupBlob(h.Type, h.ID)
|
||||
list := dstRepo.LookupBlob(h)
|
||||
if len(list) == 0 {
|
||||
t.Errorf("unable to find blob %v in repo", h.ID.Str())
|
||||
continue
|
||||
|
||||
@@ -236,16 +236,16 @@ func sortCachedPacksFirst(cache haver, blobs []*pack.PackedBlob) {
|
||||
copy(blobs[len(cached):], noncached)
|
||||
}
|
||||
|
||||
// LoadBlob loads a blob of type t from the repository.
|
||||
// LoadBlob loads a blob from the repository.
|
||||
// It may use all of buf[:cap(buf)] as scratch space.
|
||||
func (r *Repository) LoadBlob(ctx context.Context, t restic.BlobType, id restic.ID, buf []byte) ([]byte, error) {
|
||||
debug.Log("load %v with id %v (buf len %v, cap %d)", t, id, len(buf), cap(buf))
|
||||
func (r *Repository) LoadBlob(ctx context.Context, bh restic.BlobHandle, buf []byte) ([]byte, error) {
|
||||
debug.Log("load %v (buf len %v, cap %d)", bh, len(buf), cap(buf))
|
||||
|
||||
// lookup packs
|
||||
blobs := r.idx.Lookup(restic.BlobHandle{ID: id, Type: t})
|
||||
blobs := r.idx.Lookup(bh)
|
||||
if len(blobs) == 0 {
|
||||
debug.Log("id %v not found in index", id)
|
||||
return nil, errors.Errorf("id %v not found in repository", id)
|
||||
debug.Log("id %v not found in index", bh.ID)
|
||||
return nil, errors.Errorf("id %v not found in repository", bh.ID)
|
||||
}
|
||||
|
||||
// try cached pack files first
|
||||
@@ -671,8 +671,8 @@ func (r *Repository) Connections() uint {
|
||||
return r.be.Properties().Connections
|
||||
}
|
||||
|
||||
func (r *Repository) LookupBlob(tpe restic.BlobType, id restic.ID) []restic.PackBlob {
|
||||
entries := r.idx.Lookup(restic.BlobHandle{Type: tpe, ID: id})
|
||||
func (r *Repository) LookupBlob(bh restic.BlobHandle) []restic.PackBlob {
|
||||
entries := r.idx.Lookup(bh)
|
||||
out := make([]restic.PackBlob, len(entries))
|
||||
for i, e := range entries {
|
||||
out[i] = e
|
||||
@@ -681,8 +681,8 @@ func (r *Repository) LookupBlob(tpe restic.BlobType, id restic.ID) []restic.Pack
|
||||
}
|
||||
|
||||
// LookupBlobSize returns the size of blob id. Also returns pending blobs.
|
||||
func (r *Repository) LookupBlobSize(tpe restic.BlobType, id restic.ID) (uint, bool) {
|
||||
return r.idx.LookupSize(restic.BlobHandle{Type: tpe, ID: id})
|
||||
func (r *Repository) LookupBlobSize(bh restic.BlobHandle) (uint, bool) {
|
||||
return r.idx.LookupSize(bh)
|
||||
}
|
||||
|
||||
// ListBlobs runs fn on all blobs known to the index. When the context is cancelled,
|
||||
@@ -1059,7 +1059,7 @@ func (r *Repository) saveBlobAsync(ctx context.Context, t restic.BlobType, buf [
|
||||
}
|
||||
|
||||
type backendLoadFn func(ctx context.Context, h backend.Handle, length int, offset int64, fn func(rd io.Reader) error) error
|
||||
type loadBlobFn func(ctx context.Context, t restic.BlobType, id restic.ID, buf []byte) ([]byte, error)
|
||||
type loadBlobFn func(ctx context.Context, bh restic.BlobHandle, buf []byte) ([]byte, error)
|
||||
|
||||
// Skip sections with more than 1MB unused blobs
|
||||
const maxUnusedRange = 1 * 1024 * 1024
|
||||
@@ -1164,7 +1164,7 @@ func streamPackPart(ctx context.Context, beLoad backendLoadFn, loadBlobFn loadBl
|
||||
if loadBlobFn != nil {
|
||||
// check whether we can get the remaining blobs somewhere else
|
||||
for _, entry := range blobs {
|
||||
buf, ierr := loadBlobFn(ctx, entry.Type, entry.ID, nil)
|
||||
buf, ierr := loadBlobFn(ctx, entry.BlobHandle, nil)
|
||||
err = handleBlobFn(entry.BlobHandle, buf, ierr)
|
||||
if err != nil {
|
||||
break
|
||||
@@ -1191,7 +1191,7 @@ func streamPackPart(ctx context.Context, beLoad backendLoadFn, loadBlobFn loadBl
|
||||
if val.Err != nil && loadBlobFn != nil {
|
||||
var ierr error
|
||||
// check whether we can get a valid copy somewhere else
|
||||
buf, ierr := loadBlobFn(ctx, val.Handle.Type, val.Handle.ID, nil)
|
||||
buf, ierr := loadBlobFn(ctx, val.Handle, nil)
|
||||
if ierr == nil {
|
||||
// success
|
||||
val.Plaintext = buf
|
||||
|
||||
@@ -548,8 +548,8 @@ func TestStreamPackFallback(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
loadBlob := func(ctx context.Context, t restic.BlobType, id restic.ID, buf []byte) ([]byte, error) {
|
||||
if id == blobID {
|
||||
loadBlob := func(ctx context.Context, bh restic.BlobHandle, buf []byte) ([]byte, error) {
|
||||
if bh.ID == blobID {
|
||||
return plaintext, nil
|
||||
}
|
||||
return nil, errors.New("unknown blob")
|
||||
|
||||
@@ -66,7 +66,7 @@ func testSave(t *testing.T, version uint, calculateID bool) {
|
||||
}))
|
||||
|
||||
// read back
|
||||
buf, err := repo.LoadBlob(context.TODO(), restic.DataBlob, id, nil)
|
||||
buf, err := repo.LoadBlob(context.TODO(), restic.BlobHandle{Type: restic.DataBlob, ID: id}, nil)
|
||||
rtest.OK(t, err)
|
||||
rtest.Equals(t, size, len(buf))
|
||||
|
||||
@@ -97,7 +97,7 @@ func testSaveLoadZeroSizedBlob(t *testing.T, version uint) {
|
||||
return nil
|
||||
}))
|
||||
|
||||
buf, err := repo.LoadBlob(context.TODO(), restic.DataBlob, id, nil)
|
||||
buf, err := repo.LoadBlob(context.TODO(), restic.BlobHandle{Type: restic.DataBlob, ID: id}, nil)
|
||||
rtest.OK(t, err)
|
||||
rtest.Equals(t, 0, len(buf))
|
||||
}
|
||||
@@ -138,7 +138,7 @@ func testSavePackMerging(t *testing.T, targetPercentage int, expectedPacks int)
|
||||
|
||||
// check that all blobs are readable
|
||||
for _, id := range ids {
|
||||
_, err := repo.LoadBlob(context.TODO(), restic.DataBlob, id, nil)
|
||||
_, err := repo.LoadBlob(context.TODO(), restic.BlobHandle{Type: restic.DataBlob, ID: id}, nil)
|
||||
rtest.OK(t, err)
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ func testLoadBlob(t *testing.T, version uint) {
|
||||
base := crypto.CiphertextLength(length)
|
||||
for _, testlength := range []int{0, base - 20, base - 1, base, base + 7, base + 15, base + 1000} {
|
||||
buf = make([]byte, 0, testlength)
|
||||
buf, err := repo.LoadBlob(context.TODO(), restic.DataBlob, id, buf)
|
||||
buf, err := repo.LoadBlob(context.TODO(), restic.BlobHandle{Type: restic.DataBlob, ID: id}, buf)
|
||||
if err != nil {
|
||||
t.Errorf("LoadBlob() returned an error for buffer size %v: %v", testlength, err)
|
||||
continue
|
||||
@@ -230,10 +230,10 @@ func TestLoadBlobBroken(t *testing.T) {
|
||||
c := cache.TestNewCache(t)
|
||||
repo.UseCache(c, t.Logf)
|
||||
|
||||
data, err := repo.LoadBlob(context.TODO(), restic.TreeBlob, id, nil)
|
||||
data, err := repo.LoadBlob(context.TODO(), restic.BlobHandle{Type: restic.TreeBlob, ID: id}, nil)
|
||||
rtest.OK(t, err)
|
||||
rtest.Assert(t, bytes.Equal(buf, data), "data mismatch")
|
||||
pack := repo.LookupBlob(restic.TreeBlob, id)[0].PackID()
|
||||
pack := repo.LookupBlob(restic.BlobHandle{Type: restic.TreeBlob, ID: id})[0].PackID()
|
||||
rtest.Assert(t, c.Has(backend.Handle{Type: restic.PackFile, Name: pack.String()}), "expected tree pack to be cached")
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ func benchmarkLoadBlob(b *testing.B, version uint) {
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
var err error
|
||||
buf, err = repo.LoadBlob(context.TODO(), restic.DataBlob, id, buf)
|
||||
buf, err = repo.LoadBlob(context.TODO(), restic.BlobHandle{Type: restic.DataBlob, ID: id}, buf)
|
||||
|
||||
// Checking the SHA-256 with restic.Hash can make up 38% of the time
|
||||
// spent in this loop, so pause the timer.
|
||||
@@ -466,7 +466,7 @@ func TestListPack(t *testing.T) {
|
||||
repo.UseCache(c, t.Logf)
|
||||
|
||||
// Forcibly cache pack file
|
||||
packID := repo.LookupBlob(restic.TreeBlob, id)[0].PackID()
|
||||
packID := repo.LookupBlob(restic.BlobHandle{Type: restic.TreeBlob, ID: id})[0].PackID()
|
||||
rtest.OK(t, be.Load(context.TODO(), backend.Handle{Type: restic.PackFile, IsMetadata: true, Name: packID.String()}, 0, 0, func(rd io.Reader) error { return nil }))
|
||||
|
||||
// Get size to list pack
|
||||
|
||||
@@ -21,8 +21,8 @@ type Repository interface {
|
||||
|
||||
LoadIndex(ctx context.Context, p TerminalCounterFactory) error
|
||||
|
||||
LookupBlob(t BlobType, id ID) []PackBlob
|
||||
LookupBlobSize(t BlobType, id ID) (size uint, exists bool)
|
||||
LookupBlob(bh BlobHandle) []PackBlob
|
||||
LookupBlobSize(bh BlobHandle) (size uint, exists bool)
|
||||
|
||||
NewAssociatedBlobSet() AssociatedBlobSet
|
||||
// ListBlobs runs fn on all blobs known to the index. When the context is cancelled,
|
||||
@@ -31,7 +31,7 @@ type Repository interface {
|
||||
// ListPackHandles returns the blob handles stored in the pack file header.
|
||||
ListPackHandles(ctx context.Context, id ID, packSize int64) ([]BlobHandle, error)
|
||||
|
||||
LoadBlob(ctx context.Context, t BlobType, id ID, buf []byte) ([]byte, error)
|
||||
LoadBlob(ctx context.Context, bh BlobHandle, buf []byte) ([]byte, error)
|
||||
LoadBlobsFromPack(ctx context.Context, packID ID, blobs []BlobHandle, handleBlobFn func(blob BlobHandle, buf []byte, err error) error) error
|
||||
|
||||
// WithUploader starts the necessary workers to upload new blobs. Once the callback returns,
|
||||
@@ -148,7 +148,7 @@ type ListBlobser interface {
|
||||
}
|
||||
|
||||
type BlobLoader interface {
|
||||
LoadBlob(context.Context, BlobType, ID, []byte) ([]byte, error)
|
||||
LoadBlob(context.Context, BlobHandle, []byte) ([]byte, error)
|
||||
}
|
||||
|
||||
type WithBlobUploader interface {
|
||||
@@ -173,8 +173,8 @@ type BlobSaverAsync interface {
|
||||
|
||||
// Loader loads a blob from a repository.
|
||||
type Loader interface {
|
||||
LoadBlob(context.Context, BlobType, ID, []byte) ([]byte, error)
|
||||
LookupBlobSize(tpe BlobType, id ID) (uint, bool)
|
||||
LoadBlob(context.Context, BlobHandle, []byte) ([]byte, error)
|
||||
LookupBlobSize(bh BlobHandle) (uint, bool)
|
||||
Connections() uint
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ type startWarmupFn func(context.Context, restic.IDSet) (restic.WarmupJob, error)
|
||||
|
||||
// fileRestorer restores set of files
|
||||
type fileRestorer struct {
|
||||
idx func(restic.BlobType, restic.ID) []restic.PackBlob
|
||||
idx func(restic.BlobHandle) []restic.PackBlob
|
||||
blobsLoader blobsLoaderFn
|
||||
|
||||
startWarmup startWarmupFn
|
||||
@@ -68,7 +68,7 @@ type fileRestorer struct {
|
||||
|
||||
func newFileRestorer(dst string,
|
||||
blobsLoader blobsLoaderFn,
|
||||
idx func(restic.BlobType, restic.ID) []restic.PackBlob,
|
||||
idx func(restic.BlobHandle) []restic.PackBlob,
|
||||
connections uint,
|
||||
sparse bool,
|
||||
allowRecursiveDelete bool,
|
||||
@@ -109,7 +109,7 @@ func (r *fileRestorer) forEachBlob(blobIDs []restic.ID, fn func(blob restic.Pack
|
||||
|
||||
fileOffset := int64(0)
|
||||
for i, blobID := range blobIDs {
|
||||
packs := r.idx(restic.DataBlob, blobID)
|
||||
packs := r.idx(restic.BlobHandle{Type: restic.DataBlob, ID: blobID})
|
||||
if len(packs) == 0 {
|
||||
return errors.Errorf("Unknown blob %s", blobID.String())
|
||||
}
|
||||
@@ -290,7 +290,7 @@ func (r *fileRestorer) downloadPack(ctx context.Context, pack *packInfo) error {
|
||||
}
|
||||
} else if packsMap, ok := file.blobs.(map[restic.ID][]fileBlobInfo); ok {
|
||||
for _, blob := range packsMap[pack.id] {
|
||||
idxPacks := r.idx(restic.DataBlob, blob.id)
|
||||
idxPacks := r.idx(restic.BlobHandle{Type: restic.DataBlob, ID: blob.id})
|
||||
for _, idxPack := range idxPacks {
|
||||
if idxPack.PackID().Equal(pack.id) {
|
||||
addBlob(idxPack.Handle(), blob.offset)
|
||||
|
||||
@@ -67,8 +67,8 @@ type TestRepo struct {
|
||||
loader blobsLoaderFn
|
||||
}
|
||||
|
||||
func (i *TestRepo) Lookup(_ restic.BlobType, id restic.ID) []restic.PackBlob {
|
||||
packs := i.blobs[id]
|
||||
func (i *TestRepo) Lookup(bh restic.BlobHandle) []restic.PackBlob {
|
||||
packs := i.blobs[bh.ID]
|
||||
return packs
|
||||
}
|
||||
|
||||
|
||||
@@ -744,7 +744,7 @@ func (res *Restorer) verifyFile(ctx context.Context, target string, node *data.N
|
||||
if ctx.Err() != nil {
|
||||
return nil, buf, ctx.Err()
|
||||
}
|
||||
length, found := res.repo.LookupBlobSize(restic.DataBlob, blobID)
|
||||
length, found := res.repo.LookupBlobSize(restic.BlobHandle{Type: restic.DataBlob, ID: blobID})
|
||||
if !found {
|
||||
return nil, buf, errors.Errorf("Unable to fetch blob %s", blobID)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user