diff --git a/src/cmds/restic/cmd_rebuild_index.go b/src/cmds/restic/cmd_rebuild_index.go index e4a6c680a..6f6647daa 100644 --- a/src/cmds/restic/cmd_rebuild_index.go +++ b/src/cmds/restic/cmd_rebuild_index.go @@ -1,7 +1,8 @@ package main import ( - "restic/repository" + "restic" + "restic/index" "github.com/spf13/cobra" ) @@ -34,5 +35,47 @@ func runRebuildIndex(gopts GlobalOptions) error { return err } - return repository.RebuildIndex(repo) + done := make(chan struct{}) + defer close(done) + + Verbosef("counting files in repo\n") + + var packs uint64 + for _ = range repo.List(restic.DataFile, done) { + packs++ + } + + bar := newProgressMax(!gopts.Quiet, packs, "packs") + idx, err := index.New(repo, bar) + if err != nil { + return err + } + + Verbosef("listing old index files\n") + var supersedes restic.IDs + for id := range repo.List(restic.IndexFile, done) { + supersedes = append(supersedes, id) + } + + id, err := idx.Save(repo, supersedes) + if err != nil { + return err + } + + Verbosef("saved new index as %v\n", id.Str()) + + Verbosef("remove %d old index files\n", len(supersedes)) + + for _, id := range supersedes { + err := repo.Backend().Remove(restic.Handle{ + Type: restic.IndexFile, + Name: id.String(), + }) + + if err != nil { + Warnf("error deleting old index %v: %v\n", id.Str(), err) + } + } + + return nil } diff --git a/src/restic/repository/index_rebuild.go b/src/restic/repository/index_rebuild.go deleted file mode 100644 index fcfc3027f..000000000 --- a/src/restic/repository/index_rebuild.go +++ /dev/null @@ -1,66 +0,0 @@ -package repository - -import ( - "fmt" - "os" - "restic" - "restic/debug" - "restic/list" - "restic/worker" -) - -// RebuildIndex lists all packs in the repo, writes a new index and removes all -// old indexes. This operation should only be done with an exclusive lock in -// place. -func RebuildIndex(repo restic.Repository) error { - debug.Log("start rebuilding index") - - done := make(chan struct{}) - defer close(done) - - ch := make(chan worker.Job) - go list.AllPacks(repo, ch, done) - - idx := NewIndex() - for job := range ch { - id := job.Data.(restic.ID) - - if job.Error != nil { - fmt.Fprintf(os.Stderr, "error for pack %v: %v\n", id, job.Error) - continue - } - - res := job.Result.(list.Result) - - for _, entry := range res.Entries() { - pb := restic.PackedBlob{ - Blob: entry, - PackID: res.PackID(), - } - idx.Store(pb) - } - } - - oldIndexes := restic.NewIDSet() - for id := range repo.List(restic.IndexFile, done) { - idx.AddToSupersedes(id) - oldIndexes.Insert(id) - } - - id, err := SaveIndex(repo, idx) - if err != nil { - debug.Log("error saving index: %v", err) - return err - } - debug.Log("new index saved as %v", id.Str()) - - for indexID := range oldIndexes { - h := restic.Handle{Type: restic.IndexFile, Name: indexID.String()} - err := repo.Backend().Remove(h) - if err != nil { - fmt.Fprintf(os.Stderr, "unable to remove index %v: %v\n", indexID.Str(), err) - } - } - - return nil -} diff --git a/src/restic/repository/repack_test.go b/src/restic/repository/repack_test.go index 6d910c97b..619454336 100644 --- a/src/restic/repository/repack_test.go +++ b/src/restic/repository/repack_test.go @@ -4,6 +4,7 @@ import ( "io" "math/rand" "restic" + "restic/index" "restic/repository" "testing" ) @@ -144,8 +145,24 @@ func saveIndex(t *testing.T, repo restic.Repository) { } func rebuildIndex(t *testing.T, repo restic.Repository) { - if err := repository.RebuildIndex(repo); err != nil { - t.Fatalf("error rebuilding index: %v", err) + idx, err := index.New(repo, nil) + if err != nil { + t.Fatal(err) + } + + for id := range repo.List(restic.IndexFile, nil) { + err = repo.Backend().Remove(restic.Handle{ + Type: restic.IndexFile, + Name: id.String(), + }) + if err != nil { + t.Fatal(err) + } + } + + _, err = idx.Save(repo, nil) + if err != nil { + t.Fatal(err) } }