예제 #1
0
파일: coding.go 프로젝트: ipfs/go-iprs
// nodeType returns the record node's type link value.
func nodeType(nd *dag.Node) ([]byte, error) {
	tl, err := nd.GetNodeLink(linkType)
	if err != nil {
		return nil, fmt.Errorf("invalid record. failed to get link %s (%s)", linkType, err)
	}

	return tl.Hash, nil
}
예제 #2
0
func Diff(ctx context.Context, ds dag.DAGService, a, b *dag.Node) []*Change {
	if len(a.Links) == 0 && len(b.Links) == 0 {
		ak, _ := a.Key()
		bk, _ := b.Key()
		return []*Change{
			&Change{
				Type:   Mod,
				Before: ak,
				After:  bk,
			},
		}
	}

	var out []*Change
	clean_a := a.Copy()
	clean_b := b.Copy()

	// strip out unchanged stuff
	for _, lnk := range a.Links {
		l, err := b.GetNodeLink(lnk.Name)
		if err == nil {
			if bytes.Equal(l.Hash, lnk.Hash) {
				// no change... ignore it
			} else {
				anode, _ := lnk.GetNode(ctx, ds)
				bnode, _ := l.GetNode(ctx, ds)
				sub := Diff(ctx, ds, anode, bnode)

				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: key.Key(lnk.Hash),
		})
	}
	for _, lnk := range clean_b.Links {
		out = append(out, &Change{
			Type:  Add,
			Path:  lnk.Name,
			After: key.Key(lnk.Hash),
		})
	}

	return out
}
예제 #3
0
파일: thread.go 프로젝트: utamaro/core
func (t *Thread) toRecord(n *merkledag.Node) (*record.Record, error) {
	var sign []byte
	if _, err := n.GetNodeLink("sign"); err == nil {
		s, err := t.self.GetLinkedNode(n, "sign")
		if log.If(err) {
			return nil, err
		}
		sign = s.Data
	}
	cont, err := t.self.GetLinkedNode(n, "contents")
	if log.If(err) {
		return nil, err
	}
	r, err := record.FromDAGNode(t.self, cont, sign)
	log.If(err)
	return r, err
}
예제 #4
0
파일: set.go 프로젝트: yanghongkjxy/go-ipfs
func loadSet(ctx context.Context, dag merkledag.DAGService, root *merkledag.Node, name string, internalKeys keyObserver) ([]key.Key, error) {
	l, err := root.GetNodeLink(name)
	if err != nil {
		return nil, err
	}
	internalKeys(key.Key(l.Hash))
	n, err := l.GetNode(ctx, dag)
	if err != nil {
		return nil, err
	}

	var res []key.Key
	walk := func(buf []byte, idx int, link *merkledag.Link) error {
		res = append(res, key.Key(link.Hash))
		return nil
	}
	if err := walkItems(ctx, dag, n, walk, internalKeys); err != nil {
		return nil, err
	}
	return res, nil
}
예제 #5
0
파일: set.go 프로젝트: yanghongkjxy/go-ipfs
func loadMultiset(ctx context.Context, dag merkledag.DAGService, root *merkledag.Node, name string, internalKeys keyObserver) (map[key.Key]uint64, error) {
	l, err := root.GetNodeLink(name)
	if err != nil {
		return nil, fmt.Errorf("Failed to get link %s: %v", name, err)
	}
	internalKeys(key.Key(l.Hash))
	n, err := l.GetNode(ctx, dag)
	if err != nil {
		return nil, fmt.Errorf("Failed to get node from link %s: %v", name, err)
	}

	refcounts := make(map[key.Key]uint64)
	walk := func(buf []byte, idx int, link *merkledag.Link) error {
		var r refcount
		r.ReadFromIdx(buf, idx)
		refcounts[key.Key(link.Hash)] += uint64(r)
		return nil
	}
	if err := walkItems(ctx, dag, n, walk, internalKeys); err != nil {
		return nil, err
	}
	return refcounts, nil
}
예제 #6
0
파일: object.go 프로젝트: bit4bit/go-ipfs
func insertNodeAtPath(ctx context.Context, ds dag.DAGService, root *dag.Node, path []string, toinsert key.Key) (*dag.Node, error) {
	if len(path) == 1 {
		return addLink(ctx, ds, root, path[0], toinsert)
	}

	child, err := root.GetNodeLink(path[0])
	if err != nil {
		return nil, err
	}

	nd, err := child.GetNode(ctx, ds)
	if err != nil {
		return nil, err
	}

	ndprime, err := insertNodeAtPath(ctx, ds, nd, path[1:], toinsert)
	if err != nil {
		return nil, err
	}

	err = root.RemoveNodeLink(path[0])
	if err != nil {
		return nil, err
	}

	err = root.AddNodeLinkClean(path[0], ndprime)
	if err != nil {
		return nil, err
	}

	_, err = ds.Add(root)
	if err != nil {
		return nil, err
	}

	return root, nil
}