fix(diff): modify diff logic and comment
License: MIT Signed-off-by: Overbool <overbool.xu@gmail.com>
Overbool committed
Sep 22, 2018 at 09:58 UTC
c6daf934ea355b6115ec7222e00aef969ef1783a
2 files changed
+28
-25
dagutils/diff.go
+25
-22
@@ -95,29 +95,23 @@ func ApplyChange(ctx context.Context, ds ipld.DAGService, nd *dag.ProtoNode, cs
95
}
96
97
// Diff returns a set of changes that transform node 'a' into node 'b'.
98
-// It supports two nodes forms: ProtoNode and RawNode. Because we treat
99
-// the nodes as IPLD nodes as long as possible and only convert them
100
-// to ProtoNode when necessary: when we need to remove links, and at that point
101
-// (if they have links to remove) we know they are not raw nodes.
98
+// It only traverses links in the following cases:
99
+// 1. two node's links number are greater than 0.
100
+// 2. both of two nodes are ProtoNode.
101
+// Otherwise, it compares the cid and emits a Mod change object.
102
func Diff(ctx context.Context, ds ipld.DAGService, a, b ipld.Node) ([]*Change, error) {
103
// Base case where both nodes are leaves, just compare
104
// their CIDs.
105
if len(a.Links()) == 0 && len(b.Links()) == 0 {
106
- if a.Cid().Equals(b.Cid()) {
107
- return []*Change{}, nil
108
- }
109
- return []*Change{
110
- {
111
- Type: Mod,
112
- Before: a.Cid(),
113
- After: b.Cid(),
114
- },
115
- }, nil
106
+ return getChange(a, b)
107
}
108
109
var out []*Change
119
- cleanA := a.Copy()
120
- cleanB := b.Copy()
110
+ cleanA, okA := a.Copy().(*dag.ProtoNode)
111
+ cleanB, okB := b.Copy().(*dag.ProtoNode)
112
+ if !okA || !okB {
113
+ return getChange(a, b)
114
+ }
115
116
// strip out unchanged stuff
117
for _, lnk := range a.Links() {
@@ -146,12 +140,8 @@ func Diff(ctx context.Context, ds ipld.DAGService, a, b ipld.Node) ([]*Change, e
140
out = append(out, subc)
141
}
142
}
149
- if cleanA, ok := cleanA.(*dag.ProtoNode); ok {
150
- cleanA.RemoveNodeLink(l.Name)
151
- }
152
- if cleanB, ok := cleanB.(*dag.ProtoNode); ok {
153
- cleanB.RemoveNodeLink(l.Name)
154
- }
143
+ cleanA.RemoveNodeLink(l.Name)
144
+ cleanB.RemoveNodeLink(l.Name)
145
}
146
}
147
@@ -207,3 +197,16 @@ func MergeDiffs(a, b []*Change) ([]*Change, []Conflict) {
197
}
198
return out, conflicts
199
}
200
+
201
+func getChange(a, b ipld.Node) ([]*Change, error) {
202
+ if a.Cid().Equals(b.Cid()) {
203
+ return []*Change{}, nil
204
+ }
205
+ return []*Change{
206
+ {
207
+ Type: Mod,
208
+ Before: a.Cid(),
209
+ After: b.Cid(),
210
+ },
211
+ }, nil
212
+}
test/sharness/t0052-object-diff.sh
+3
-3
@@ -58,19 +58,19 @@ test_expect_success "diff against self (single file) is empty" '
58
'
59
60
test_expect_success "diff (raw-leaves) against self (single file) is empty" '
61
- ipfs object diff $SINGLE_FILE_RAW $SINGLE_FILE_RAW > diff_raw_out
61
+ ipfs object diff $SINGLE_FILE_RAW $SINGLE_FILE_RAW > diff_raw_out &&
62
printf "" > diff_raw_exp &&
63
test_cmp diff_raw_exp diff_raw_out
64
'
65
66
test_expect_success "diff against self (empty dir) is empty" '
67
- ipfs object diff $EMPTY_DIR $EMPTY_DIR > diff_out
67
+ ipfs object diff $EMPTY_DIR $EMPTY_DIR > diff_out &&
68
printf "" > diff_exp &&
69
test_cmp diff_exp diff_out
70
'
71
72
test_expect_success "diff (raw-leaves) against self (empty dir) is empty" '
73
- ipfs object diff $EMPTY_DIR_RAW $EMPTY_DIR_RAW > diff_raw_out
73
+ ipfs object diff $EMPTY_DIR_RAW $EMPTY_DIR_RAW > diff_raw_out &&
74
printf "" > diff_raw_exp &&
75
test_cmp diff_raw_exp diff_raw_out
76
'