aboutsummaryrefslogtreecommitdiff
path: root/internal/dup/dup_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/dup/dup_test.go')
-rw-r--r--internal/dup/dup_test.go49
1 files changed, 49 insertions, 0 deletions
diff --git a/internal/dup/dup_test.go b/internal/dup/dup_test.go
index 8984336..a616118 100644
--- a/internal/dup/dup_test.go
+++ b/internal/dup/dup_test.go
@@ -577,3 +577,52 @@ func TestThreeCopiesWithOverlappingExtraDirKeepOne(t *testing.T) {
}
}
}
+
+// TestLookupWalksAClassOnce: every member of a content class elects the
+// same original, so the class is worth computing once. Walking the size
+// group again for every member makes a directory of N copies cost N^2
+// comparisons - 8000 identical files took 35 s of it - and the walk takes
+// the index's lock at every step, so more workers made it slower rather
+// than faster. This counts the walks: one per class, not one per file.
+func TestLookupWalksAClassOnce(t *testing.T) {
+ d := t.TempDir()
+ const n = 12
+ var files []scan.File
+ for i := 0; i < n; i++ {
+ // Two classes of one size, so the size group cannot be the thing
+ // being memoised.
+ body := "the same bytes for all of these"
+ if i%2 == 1 {
+ body = "different bytes, identical size"
+ }
+ files = append(files, put(t, d, fmt.Sprintf("f%02d.bin", i), []byte(body), i))
+ }
+ x, errs := NewIndex(files, nil)
+ if len(errs) > 0 {
+ t.Fatal(errs)
+ }
+ for _, f := range files {
+ lookup(t, x, f)
+ }
+ if x.walks > 2 {
+ t.Errorf("identicalTo ran %d times for 2 content classes over %d files; want one walk per class", x.walks, n)
+ }
+
+ // The answers must be what they were before memoising: one original
+ // per class, and that original is not itself a duplicate.
+ dups := 0
+ origs := map[string]int{}
+ for _, f := range files {
+ orig, isDup := lookup(t, x, f)
+ if isDup {
+ dups++
+ }
+ origs[orig]++
+ }
+ if dups != n-2 {
+ t.Errorf("%d duplicates over two classes of %d files, want %d", dups, n, n-2)
+ }
+ if len(origs) != 2 {
+ t.Errorf("the two classes elected %d originals, want 2", len(origs))
+ }
+}