func loadSet(ctx context.Context, dag merkledag.DAGService, root *merkledag.ProtoNode, name string, internalKeys keyObserver) ([]*cid.Cid, error) { l, err := root.GetNodeLink(name) if err != nil { return nil, err } lnkc := l.Cid internalKeys(lnkc) n, err := l.GetNode(ctx, dag) if err != nil { return nil, err } pbn, ok := n.(*merkledag.ProtoNode) if !ok { return nil, merkledag.ErrNotProtobuf } var res []*cid.Cid walk := func(idx int, link *node.Link) error { res = append(res, link.Cid) return nil } if err := walkItems(ctx, dag, pbn, walk, internalKeys); err != nil { return nil, err } return res, nil }
func Diff(ctx context.Context, ds dag.DAGService, a, b *dag.ProtoNode) ([]*Change, error) { if len(a.Links()) == 0 && len(b.Links()) == 0 { return []*Change{ &Change{ Type: Mod, Before: a.Cid(), After: b.Cid(), }, }, nil } var out []*Change clean_a := a.Copy().(*dag.ProtoNode) clean_b := b.Copy().(*dag.ProtoNode) // strip out unchanged stuff for _, lnk := range a.Links() { l, err := b.GetNodeLink(lnk.Name) if err == nil { if l.Cid.Equals(lnk.Cid) { // no change... ignore it } else { anode, err := lnk.GetNode(ctx, ds) if err != nil { return nil, err } bnode, err := l.GetNode(ctx, ds) if err != nil { return nil, err } anodepb, ok := anode.(*dag.ProtoNode) if !ok { return nil, dag.ErrNotProtobuf } bnodepb, ok := bnode.(*dag.ProtoNode) if !ok { return nil, dag.ErrNotProtobuf } sub, err := Diff(ctx, ds, anodepb, bnodepb) if err != nil { return nil, err } for _, subc := range sub { subc.Path = path.Join(lnk.Name, subc.Path) out = append(out, subc) } } clean_a.RemoveNodeLink(l.Name) clean_b.RemoveNodeLink(l.Name) } } for _, lnk := range clean_a.Links() { out = append(out, &Change{ Type: Remove, Path: lnk.Name, Before: lnk.Cid, }) } for _, lnk := range clean_b.Links() { out = append(out, &Change{ Type: Add, Path: lnk.Name, After: lnk.Cid, }) } return out, nil }