-
Notifications
You must be signed in to change notification settings - Fork 352
/
diff.go
96 lines (83 loc) · 1.9 KB
/
diff.go
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package metastore
import (
"sort"
"github.com/treeverse/lakefs/pkg/catalog"
)
type MetaDiff struct {
PartitionDiff catalog.Differences
ColumnsDiff catalog.Differences
}
type CompareResult int
const (
ItemLess CompareResult = iota
ItemSameKey
ItemSame
ItemGreater
)
type Collection interface {
sort.Interface
Value(i int) interface{}
Name(i int) string
CompareWith(i int, v interface{}, j int) CompareResult
}
type DiffCallbackFn func(difference catalog.DifferenceType, iter interface{}, name string) error
func DiffIterable(iterA, iterB Collection, callbackFn DiffCallbackFn) error {
sort.Sort(iterA)
sort.Sort(iterB)
i, j, sizeA, sizeB := 0, 0, iterA.Len(), iterB.Len()
for i < sizeA && j < sizeB {
switch iterA.CompareWith(i, iterB, j) {
case ItemSameKey:
err := callbackFn(catalog.DifferenceTypeChanged, iterA.Value(i), iterA.Name(i))
if err != nil {
return err
}
i++
j++
case ItemSame:
i++
j++
case ItemGreater:
err := callbackFn(catalog.DifferenceTypeRemoved, iterB.Value(j), iterB.Name(j))
if err != nil {
return err
}
j++
case ItemLess:
err := callbackFn(catalog.DifferenceTypeAdded, iterA.Value(i), iterA.Name(i))
if err != nil {
return err
}
i++
}
}
for j < sizeB {
err := callbackFn(catalog.DifferenceTypeRemoved, iterB.Value(j), iterB.Name(j))
if err != nil {
return err
}
j++
}
for i < sizeA {
err := callbackFn(catalog.DifferenceTypeAdded, iterA.Value(i), iterA.Name(i))
if err != nil {
return err
}
i++
}
return nil
}
func Diff(iterA, iterB Collection) (catalog.Differences, error) {
var diff catalog.Differences
err := DiffIterable(iterA, iterB, func(diffType catalog.DifferenceType, _ interface{}, name string) error {
diff = append(diff, catalog.Difference{
Type: diffType,
DBEntry: catalog.DBEntry{Path: name},
})
return nil
})
if err != nil {
return nil, err
}
return diff, nil
}