diff --git a/cmd/restic/cmd_prune.go b/cmd/restic/cmd_prune.go index bdad4efd9..90fe7693d 100644 --- a/cmd/restic/cmd_prune.go +++ b/cmd/restic/cmd_prune.go @@ -574,20 +574,14 @@ func getUsedBlobs(gopts GlobalOptions, repo restic.Repository, ignoreSnapshots r bar := newProgressMax(!gopts.Quiet, uint64(len(snapshotTrees)), "snapshots") defer bar.Done() - for _, tree := range snapshotTrees { - debug.Log("process tree %v", tree) - err = restic.FindUsedBlobs(ctx, repo, tree, usedBlobs) - if err != nil { - if repo.Backend().IsNotExist(err) { - return nil, errors.Fatal("unable to load a tree from the repo: " + err.Error()) - } - - return nil, err + err = restic.FindUsedBlobs(ctx, repo, snapshotTrees, usedBlobs, bar) + if err != nil { + if repo.Backend().IsNotExist(err) { + return nil, errors.Fatal("unable to load a tree from the repo: " + err.Error()) } - debug.Log("processed tree %v", tree) - bar.Add(1) + return nil, err } return usedBlobs, nil } diff --git a/cmd/restic/cmd_stats.go b/cmd/restic/cmd_stats.go index 81ec66843..deb649e26 100644 --- a/cmd/restic/cmd_stats.go +++ b/cmd/restic/cmd_stats.go @@ -166,7 +166,7 @@ func statsWalkSnapshot(ctx context.Context, snapshot *restic.Snapshot, repo rest if statsOptions.countMode == countModeRawData { // count just the sizes of unique blobs; we don't need to walk the tree // ourselves in this case, since a nifty function does it for us - return restic.FindUsedBlobs(ctx, repo, *snapshot.Tree, stats.blobs) + return restic.FindUsedBlobs(ctx, repo, restic.IDs{*snapshot.Tree}, stats.blobs, nil) } err := walker.Walk(ctx, repo, *snapshot.Tree, restic.NewIDSet(), statsWalkTree(repo, stats)) diff --git a/internal/restic/find.go b/internal/restic/find.go index 4c72766c6..4d6433d60 100644 --- a/internal/restic/find.go +++ b/internal/restic/find.go @@ -4,6 +4,7 @@ import ( "context" "sync" + "github.com/restic/restic/internal/ui/progress" "golang.org/x/sync/errgroup" ) @@ -14,11 +15,11 @@ type TreeLoader interface { // FindUsedBlobs traverses the tree ID and adds all seen blobs (trees and data // blobs) to the set blobs. Already seen tree blobs will not be visited again. -func FindUsedBlobs(ctx context.Context, repo TreeLoader, treeID ID, blobs BlobSet) error { +func FindUsedBlobs(ctx context.Context, repo TreeLoader, treeIDs IDs, blobs BlobSet, p *progress.Counter) error { var lock sync.Mutex wg, ctx := errgroup.WithContext(ctx) - treeStream := StreamTrees(ctx, wg, repo, IDs{treeID}, func(treeID ID) bool { + treeStream := StreamTrees(ctx, wg, repo, treeIDs, func(treeID ID) bool { // locking is necessary the goroutine below concurrently adds data blobs lock.Lock() h := BlobHandle{ID: treeID, Type: TreeBlob} @@ -27,7 +28,7 @@ func FindUsedBlobs(ctx context.Context, repo TreeLoader, treeID ID, blobs BlobSe blobs.Insert(h) lock.Unlock() return blobReferenced - }, nil) + }, p) wg.Go(func() error { for tree := range treeStream { diff --git a/internal/restic/find_test.go b/internal/restic/find_test.go index 635421d8b..278a7471a 100644 --- a/internal/restic/find_test.go +++ b/internal/restic/find_test.go @@ -94,7 +94,7 @@ func TestFindUsedBlobs(t *testing.T) { for i, sn := range snapshots { usedBlobs := restic.NewBlobSet() - err := restic.FindUsedBlobs(context.TODO(), repo, *sn.Tree, usedBlobs) + err := restic.FindUsedBlobs(context.TODO(), repo, restic.IDs{*sn.Tree}, usedBlobs, nil) if err != nil { t.Errorf("FindUsedBlobs returned error: %v", err) continue @@ -133,12 +133,12 @@ func TestFindUsedBlobsSkipsSeenBlobs(t *testing.T) { t.Logf("snapshot %v saved, tree %v", snapshot.ID().Str(), snapshot.Tree.Str()) usedBlobs := restic.NewBlobSet() - err := restic.FindUsedBlobs(context.TODO(), repo, *snapshot.Tree, usedBlobs) + err := restic.FindUsedBlobs(context.TODO(), repo, restic.IDs{*snapshot.Tree}, usedBlobs, nil) if err != nil { t.Fatalf("FindUsedBlobs returned error: %v", err) } - err = restic.FindUsedBlobs(context.TODO(), ForbiddenRepo{}, *snapshot.Tree, usedBlobs) + err = restic.FindUsedBlobs(context.TODO(), ForbiddenRepo{}, restic.IDs{*snapshot.Tree}, usedBlobs, nil) if err != nil { t.Fatalf("FindUsedBlobs returned error: %v", err) } @@ -154,7 +154,7 @@ func BenchmarkFindUsedBlobs(b *testing.B) { for i := 0; i < b.N; i++ { blobs := restic.NewBlobSet() - err := restic.FindUsedBlobs(context.TODO(), repo, *sn.Tree, blobs) + err := restic.FindUsedBlobs(context.TODO(), repo, restic.IDs{*sn.Tree}, blobs, nil) if err != nil { b.Error(err) }