From 4bdd59b4ad3e4b0c703973892fcf0041ca95cf0c Mon Sep 17 00:00:00 2001
From: Alexander Neumann <alexander@bumpern.de>
Date: Sun, 7 Aug 2016 21:57:31 +0200
Subject: [PATCH] Index: Add DuplicateBlobs()

---
 src/restic/index/index.go      | 19 +++++++++++++++++++
 src/restic/index/index_test.go | 15 +++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/src/restic/index/index.go b/src/restic/index/index.go
index ffb5272d..f53981ab 100644
--- a/src/restic/index/index.go
+++ b/src/restic/index/index.go
@@ -147,3 +147,22 @@ func Load(repo *repository.Repository) (*Index, error) {
 
 	return idx, nil
 }
+
+// DuplicateBlobs returns a list of blobs that are stored more than once in the
+// repo.
+func (idx *Index) DuplicateBlobs() (dups map[pack.Handle]int) {
+	dups = make(map[pack.Handle]int)
+	seen := pack.NewBlobSet()
+
+	for _, p := range idx.Packs {
+		for _, entry := range p.Entries {
+			h := pack.Handle{ID: entry.ID, Type: entry.Type}
+			if seen.Has(h) {
+				dups[h]++
+			}
+			seen.Insert(h)
+		}
+	}
+
+	return dups
+}
diff --git a/src/restic/index/index_test.go b/src/restic/index/index_test.go
index 307a1c32..b0d39abe 100644
--- a/src/restic/index/index_test.go
+++ b/src/restic/index/index_test.go
@@ -154,3 +154,18 @@ func BenchmarkIndexNew(b *testing.B) {
 		}
 	}
 }
+
+func TestIndexDuplicateBlobs(t *testing.T) {
+	repo, cleanup := createFilledRepo(t, 3, 0.05)
+	defer cleanup()
+
+	idx, err := New(repo)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	dups := idx.DuplicateBlobs()
+	if len(dups) == 0 {
+		t.Errorf("no duplicate blobs found")
+	}
+}