diff --git a/src/restic/index/index.go b/src/restic/index/index.go index d2f0d9856..0bd87be3e 100644 --- a/src/restic/index/index.go +++ b/src/restic/index/index.go @@ -189,6 +189,26 @@ func (idx *Index) AddPack(id backend.ID, size int64, entries []pack.Blob) error return nil } +// RemovePack deletes a pack from the index. +func (idx *Index) RemovePack(id backend.ID) error { + if _, ok := idx.Packs[id]; !ok { + return fmt.Errorf("pack %v not found in the index", id.Str()) + } + + for _, blob := range idx.Packs[id].Entries { + h := pack.Handle{ID: blob.ID, Type: blob.Type} + idx.Blobs[h].Packs.Delete(id) + + if len(idx.Blobs[h].Packs) == 0 { + delete(idx.Blobs, h) + } + } + + delete(idx.Packs, id) + + return nil +} + // DuplicateBlobs returns a list of blobs that are stored more than once in the // repo. func (idx *Index) DuplicateBlobs() (dups pack.BlobSet) { diff --git a/src/restic/index/index_test.go b/src/restic/index/index_test.go index 825a24400..580fffccb 100644 --- a/src/restic/index/index_test.go +++ b/src/restic/index/index_test.go @@ -239,6 +239,44 @@ func TestIndexSave(t *testing.T) { } } +func TestIndexAddRemovePack(t *testing.T) { + repo, cleanup := createFilledRepo(t, 3, 0) + defer cleanup() + + idx, err := Load(repo) + if err != nil { + t.Fatalf("Load() returned error %v", err) + } + + done := make(chan struct{}) + defer close(done) + + packID := <-repo.List(backend.Data, done) + + t.Logf("selected pack %v", packID.Str()) + + blobs := idx.Packs[packID].Entries + + idx.RemovePack(packID) + + if _, ok := idx.Packs[packID]; ok { + t.Errorf("removed pack %v found in index.Packs", packID.Str()) + } + + for _, blob := range blobs { + h := pack.Handle{ID: blob.ID, Type: blob.Type} + _, err := idx.FindBlob(h) + if err == nil { + t.Errorf("removed blob %v found in index", h) + } + + if _, ok := idx.Blobs[h]; ok { + t.Errorf("removed blob %v found in index.Blobs", h) + } + } + +} + // example index serialization from doc/Design.md var docExample = []byte(` {