@cryptotaxi247 / kubo / commits / c6daf934e

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 '