merkledag.go 1.36 KB
Newer Older
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
1 2 3
package merkledag

import (
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
4
	u "github.com/jbenet/go-ipfs/util"
Juan Batiz-Benet's avatar
gofmt  
Juan Batiz-Benet committed
5
	mh "github.com/jbenet/go-multihash"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
6 7
)

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
8 9 10 11
// can't use []byte/Multihash for keys :(
// so have to convert Multihash bytes to string
type NodeMap map[u.Key]*Node

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
12 13
// A node in the IPFS Merkle DAG.
// nodes have opaque data and a set of navigable links.
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
14
type Node struct {
Juan Batiz-Benet's avatar
gofmt  
Juan Batiz-Benet committed
15 16
	Links []*Link
	Data  []byte
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
17 18 19

	// cache encoded/marshaled value
	encoded []byte
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
20 21 22
}

// An IPFS Merkle DAG Link
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
23
type Link struct {
Juan Batiz-Benet's avatar
gofmt  
Juan Batiz-Benet committed
24 25
	// utf string name. should be unique per object
	Name string // utf8
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
26

Juan Batiz-Benet's avatar
gofmt  
Juan Batiz-Benet committed
27 28
	// cumulative size of target object
	Size uint64
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
29

Juan Batiz-Benet's avatar
gofmt  
Juan Batiz-Benet committed
30 31
	// multihash of the target object
	Hash mh.Multihash
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
32 33 34

	// a ptr to the actual node for graph manipulation
	Node *Node
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
35 36
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
func (n *Node) AddNodeLink(name string, that *Node) error {
	s, err := that.Size()
	if err != nil {
		return err
	}

	h, err := that.Multihash()
	if err != nil {
		return err
	}

	n.Links = append(n.Links, &Link{
		Name: name,
		Size: s,
		Hash: h,
	})
	return nil
}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
55

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
56
func (n *Node) Size() (uint64, error) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
57
	b, err := n.Encoded(false)
Juan Batiz-Benet's avatar
gofmt  
Juan Batiz-Benet committed
58 59 60 61
	if err != nil {
		return 0, err
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
62
	s := uint64(len(b))
Juan Batiz-Benet's avatar
gofmt  
Juan Batiz-Benet committed
63 64 65 66
	for _, l := range n.Links {
		s += l.Size
	}
	return s, nil
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
67
}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
68 69 70 71 72 73 74

func (n *Node) Multihash() (mh.Multihash, error) {
	b, err := n.Encoded(false)
	if err != nil {
		return nil, err
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
75
	return u.Hash(b)
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
76
}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
77 78 79 80 81

func (n *Node) Key() (u.Key, error) {
	h, err := n.Multihash()
	return u.Key(h), err
}