1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-06-23 13:44:27 +08:00

fix(diff): modify diff logic and comment

License: MIT
Signed-off-by: Overbool <overbool.xu@gmail.com>
This commit is contained in:
Overbool
2018-09-22 09:58:12 +08:00
parent 7cda005a5f
commit c6daf934ea
2 changed files with 28 additions and 25 deletions

View File

@ -95,29 +95,23 @@ func ApplyChange(ctx context.Context, ds ipld.DAGService, nd *dag.ProtoNode, cs
} }
// Diff returns a set of changes that transform node 'a' into node 'b'. // Diff returns a set of changes that transform node 'a' into node 'b'.
// It supports two nodes forms: ProtoNode and RawNode. Because we treat // It only traverses links in the following cases:
// the nodes as IPLD nodes as long as possible and only convert them // 1. two node's links number are greater than 0.
// to ProtoNode when necessary: when we need to remove links, and at that point // 2. both of two nodes are ProtoNode.
// (if they have links to remove) we know they are not raw nodes. // Otherwise, it compares the cid and emits a Mod change object.
func Diff(ctx context.Context, ds ipld.DAGService, a, b ipld.Node) ([]*Change, error) { func Diff(ctx context.Context, ds ipld.DAGService, a, b ipld.Node) ([]*Change, error) {
// Base case where both nodes are leaves, just compare // Base case where both nodes are leaves, just compare
// their CIDs. // their CIDs.
if len(a.Links()) == 0 && len(b.Links()) == 0 { if len(a.Links()) == 0 && len(b.Links()) == 0 {
if a.Cid().Equals(b.Cid()) { return getChange(a, b)
return []*Change{}, nil
}
return []*Change{
{
Type: Mod,
Before: a.Cid(),
After: b.Cid(),
},
}, nil
} }
var out []*Change var out []*Change
cleanA := a.Copy() cleanA, okA := a.Copy().(*dag.ProtoNode)
cleanB := b.Copy() cleanB, okB := b.Copy().(*dag.ProtoNode)
if !okA || !okB {
return getChange(a, b)
}
// strip out unchanged stuff // strip out unchanged stuff
for _, lnk := range a.Links() { for _, lnk := range a.Links() {
@ -146,12 +140,8 @@ func Diff(ctx context.Context, ds ipld.DAGService, a, b ipld.Node) ([]*Change, e
out = append(out, subc) out = append(out, subc)
} }
} }
if cleanA, ok := cleanA.(*dag.ProtoNode); ok { cleanA.RemoveNodeLink(l.Name)
cleanA.RemoveNodeLink(l.Name) cleanB.RemoveNodeLink(l.Name)
}
if cleanB, ok := cleanB.(*dag.ProtoNode); ok {
cleanB.RemoveNodeLink(l.Name)
}
} }
} }
@ -207,3 +197,16 @@ func MergeDiffs(a, b []*Change) ([]*Change, []Conflict) {
} }
return out, conflicts return out, conflicts
} }
func getChange(a, b ipld.Node) ([]*Change, error) {
if a.Cid().Equals(b.Cid()) {
return []*Change{}, nil
}
return []*Change{
{
Type: Mod,
Before: a.Cid(),
After: b.Cid(),
},
}, nil
}

View File

@ -58,19 +58,19 @@ test_expect_success "diff against self (single file) is empty" '
' '
test_expect_success "diff (raw-leaves) against self (single file) is empty" ' test_expect_success "diff (raw-leaves) against self (single file) is empty" '
ipfs object diff $SINGLE_FILE_RAW $SINGLE_FILE_RAW > diff_raw_out ipfs object diff $SINGLE_FILE_RAW $SINGLE_FILE_RAW > diff_raw_out &&
printf "" > diff_raw_exp && printf "" > diff_raw_exp &&
test_cmp diff_raw_exp diff_raw_out test_cmp diff_raw_exp diff_raw_out
' '
test_expect_success "diff against self (empty dir) is empty" ' test_expect_success "diff against self (empty dir) is empty" '
ipfs object diff $EMPTY_DIR $EMPTY_DIR > diff_out ipfs object diff $EMPTY_DIR $EMPTY_DIR > diff_out &&
printf "" > diff_exp && printf "" > diff_exp &&
test_cmp diff_exp diff_out test_cmp diff_exp diff_out
' '
test_expect_success "diff (raw-leaves) against self (empty dir) is empty" ' test_expect_success "diff (raw-leaves) against self (empty dir) is empty" '
ipfs object diff $EMPTY_DIR_RAW $EMPTY_DIR_RAW > diff_raw_out ipfs object diff $EMPTY_DIR_RAW $EMPTY_DIR_RAW > diff_raw_out &&
printf "" > diff_raw_exp && printf "" > diff_raw_exp &&
test_cmp diff_raw_exp diff_raw_out test_cmp diff_raw_exp diff_raw_out
' '