-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdedup.go
More file actions
60 lines (54 loc) · 1.5 KB
/
dedup.go
File metadata and controls
60 lines (54 loc) · 1.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package main
import (
"github.com/bertbaron/btrdedup/sys"
"log"
"os"
)
const (
maxSize uint64 = 64 * 1024 * 1024
)
// returns true if deduplication was successfull, false otherwise
func dedup(filenames []string, offset, length uint64) bool {
same := make([]sys.BtrfsSameExtendInfo, 0)
for _, filename := range filenames {
if file, err := os.OpenFile(filename, os.O_RDONLY, 0); err != nil {
log.Printf("Skipping %s, error while opening: %v", filename, err)
} else {
defer file.Close()
same = append(same, sys.BtrfsSameExtendInfo{file, offset})
}
}
if len(same) < 2 {
return false
}
result, err := sys.BtrfsExtendSame(same, length)
if err != nil {
log.Printf("Error while deduplicating %s and %d other files: %v", filenames[0], len(filenames)-1, err)
return false
}
var bytesDeduped uint64 = 0
dataDiffers := false
for _, r := range result {
dataDiffers = dataDiffers || r.DataDiffers
if r.BytesDeduped > bytesDeduped {
bytesDeduped = r.BytesDeduped
}
}
log.Printf("Result for length %d: same=%v, deduped=%d\n", length, !dataDiffers, bytesDeduped)
return !dataDiffers
}
// Returns true if deduplication was successfull
func Dedup(filenames []string, offset, length uint64) {
size := offset + length
max := maxSize / uint64(len(filenames))
same := true
// continue until the data is different
for same && offset < size {
len := size - offset
if len > max {
len = max &^ 0x0FFF // multiple of 4k
}
same = same && dedup(filenames, offset, len)
offset = offset + len
}
}