From 5808fe2edd800834efcf793dd2ad649456e75171 Mon Sep 17 00:00:00 2001 From: Mildred Ki'Lya Date: Mon, 26 Oct 2015 17:13:44 +0100 Subject: [PATCH 01/12] Remove usage of merkledag.Link.Node pointer outside of merkledag This prepares for inclusion of IPLD where the Node pointer won't be there. License: MIT Signed-off-by: Mildred Ki'Lya --- core/commands/ls.go | 5 +++-- core/commands/unixfs/ls.go | 6 ++++-- merkledag/node.go | 21 +++++++++++++++++++++ path/resolver.go | 22 ++++++---------------- 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/core/commands/ls.go b/core/commands/ls.go index 2007d4059..5aa3b6513 100644 --- a/core/commands/ls.go +++ b/core/commands/ls.go @@ -77,12 +77,13 @@ Displays the links an IPFS or IPNS object(s) contains, with the following format Links: make([]LsLink, len(dagnode.Links)), } for j, link := range dagnode.Links { - link.Node, err = link.GetNode(req.Context(), node.DAG) + var linkNode *merkledag.Node + linkNode, err = link.GetNode(req.Context(), node.DAG) if err != nil { res.SetError(err, cmds.ErrNormal) return } - d, err := unixfs.FromBytes(link.Node.Data) + d, err := unixfs.FromBytes(linkNode.Data) if err != nil { res.SetError(err, cmds.ErrNormal) return diff --git a/core/commands/unixfs/ls.go b/core/commands/unixfs/ls.go index 98c54de58..fd44e4389 100644 --- a/core/commands/unixfs/ls.go +++ b/core/commands/unixfs/ls.go @@ -12,6 +12,7 @@ import ( path "github.com/ipfs/go-ipfs/path" unixfs "github.com/ipfs/go-ipfs/unixfs" unixfspb "github.com/ipfs/go-ipfs/unixfs/pb" + merkledag "github.com/ipfs/go-ipfs/merkledag" ) type LsLink struct { @@ -104,12 +105,13 @@ size is the IPFS link size. links := make([]LsLink, len(merkleNode.Links)) output.Objects[hash].Links = links for i, link := range merkleNode.Links { - link.Node, err = link.GetNode(ctx, node.DAG) + var linkNode *merkledag.Node + linkNode, err = link.GetNode(ctx, node.DAG) if err != nil { res.SetError(err, cmds.ErrNormal) return } - d, err := unixfs.FromBytes(link.Node.Data) + d, err := unixfs.FromBytes(linkNode.Data) if err != nil { res.SetError(err, cmds.ErrNormal) return diff --git a/merkledag/node.go b/merkledag/node.go index b5e95f81b..ee21e5180 100644 --- a/merkledag/node.go +++ b/merkledag/node.go @@ -2,6 +2,7 @@ package merkledag import ( "fmt" + "time" "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context" @@ -85,6 +86,26 @@ func (l *Link) GetNode(ctx context.Context, serv DAGService) (*Node, error) { return serv.Get(ctx, key.Key(l.Hash)) } +// GetNodeAndCache return the MDAG Node that the link points to and store a +// pointer to that node along with the link to speed up further retrivals. A +// timeout is to be specified to avoid taking too much time. +func (l *Link) GetNodeAndCache(ctx context.Context, serv DAGService, timeout time.Duration) (*Node, error) { + if l.Node == nil { + if timeout != 0 { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, time.Minute) + defer cancel() + } + nd, err := serv.Get(ctx, key.Key(l.Hash)) + if err != nil { + return nil, err + } + l.Node = nd + } + + return l.Node, nil +} + // AddNodeLink adds a link to another node. func (n *Node) AddNodeLink(name string, that *Node) error { n.encoded = nil diff --git a/path/resolver.go b/path/resolver.go index 10368bbfd..d5a6745e1 100644 --- a/path/resolver.go +++ b/path/resolver.go @@ -111,37 +111,27 @@ func (s *Resolver) ResolveLinks(ctx context.Context, ndd *merkledag.Node, names // for each of the path components for _, name := range names { - var next key.Key var nlink *merkledag.Link // for each of the links in nd, the current object for _, link := range nd.Links { if link.Name == name { - next = key.Key(link.Hash) nlink = link break } } - if next == "" { + if nlink == nil || len(nlink.Hash) == 0 { n, _ := nd.Multihash() return result, ErrNoLink{Name: name, Node: n} } - if nlink.Node == nil { - // fetch object for link and assign to nd - ctx, cancel := context.WithTimeout(ctx, time.Minute) - defer cancel() - var err error - nd, err = s.DAG.Get(ctx, next) - if err != nil { - return append(result, nd), err - } - nlink.Node = nd - } else { - nd = nlink.Node + var err error + nd, err = nlink.GetNodeAndCache(ctx, s.DAG, time.Minute) + if err != nil { + return append(result, nd), err } - result = append(result, nlink.Node) + result = append(result, nd) } return result, nil } From 1f820dc2356275b521561622bc649e541a53a532 Mon Sep 17 00:00:00 2001 From: Mildred Ki'Lya Date: Mon, 26 Oct 2015 22:47:04 +0100 Subject: [PATCH 02/12] path/resolver.go: Handle timeout here License: MIT Signed-off-by: Mildred Ki'Lya --- merkledag/node.go | 13 ++++++------- path/resolver.go | 8 +++++++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/merkledag/node.go b/merkledag/node.go index ee21e5180..ed503d312 100644 --- a/merkledag/node.go +++ b/merkledag/node.go @@ -2,7 +2,6 @@ package merkledag import ( "fmt" - "time" "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context" @@ -77,6 +76,11 @@ func MakeLink(n *Node) (*Link, error) { }, nil } +// GetCachedNode returns the MDAG Node that was cached, or nil +func (l *Link) GetCachedNode() *Node { + return l.Node +} + // GetNode returns the MDAG Node that this link points to func (l *Link) GetNode(ctx context.Context, serv DAGService) (*Node, error) { if l.Node != nil { @@ -89,13 +93,8 @@ func (l *Link) GetNode(ctx context.Context, serv DAGService) (*Node, error) { // GetNodeAndCache return the MDAG Node that the link points to and store a // pointer to that node along with the link to speed up further retrivals. A // timeout is to be specified to avoid taking too much time. -func (l *Link) GetNodeAndCache(ctx context.Context, serv DAGService, timeout time.Duration) (*Node, error) { +func (l *Link) GetNodeAndCache(ctx context.Context, serv DAGService) (*Node, error) { if l.Node == nil { - if timeout != 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(ctx, time.Minute) - defer cancel() - } nd, err := serv.Get(ctx, key.Key(l.Hash)) if err != nil { return nil, err diff --git a/path/resolver.go b/path/resolver.go index d5a6745e1..4bb11ecf0 100644 --- a/path/resolver.go +++ b/path/resolver.go @@ -125,8 +125,14 @@ func (s *Resolver) ResolveLinks(ctx context.Context, ndd *merkledag.Node, names return result, ErrNoLink{Name: name, Node: n} } + if nlink.GetCachedNode() == nil { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, time.Minute) + defer cancel() + } + var err error - nd, err = nlink.GetNodeAndCache(ctx, s.DAG, time.Minute) + nd, err = nlink.GetNodeAndCache(ctx, s.DAG) if err != nil { return append(result, nd), err } From 3b729b200bec3df8b4772b8318d148ccd3ad0ed4 Mon Sep 17 00:00:00 2001 From: Mildred Ki'Lya Date: Fri, 27 Nov 2015 20:22:09 +0100 Subject: [PATCH 03/12] merkledag: Make Node.Unmarshal() private License: MIT Signed-off-by: Mildred Ki'Lya --- merkledag/coding.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/merkledag/coding.go b/merkledag/coding.go index 1c57125fb..302e75151 100644 --- a/merkledag/coding.go +++ b/merkledag/coding.go @@ -13,9 +13,9 @@ import ( // for now, we use a PBNode intermediate thing. // because native go objects are nice. -// Unmarshal decodes raw data into a *Node instance. +// unmarshal decodes raw data into a *Node instance. // The conversion uses an intermediate PBNode. -func (n *Node) Unmarshal(encoded []byte) error { +func (n *Node) unmarshal(encoded []byte) error { var pbn pb.PBNode if err := pbn.Unmarshal(encoded); err != nil { return fmt.Errorf("Unmarshal failed. %v", err) @@ -87,7 +87,7 @@ func (n *Node) Encoded(force bool) ([]byte, error) { // Decoded decodes raw data and returns a new Node instance. func Decoded(encoded []byte) (*Node, error) { n := new(Node) - err := n.Unmarshal(encoded) + err := n.unmarshal(encoded) if err != nil { return nil, fmt.Errorf("incorrectly formatted merkledag node: %s", err) } From 67c59d871ea3b2bd098965d76ba0fad5b64c9813 Mon Sep 17 00:00:00 2001 From: Mildred Ki'Lya Date: Fri, 5 Feb 2016 23:31:37 +0100 Subject: [PATCH 04/12] Rename Decoded into DecodeProtobuf This function work only with protocol buffer encoding. To make this clear, rename the function. License: MIT Signed-off-by: Mildred Ki'Lya --- core/commands/object/object.go | 2 +- merkledag/coding.go | 2 +- merkledag/merkledag.go | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/commands/object/object.go b/core/commands/object/object.go index 27f32daac..86091ad07 100644 --- a/core/commands/object/object.go +++ b/core/commands/object/object.go @@ -486,7 +486,7 @@ func objectPut(n *core.IpfsNode, input io.Reader, encoding string) (*Object, err } case objectEncodingProtobuf: - dagnode, err = dag.Decoded(data) + dagnode, err = dag.DecodeProtobuf(data) case objectEncodingXML: node := new(Node) diff --git a/merkledag/coding.go b/merkledag/coding.go index 302e75151..884b0277c 100644 --- a/merkledag/coding.go +++ b/merkledag/coding.go @@ -85,7 +85,7 @@ func (n *Node) Encoded(force bool) ([]byte, error) { } // Decoded decodes raw data and returns a new Node instance. -func Decoded(encoded []byte) (*Node, error) { +func DecodeProtobuf(encoded []byte) (*Node, error) { n := new(Node) err := n.unmarshal(encoded) if err != nil { diff --git a/merkledag/merkledag.go b/merkledag/merkledag.go index aebc370ad..0152a5afc 100644 --- a/merkledag/merkledag.go +++ b/merkledag/merkledag.go @@ -104,7 +104,7 @@ func (n *dagService) Get(ctx context.Context, k key.Key) (*Node, error) { return nil, err } - return Decoded(b.Data) + return DecodeProtobuf(b.Data) } // Remove deletes the given node and all of its children from the BlockService @@ -167,7 +167,7 @@ func (ds *dagService) GetMany(ctx context.Context, keys []key.Key) <-chan *NodeO } return } - nd, err := Decoded(b.Data) + nd, err := DecodeProtobuf(b.Data) if err != nil { out <- &NodeOption{Err: err} return From 28bc3ee8ee105ac988bdb4f65d10e6962e36d5eb Mon Sep 17 00:00:00 2001 From: Mildred Ki'Lya Date: Wed, 24 Feb 2016 08:34:32 +0100 Subject: [PATCH 05/12] merkledag: make Link.Node (the node cache) a private field License: MIT Signed-off-by: Mildred Ki'Lya --- merkledag/merkledag.go | 8 ++++---- merkledag/node.go | 22 +++++++++++----------- pin/set.go | 3 +-- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/merkledag/merkledag.go b/merkledag/merkledag.go index 0152a5afc..83d363677 100644 --- a/merkledag/merkledag.go +++ b/merkledag/merkledag.go @@ -77,8 +77,8 @@ func (n *dagService) AddRecursive(nd *Node) error { } for _, link := range nd.Links { - if link.Node != nil { - err := n.AddRecursive(link.Node) + if link.node != nil { + err := n.AddRecursive(link.node) if err != nil { return err } @@ -110,8 +110,8 @@ func (n *dagService) Get(ctx context.Context, k key.Key) (*Node, error) { // Remove deletes the given node and all of its children from the BlockService func (n *dagService) RemoveRecursive(nd *Node) error { for _, l := range nd.Links { - if l.Node != nil { - n.RemoveRecursive(l.Node) + if l.node != nil { + n.RemoveRecursive(l.node) } } k, err := nd.Key() diff --git a/merkledag/node.go b/merkledag/node.go index ed503d312..e0e282dba 100644 --- a/merkledag/node.go +++ b/merkledag/node.go @@ -5,8 +5,8 @@ import ( "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context" - mh "gx/ipfs/QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku/go-multihash" key "github.com/ipfs/go-ipfs/blocks/key" + mh "gx/ipfs/QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku/go-multihash" ) var ErrLinkNotFound = fmt.Errorf("no link by that name") @@ -50,7 +50,7 @@ type Link struct { Hash mh.Multihash // a ptr to the actual node for graph manipulation - Node *Node + node *Node } type LinkSlice []*Link @@ -78,13 +78,13 @@ func MakeLink(n *Node) (*Link, error) { // GetCachedNode returns the MDAG Node that was cached, or nil func (l *Link) GetCachedNode() *Node { - return l.Node + return l.node } // GetNode returns the MDAG Node that this link points to func (l *Link) GetNode(ctx context.Context, serv DAGService) (*Node, error) { - if l.Node != nil { - return l.Node, nil + if l.node != nil { + return l.node, nil } return serv.Get(ctx, key.Key(l.Hash)) @@ -94,15 +94,15 @@ func (l *Link) GetNode(ctx context.Context, serv DAGService) (*Node, error) { // pointer to that node along with the link to speed up further retrivals. A // timeout is to be specified to avoid taking too much time. func (l *Link) GetNodeAndCache(ctx context.Context, serv DAGService) (*Node, error) { - if l.Node == nil { + if l.node == nil { nd, err := serv.Get(ctx, key.Key(l.Hash)) if err != nil { return nil, err } - l.Node = nd + l.node = nd } - return l.Node, nil + return l.node, nil } // AddNodeLink adds a link to another node. @@ -112,7 +112,7 @@ func (n *Node) AddNodeLink(name string, that *Node) error { lnk, err := MakeLink(that) lnk.Name = name - lnk.Node = that + lnk.node = that if err != nil { return err } @@ -142,7 +142,7 @@ func (n *Node) AddRawLink(name string, l *Link) error { Name: name, Size: l.Size, Hash: l.Hash, - Node: l.Node, + node: l.node, }) return nil @@ -178,7 +178,7 @@ func (n *Node) GetNodeLink(name string) (*Link, error) { Name: l.Name, Size: l.Size, Hash: l.Hash, - Node: l.Node, + node: l.node, }, nil } } diff --git a/pin/set.go b/pin/set.go index f3d825818..669fa7a60 100644 --- a/pin/set.go +++ b/pin/set.go @@ -11,10 +11,10 @@ import ( "sort" "unsafe" - "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto" "github.com/ipfs/go-ipfs/blocks/key" "github.com/ipfs/go-ipfs/merkledag" "github.com/ipfs/go-ipfs/pin/internal/pb" + "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto" "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context" ) @@ -172,7 +172,6 @@ func storeItems(ctx context.Context, dag merkledag.DAGService, estimatedLen uint Name: "", Hash: childKey.ToMultihash(), Size: size, - Node: child, } n.Links[int(h%defaultFanout)] = l } From 7fc9205709c26a2dfb26997c283380a16874a5df Mon Sep 17 00:00:00 2001 From: Mildred Ki'Lya Date: Wed, 24 Feb 2016 08:41:55 +0100 Subject: [PATCH 06/12] path/resolver.go: simplify ResolveLinks() License: MIT Signed-off-by: Mildred Ki'Lya --- merkledag/node.go | 15 --------------- path/resolver.go | 31 +++++++++---------------------- 2 files changed, 9 insertions(+), 37 deletions(-) diff --git a/merkledag/node.go b/merkledag/node.go index e0e282dba..b07d64b5b 100644 --- a/merkledag/node.go +++ b/merkledag/node.go @@ -90,21 +90,6 @@ func (l *Link) GetNode(ctx context.Context, serv DAGService) (*Node, error) { return serv.Get(ctx, key.Key(l.Hash)) } -// GetNodeAndCache return the MDAG Node that the link points to and store a -// pointer to that node along with the link to speed up further retrivals. A -// timeout is to be specified to avoid taking too much time. -func (l *Link) GetNodeAndCache(ctx context.Context, serv DAGService) (*Node, error) { - if l.node == nil { - nd, err := serv.Get(ctx, key.Key(l.Hash)) - if err != nil { - return nil, err - } - l.node = nd - } - - return l.node, nil -} - // AddNodeLink adds a link to another node. func (n *Node) AddNodeLink(name string, that *Node) error { n.encoded = nil diff --git a/path/resolver.go b/path/resolver.go index 4bb11ecf0..3eaf345ff 100644 --- a/path/resolver.go +++ b/path/resolver.go @@ -111,33 +111,20 @@ func (s *Resolver) ResolveLinks(ctx context.Context, ndd *merkledag.Node, names // for each of the path components for _, name := range names { - var nlink *merkledag.Link - // for each of the links in nd, the current object - for _, link := range nd.Links { - if link.Name == name { - nlink = link - break - } - } + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, time.Minute) + defer cancel() - if nlink == nil || len(nlink.Hash) == 0 { + nextnode, err := nd.GetLinkedNode(ctx, s.DAG, name) + if err == merkledag.ErrLinkNotFound { n, _ := nd.Multihash() return result, ErrNoLink{Name: name, Node: n} + } else if err != nil { + return append(result, nextnode), err } - if nlink.GetCachedNode() == nil { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(ctx, time.Minute) - defer cancel() - } - - var err error - nd, err = nlink.GetNodeAndCache(ctx, s.DAG) - if err != nil { - return append(result, nd), err - } - - result = append(result, nd) + nd = nextnode + result = append(result, nextnode) } return result, nil } From 1f5b76ac1825c4d62bf47d0ae2f0f21bdfd40e4a Mon Sep 17 00:00:00 2001 From: Mildred Ki'Lya Date: Thu, 25 Feb 2016 07:34:56 +0100 Subject: [PATCH 07/12] Remove GetCachedNode() License: MIT Signed-off-by: Mildred Ki'Lya --- merkledag/node.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/merkledag/node.go b/merkledag/node.go index b07d64b5b..0a17ccca5 100644 --- a/merkledag/node.go +++ b/merkledag/node.go @@ -76,11 +76,6 @@ func MakeLink(n *Node) (*Link, error) { }, nil } -// GetCachedNode returns the MDAG Node that was cached, or nil -func (l *Link) GetCachedNode() *Node { - return l.node -} - // GetNode returns the MDAG Node that this link points to func (l *Link) GetNode(ctx context.Context, serv DAGService) (*Node, error) { if l.node != nil { From 7c11fe57cb45fb58862cb06dce7e4f71a2c5d15c Mon Sep 17 00:00:00 2001 From: Mildred Ki'Lya Date: Thu, 25 Feb 2016 07:35:28 +0100 Subject: [PATCH 08/12] Rename Encoded() to EncodeProtobuf() License: MIT Signed-off-by: Mildred Ki'Lya --- merkledag/coding.go | 4 ++-- merkledag/merkledag.go | 4 ++-- merkledag/merkledag_test.go | 6 +++--- merkledag/node.go | 8 ++++---- unixfs/mod/dagmodifier.go | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/merkledag/coding.go b/merkledag/coding.go index 884b0277c..3d7b8381c 100644 --- a/merkledag/coding.go +++ b/merkledag/coding.go @@ -68,9 +68,9 @@ func (n *Node) getPBNode() *pb.PBNode { return pbn } -// Encoded returns the encoded raw data version of a Node instance. +// EncodeProtobuf returns the encoded raw data version of a Node instance. // It may use a cached encoded version, unless the force flag is given. -func (n *Node) Encoded(force bool) ([]byte, error) { +func (n *Node) EncodeProtobuf(force bool) ([]byte, error) { sort.Stable(LinkSlice(n.Links)) // keep links sorted if n.encoded == nil || force { var err error diff --git a/merkledag/merkledag.go b/merkledag/merkledag.go index 83d363677..792194002 100644 --- a/merkledag/merkledag.go +++ b/merkledag/merkledag.go @@ -49,7 +49,7 @@ func (n *dagService) Add(nd *Node) (key.Key, error) { return "", fmt.Errorf("dagService is nil") } - d, err := nd.Encoded(false) + d, err := nd.EncodeProtobuf(false) if err != nil { return "", err } @@ -313,7 +313,7 @@ type Batch struct { } func (t *Batch) Add(nd *Node) (key.Key, error) { - d, err := nd.Encoded(false) + d, err := nd.EncodeProtobuf(false) if err != nil { return "", err } diff --git a/merkledag/merkledag_test.go b/merkledag/merkledag_test.go index 91bc2c0f7..6816aad52 100644 --- a/merkledag/merkledag_test.go +++ b/merkledag/merkledag_test.go @@ -64,7 +64,7 @@ func TestNode(t *testing.T) { fmt.Println("-", l.Name, l.Size, l.Hash) } - e, err := n.Encoded(false) + e, err := n.EncodeProtobuf(false) if err != nil { t.Error(err) } else { @@ -96,9 +96,9 @@ func TestNode(t *testing.T) { } func SubtestNodeStat(t *testing.T, n *Node) { - enc, err := n.Encoded(true) + enc, err := n.EncodeProtobuf(true) if err != nil { - t.Error("n.Encoded(true) failed") + t.Error("n.EncodeProtobuf(true) failed") return } diff --git a/merkledag/node.go b/merkledag/node.go index 0a17ccca5..5fa05b41a 100644 --- a/merkledag/node.go +++ b/merkledag/node.go @@ -203,7 +203,7 @@ func (n *Node) UpdateNodeLink(name string, that *Node) (*Node, error) { // Size returns the total size of the data addressed by node, // including the total sizes of references. func (n *Node) Size() (uint64, error) { - b, err := n.Encoded(false) + b, err := n.EncodeProtobuf(false) if err != nil { return 0, err } @@ -217,7 +217,7 @@ func (n *Node) Size() (uint64, error) { // Stat returns statistics on the node. func (n *Node) Stat() (*NodeStat, error) { - enc, err := n.Encoded(false) + enc, err := n.EncodeProtobuf(false) if err != nil { return nil, err } @@ -244,8 +244,8 @@ func (n *Node) Stat() (*NodeStat, error) { // Multihash hashes the encoded data of this node. func (n *Node) Multihash() (mh.Multihash, error) { - // Note: Encoded generates the hash and puts it in n.cached. - _, err := n.Encoded(false) + // Note: EncodeProtobuf generates the hash and puts it in n.cached. + _, err := n.EncodeProtobuf(false) if err != nil { return nil, err } diff --git a/unixfs/mod/dagmodifier.go b/unixfs/mod/dagmodifier.go index 33f082417..0f5866716 100644 --- a/unixfs/mod/dagmodifier.go +++ b/unixfs/mod/dagmodifier.go @@ -258,7 +258,7 @@ func (dm *DagModifier) modifyDag(node *mdag.Node, offset uint64, data io.Reader) node.Links[i].Hash = mh.Multihash(k) // Recache serialized node - _, err = node.Encoded(true) + _, err = node.EncodeProtobuf(true) if err != nil { return "", false, err } @@ -489,7 +489,7 @@ func dagTruncate(ctx context.Context, nd *mdag.Node, size uint64, ds mdag.DAGSer nd.Data = d // invalidate cache and recompute serialized data - _, err = nd.Encoded(true) + _, err = nd.EncodeProtobuf(true) if err != nil { return nil, err } From b3c9922c7b14757353dcdb2c1f4903e010682c91 Mon Sep 17 00:00:00 2001 From: Mildred Ki'Lya Date: Sun, 28 Feb 2016 11:30:26 +0100 Subject: [PATCH 09/12] merkledag: Remove unused AddRecursive and RemoveRecursive License: MIT Signed-off-by: Mildred Ki'Lya --- core/corehttp/gateway_handler.go | 12 ++++++---- core/corehttp/gateway_test.go | 17 +++++++++++-- merkledag/merkledag.go | 36 ---------------------------- merkledag/merkledag_test.go | 41 +------------------------------- path/resolver_test.go | 8 ++++--- pin/pin_test.go | 6 ++++- 6 files changed, 34 insertions(+), 86 deletions(-) diff --git a/core/corehttp/gateway_handler.go b/core/corehttp/gateway_handler.go index ca7938346..54ef9c7b7 100644 --- a/core/corehttp/gateway_handler.go +++ b/core/corehttp/gateway_handler.go @@ -453,16 +453,20 @@ func (i *gatewayHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { } newnode := pathNodes[len(pathNodes)-1] - for i := len(pathNodes) - 2; i >= 0; i-- { - newnode, err = pathNodes[i].UpdateNodeLink(components[i], newnode) + for j := len(pathNodes) - 2; j >= 0; j-- { + if _, err := i.node.DAG.Add(newnode); err != nil { + webError(w, "Could not add node", err, http.StatusInternalServerError) + return + } + newnode, err = pathNodes[j].UpdateNodeLink(components[j], newnode) if err != nil { webError(w, "Could not update node links", err, http.StatusInternalServerError) return } } - if err := i.node.DAG.AddRecursive(newnode); err != nil { - webError(w, "Could not add recursively new node", err, http.StatusInternalServerError) + if _, err := i.node.DAG.Add(newnode); err != nil { + webError(w, "Could not add root node", err, http.StatusInternalServerError) return } diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 551fbf6f5..1e3a1c6f7 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -181,7 +181,12 @@ func TestIPNSHostnameRedirect(t *testing.T) { t.Fatal(err) } - err = n.DAG.AddRecursive(dagn1) + _, err = n.DAG.Add(dagn2) + if err != nil { + t.Fatal(err) + } + + _, err = n.DAG.Add(dagn1) if err != nil { t.Fatal(err) } @@ -266,7 +271,15 @@ func TestIPNSHostnameBacklinks(t *testing.T) { t.Fatal(err) } - err = n.DAG.AddRecursive(dagn1) + _, err = n.DAG.Add(dagn3) + if err != nil { + t.Fatal(err) + } + _, err = n.DAG.Add(dagn2) + if err != nil { + t.Fatal(err) + } + _, err = n.DAG.Add(dagn1) if err != nil { t.Fatal(err) } diff --git a/merkledag/merkledag.go b/merkledag/merkledag.go index 792194002..3466aafc2 100644 --- a/merkledag/merkledag.go +++ b/merkledag/merkledag.go @@ -18,10 +18,8 @@ var ErrNotFound = fmt.Errorf("merkledag: not found") // DAGService is an IPFS Merkle DAG service. type DAGService interface { Add(*Node) (key.Key, error) - AddRecursive(*Node) error Get(context.Context, key.Key) (*Node, error) Remove(*Node) error - RemoveRecursive(*Node) error // GetDAG returns, in order, all the single leve child // nodes of the passed in node. @@ -68,26 +66,6 @@ func (n *dagService) Batch() *Batch { return &Batch{ds: n, MaxSize: 8 * 1024 * 1024} } -// AddRecursive adds the given node and all child nodes to the BlockService -func (n *dagService) AddRecursive(nd *Node) error { - _, err := n.Add(nd) - if err != nil { - log.Info("AddRecursive Error: %s\n", err) - return err - } - - for _, link := range nd.Links { - if link.node != nil { - err := n.AddRecursive(link.node) - if err != nil { - return err - } - } - } - - return nil -} - // Get retrieves a node from the dagService, fetching the block in the BlockService func (n *dagService) Get(ctx context.Context, k key.Key) (*Node, error) { if n == nil { @@ -107,20 +85,6 @@ func (n *dagService) Get(ctx context.Context, k key.Key) (*Node, error) { return DecodeProtobuf(b.Data) } -// Remove deletes the given node and all of its children from the BlockService -func (n *dagService) RemoveRecursive(nd *Node) error { - for _, l := range nd.Links { - if l.node != nil { - n.RemoveRecursive(l.node) - } - } - k, err := nd.Key() - if err != nil { - return err - } - return n.Blocks.DeleteBlock(k) -} - func (n *dagService) Remove(nd *Node) error { k, err := nd.Key() if err != nil { diff --git a/merkledag/merkledag_test.go b/merkledag/merkledag_test.go index 6816aad52..8137496d8 100644 --- a/merkledag/merkledag_test.go +++ b/merkledag/merkledag_test.go @@ -181,7 +181,7 @@ func runBatchFetchTest(t *testing.T, read io.Reader) { t.Fatal(err) } - err = dagservs[0].AddRecursive(root) + _, err = dagservs[0].Add(root) if err != nil { t.Fatal(err) } @@ -232,45 +232,6 @@ func runBatchFetchTest(t *testing.T, read io.Reader) { } } } -func TestRecursiveAdd(t *testing.T) { - a := &Node{Data: []byte("A")} - b := &Node{Data: []byte("B")} - c := &Node{Data: []byte("C")} - d := &Node{Data: []byte("D")} - e := &Node{Data: []byte("E")} - - err := a.AddNodeLink("blah", b) - if err != nil { - t.Fatal(err) - } - - err = b.AddNodeLink("foo", c) - if err != nil { - t.Fatal(err) - } - - err = b.AddNodeLink("bar", d) - if err != nil { - t.Fatal(err) - } - - err = d.AddNodeLink("baz", e) - if err != nil { - t.Fatal(err) - } - - dsp := getDagservAndPinner(t) - err = dsp.ds.AddRecursive(a) - if err != nil { - t.Fatal(err) - } - - assertCanGet(t, dsp.ds, a) - assertCanGet(t, dsp.ds, b) - assertCanGet(t, dsp.ds, c) - assertCanGet(t, dsp.ds, d) - assertCanGet(t, dsp.ds, e) -} func assertCanGet(t *testing.T, ds DAGService, n *Node) { k, err := n.Key() diff --git a/path/resolver_test.go b/path/resolver_test.go index 7f5f756c4..fe8155a85 100644 --- a/path/resolver_test.go +++ b/path/resolver_test.go @@ -39,9 +39,11 @@ func TestRecurivePathResolution(t *testing.T) { t.Fatal(err) } - err = dagService.AddRecursive(a) - if err != nil { - t.Fatal(err) + for _, n := range []*merkledag.Node{a, b, c} { + _, err = dagService.Add(n) + if err != nil { + t.Fatal(err) + } } aKey, err := a.Key() diff --git a/pin/pin_test.go b/pin/pin_test.go index 9eb61acef..09371fc6e 100644 --- a/pin/pin_test.go +++ b/pin/pin_test.go @@ -104,7 +104,11 @@ func TestPinnerBasic(t *testing.T) { d.AddNodeLink("e", e) // Must be in dagserv for unpin to work - err = dserv.AddRecursive(d) + _, err = dserv.Add(e) + if err != nil { + t.Fatal(err) + } + _, err = dserv.Add(d) if err != nil { t.Fatal(err) } From 8f8020e86f0dcbf4cb43d74db8df84cbbce60618 Mon Sep 17 00:00:00 2001 From: Mildred Ki'Lya Date: Sun, 28 Feb 2016 11:40:08 +0100 Subject: [PATCH 10/12] merkledag: Remove cached Node.node License: MIT Signed-off-by: Mildred Ki'Lya --- merkledag/node.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/merkledag/node.go b/merkledag/node.go index 5fa05b41a..d44285159 100644 --- a/merkledag/node.go +++ b/merkledag/node.go @@ -48,9 +48,6 @@ type Link struct { // multihash of the target object Hash mh.Multihash - - // a ptr to the actual node for graph manipulation - node *Node } type LinkSlice []*Link @@ -78,10 +75,6 @@ func MakeLink(n *Node) (*Link, error) { // GetNode returns the MDAG Node that this link points to func (l *Link) GetNode(ctx context.Context, serv DAGService) (*Node, error) { - if l.node != nil { - return l.node, nil - } - return serv.Get(ctx, key.Key(l.Hash)) } @@ -92,7 +85,6 @@ func (n *Node) AddNodeLink(name string, that *Node) error { lnk, err := MakeLink(that) lnk.Name = name - lnk.node = that if err != nil { return err } @@ -122,7 +114,6 @@ func (n *Node) AddRawLink(name string, l *Link) error { Name: name, Size: l.Size, Hash: l.Hash, - node: l.node, }) return nil @@ -158,7 +149,6 @@ func (n *Node) GetNodeLink(name string) (*Link, error) { Name: l.Name, Size: l.Size, Hash: l.Hash, - node: l.node, }, nil } } From b1f77e9e7f85786704b2316817b8b5c53883f0fe Mon Sep 17 00:00:00 2001 From: Mildred Ki'Lya Date: Wed, 2 Mar 2016 09:54:42 +0100 Subject: [PATCH 11/12] Improve error reporting and fix pin/set_test.go License: MIT Signed-off-by: Mildred Ki'Lya --- merkledag/coding.go | 2 +- merkledag/merkledag.go | 8 ++++++-- pin/set.go | 4 ++-- pin/set_test.go | 21 +++++++++++++++++++++ 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/merkledag/coding.go b/merkledag/coding.go index 3d7b8381c..10c30727a 100644 --- a/merkledag/coding.go +++ b/merkledag/coding.go @@ -27,7 +27,7 @@ func (n *Node) unmarshal(encoded []byte) error { n.Links[i] = &Link{Name: l.GetName(), Size: l.GetTsize()} h, err := mh.Cast(l.GetHash()) if err != nil { - return fmt.Errorf("Link hash is not valid multihash. %v", err) + return fmt.Errorf("Link hash #%d is not valid multihash. %v", i, err) } n.Links[i].Hash = h } diff --git a/merkledag/merkledag.go b/merkledag/merkledag.go index 3466aafc2..df6fa4187 100644 --- a/merkledag/merkledag.go +++ b/merkledag/merkledag.go @@ -79,10 +79,14 @@ func (n *dagService) Get(ctx context.Context, k key.Key) (*Node, error) { if err == bserv.ErrNotFound { return nil, ErrNotFound } - return nil, err + return nil, fmt.Errorf("Failed to get block for %s: %v", k.B58String(), err) } - return DecodeProtobuf(b.Data) + res, err := DecodeProtobuf(b.Data) + if err != nil { + return nil, fmt.Errorf("Failed to decode Protocol Buffers: %v", err) + } + return res, nil } func (n *dagService) Remove(nd *Node) error { diff --git a/pin/set.go b/pin/set.go index 669fa7a60..fec38e254 100644 --- a/pin/set.go +++ b/pin/set.go @@ -271,12 +271,12 @@ func loadSet(ctx context.Context, dag merkledag.DAGService, root *merkledag.Node 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, err + 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, err + return nil, fmt.Errorf("Failed to get node from link %s: %v", name, err) } refcounts := make(map[key.Key]uint64) diff --git a/pin/set_test.go b/pin/set_test.go index 3ef7ce51b..b25f91a96 100644 --- a/pin/set_test.go +++ b/pin/set_test.go @@ -11,6 +11,8 @@ import ( "github.com/ipfs/go-ipfs/blockservice" "github.com/ipfs/go-ipfs/exchange/offline" "github.com/ipfs/go-ipfs/merkledag" + mh "gx/ipfs/QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku/go-multihash" + u "gx/ipfs/QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1/go-ipfs-util" "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context" ) @@ -31,6 +33,14 @@ func TestMultisetRoundtrip(t *testing.T) { dag := merkledag.NewDAGService(bserv) fn := func(m map[key.Key]uint16) bool { + // Convert invalid multihash from input to valid ones + for k, v := range m { + if _, err := mh.Cast([]byte(k)); err != nil { + delete(m, k) + m[key.Key(u.Hash([]byte(k)))] = v + } + } + // Generate a smaller range for refcounts than full uint64, as // otherwise this just becomes overly cpu heavy, splitting it // out into too many items. That means we need to convert to @@ -43,6 +53,17 @@ func TestMultisetRoundtrip(t *testing.T) { if err != nil { t.Fatalf("storing multiset: %v", err) } + + // Check that the node n is in the DAG + k, err := n.Key() + if err != nil { + t.Fatalf("Could not get key: %v", err) + } + _, err = dag.Get(ctx, k) + if err != nil { + t.Fatalf("Could not get node: %v", err) + } + root := &merkledag.Node{} const linkName = "dummylink" if err := root.AddNodeLink(linkName, n); err != nil { From 683b81760e807571cebfa300e818a63ac51b8c6e Mon Sep 17 00:00:00 2001 From: Mildred Ki'Lya Date: Wed, 2 Mar 2016 22:32:21 +0100 Subject: [PATCH 12/12] merkledag/traverse: Fix tests after node pointer removal License: MIT Signed-off-by: Mildred Ki'Lya --- merkledag/traverse/traverse_test.go | 140 ++++++++++++++++------------ 1 file changed, 79 insertions(+), 61 deletions(-) diff --git a/merkledag/traverse/traverse_test.go b/merkledag/traverse/traverse_test.go index ff57909a3..5ca906a51 100644 --- a/merkledag/traverse/traverse_test.go +++ b/merkledag/traverse/traverse_test.go @@ -6,12 +6,14 @@ import ( "testing" mdag "github.com/ipfs/go-ipfs/merkledag" + mdagtest "github.com/ipfs/go-ipfs/merkledag/test" ) func TestDFSPreNoSkip(t *testing.T) { - opts := Options{Order: DFSPre} + ds := mdagtest.Mock() + opts := Options{Order: DFSPre, DAG: ds} - testWalkOutputs(t, newFan(t), opts, []byte(` + testWalkOutputs(t, newFan(t, ds), opts, []byte(` 0 /a 1 /a/aa 1 /a/ab @@ -19,7 +21,7 @@ func TestDFSPreNoSkip(t *testing.T) { 1 /a/ad `)) - testWalkOutputs(t, newLinkedList(t), opts, []byte(` + testWalkOutputs(t, newLinkedList(t, ds), opts, []byte(` 0 /a 1 /a/aa 2 /a/aa/aaa @@ -27,7 +29,7 @@ func TestDFSPreNoSkip(t *testing.T) { 4 /a/aa/aaa/aaaa/aaaaa `)) - testWalkOutputs(t, newBinaryTree(t), opts, []byte(` + testWalkOutputs(t, newBinaryTree(t, ds), opts, []byte(` 0 /a 1 /a/aa 2 /a/aa/aaa @@ -37,7 +39,7 @@ func TestDFSPreNoSkip(t *testing.T) { 2 /a/ab/abb `)) - testWalkOutputs(t, newBinaryDAG(t), opts, []byte(` + testWalkOutputs(t, newBinaryDAG(t, ds), opts, []byte(` 0 /a 1 /a/aa 2 /a/aa/aaa @@ -73,9 +75,10 @@ func TestDFSPreNoSkip(t *testing.T) { } func TestDFSPreSkip(t *testing.T) { - opts := Options{Order: DFSPre, SkipDuplicates: true} + ds := mdagtest.Mock() + opts := Options{Order: DFSPre, SkipDuplicates: true, DAG: ds} - testWalkOutputs(t, newFan(t), opts, []byte(` + testWalkOutputs(t, newFan(t, ds), opts, []byte(` 0 /a 1 /a/aa 1 /a/ab @@ -83,7 +86,7 @@ func TestDFSPreSkip(t *testing.T) { 1 /a/ad `)) - testWalkOutputs(t, newLinkedList(t), opts, []byte(` + testWalkOutputs(t, newLinkedList(t, ds), opts, []byte(` 0 /a 1 /a/aa 2 /a/aa/aaa @@ -91,7 +94,7 @@ func TestDFSPreSkip(t *testing.T) { 4 /a/aa/aaa/aaaa/aaaaa `)) - testWalkOutputs(t, newBinaryTree(t), opts, []byte(` + testWalkOutputs(t, newBinaryTree(t, ds), opts, []byte(` 0 /a 1 /a/aa 2 /a/aa/aaa @@ -101,7 +104,7 @@ func TestDFSPreSkip(t *testing.T) { 2 /a/ab/abb `)) - testWalkOutputs(t, newBinaryDAG(t), opts, []byte(` + testWalkOutputs(t, newBinaryDAG(t, ds), opts, []byte(` 0 /a 1 /a/aa 2 /a/aa/aaa @@ -111,9 +114,10 @@ func TestDFSPreSkip(t *testing.T) { } func TestDFSPostNoSkip(t *testing.T) { - opts := Options{Order: DFSPost} + ds := mdagtest.Mock() + opts := Options{Order: DFSPost, DAG: ds} - testWalkOutputs(t, newFan(t), opts, []byte(` + testWalkOutputs(t, newFan(t, ds), opts, []byte(` 1 /a/aa 1 /a/ab 1 /a/ac @@ -121,7 +125,7 @@ func TestDFSPostNoSkip(t *testing.T) { 0 /a `)) - testWalkOutputs(t, newLinkedList(t), opts, []byte(` + testWalkOutputs(t, newLinkedList(t, ds), opts, []byte(` 4 /a/aa/aaa/aaaa/aaaaa 3 /a/aa/aaa/aaaa 2 /a/aa/aaa @@ -129,7 +133,7 @@ func TestDFSPostNoSkip(t *testing.T) { 0 /a `)) - testWalkOutputs(t, newBinaryTree(t), opts, []byte(` + testWalkOutputs(t, newBinaryTree(t, ds), opts, []byte(` 2 /a/aa/aaa 2 /a/aa/aab 1 /a/aa @@ -139,7 +143,7 @@ func TestDFSPostNoSkip(t *testing.T) { 0 /a `)) - testWalkOutputs(t, newBinaryDAG(t), opts, []byte(` + testWalkOutputs(t, newBinaryDAG(t, ds), opts, []byte(` 4 /a/aa/aaa/aaaa/aaaaa 4 /a/aa/aaa/aaaa/aaaaa 3 /a/aa/aaa/aaaa @@ -175,9 +179,10 @@ func TestDFSPostNoSkip(t *testing.T) { } func TestDFSPostSkip(t *testing.T) { - opts := Options{Order: DFSPost, SkipDuplicates: true} + ds := mdagtest.Mock() + opts := Options{Order: DFSPost, SkipDuplicates: true, DAG: ds} - testWalkOutputs(t, newFan(t), opts, []byte(` + testWalkOutputs(t, newFan(t, ds), opts, []byte(` 1 /a/aa 1 /a/ab 1 /a/ac @@ -185,7 +190,7 @@ func TestDFSPostSkip(t *testing.T) { 0 /a `)) - testWalkOutputs(t, newLinkedList(t), opts, []byte(` + testWalkOutputs(t, newLinkedList(t, ds), opts, []byte(` 4 /a/aa/aaa/aaaa/aaaaa 3 /a/aa/aaa/aaaa 2 /a/aa/aaa @@ -193,7 +198,7 @@ func TestDFSPostSkip(t *testing.T) { 0 /a `)) - testWalkOutputs(t, newBinaryTree(t), opts, []byte(` + testWalkOutputs(t, newBinaryTree(t, ds), opts, []byte(` 2 /a/aa/aaa 2 /a/aa/aab 1 /a/aa @@ -203,7 +208,7 @@ func TestDFSPostSkip(t *testing.T) { 0 /a `)) - testWalkOutputs(t, newBinaryDAG(t), opts, []byte(` + testWalkOutputs(t, newBinaryDAG(t, ds), opts, []byte(` 4 /a/aa/aaa/aaaa/aaaaa 3 /a/aa/aaa/aaaa 2 /a/aa/aaa @@ -213,9 +218,10 @@ func TestDFSPostSkip(t *testing.T) { } func TestBFSNoSkip(t *testing.T) { - opts := Options{Order: BFS} + ds := mdagtest.Mock() + opts := Options{Order: BFS, DAG: ds} - testWalkOutputs(t, newFan(t), opts, []byte(` + testWalkOutputs(t, newFan(t, ds), opts, []byte(` 0 /a 1 /a/aa 1 /a/ab @@ -223,7 +229,7 @@ func TestBFSNoSkip(t *testing.T) { 1 /a/ad `)) - testWalkOutputs(t, newLinkedList(t), opts, []byte(` + testWalkOutputs(t, newLinkedList(t, ds), opts, []byte(` 0 /a 1 /a/aa 2 /a/aa/aaa @@ -231,7 +237,7 @@ func TestBFSNoSkip(t *testing.T) { 4 /a/aa/aaa/aaaa/aaaaa `)) - testWalkOutputs(t, newBinaryTree(t), opts, []byte(` + testWalkOutputs(t, newBinaryTree(t, ds), opts, []byte(` 0 /a 1 /a/aa 1 /a/ab @@ -241,7 +247,7 @@ func TestBFSNoSkip(t *testing.T) { 2 /a/ab/abb `)) - testWalkOutputs(t, newBinaryDAG(t), opts, []byte(` + testWalkOutputs(t, newBinaryDAG(t, ds), opts, []byte(` 0 /a 1 /a/aa 1 /a/aa @@ -277,9 +283,10 @@ func TestBFSNoSkip(t *testing.T) { } func TestBFSSkip(t *testing.T) { - opts := Options{Order: BFS, SkipDuplicates: true} + ds := mdagtest.Mock() + opts := Options{Order: BFS, SkipDuplicates: true, DAG: ds} - testWalkOutputs(t, newFan(t), opts, []byte(` + testWalkOutputs(t, newFan(t, ds), opts, []byte(` 0 /a 1 /a/aa 1 /a/ab @@ -287,7 +294,7 @@ func TestBFSSkip(t *testing.T) { 1 /a/ad `)) - testWalkOutputs(t, newLinkedList(t), opts, []byte(` + testWalkOutputs(t, newLinkedList(t, ds), opts, []byte(` 0 /a 1 /a/aa 2 /a/aa/aaa @@ -295,7 +302,7 @@ func TestBFSSkip(t *testing.T) { 4 /a/aa/aaa/aaaa/aaaaa `)) - testWalkOutputs(t, newBinaryTree(t), opts, []byte(` + testWalkOutputs(t, newBinaryTree(t, ds), opts, []byte(` 0 /a 1 /a/aa 1 /a/ab @@ -305,7 +312,7 @@ func TestBFSSkip(t *testing.T) { 2 /a/ab/abb `)) - testWalkOutputs(t, newBinaryDAG(t), opts, []byte(` + testWalkOutputs(t, newBinaryDAG(t, ds), opts, []byte(` 0 /a 1 /a/aa 2 /a/aa/aaa @@ -341,57 +348,68 @@ func testWalkOutputs(t *testing.T, root *mdag.Node, opts Options, expect []byte) } } -func newFan(t *testing.T) *mdag.Node { +func newFan(t *testing.T, ds mdag.DAGService) *mdag.Node { a := &mdag.Node{Data: []byte("/a")} - addChild(t, a, "aa") - addChild(t, a, "ab") - addChild(t, a, "ac") - addChild(t, a, "ad") + addLink(t, ds, a, child(t, ds, a, "aa")) + addLink(t, ds, a, child(t, ds, a, "ab")) + addLink(t, ds, a, child(t, ds, a, "ac")) + addLink(t, ds, a, child(t, ds, a, "ad")) return a } -func newLinkedList(t *testing.T) *mdag.Node { +func newLinkedList(t *testing.T, ds mdag.DAGService) *mdag.Node { a := &mdag.Node{Data: []byte("/a")} - aa := addChild(t, a, "aa") - aaa := addChild(t, aa, "aaa") - aaaa := addChild(t, aaa, "aaaa") - addChild(t, aaaa, "aaaaa") + aa := child(t, ds, a, "aa") + aaa := child(t, ds, aa, "aaa") + aaaa := child(t, ds, aaa, "aaaa") + aaaaa := child(t, ds, aaaa, "aaaaa") + addLink(t, ds, aaaa, aaaaa) + addLink(t, ds, aaa, aaaa) + addLink(t, ds, aa, aaa) + addLink(t, ds, a, aa) return a } -func newBinaryTree(t *testing.T) *mdag.Node { +func newBinaryTree(t *testing.T, ds mdag.DAGService) *mdag.Node { a := &mdag.Node{Data: []byte("/a")} - aa := addChild(t, a, "aa") - ab := addChild(t, a, "ab") - addChild(t, aa, "aaa") - addChild(t, aa, "aab") - addChild(t, ab, "aba") - addChild(t, ab, "abb") + aa := child(t, ds, a, "aa") + ab := child(t, ds, a, "ab") + addLink(t, ds, aa, child(t, ds, aa, "aaa")) + addLink(t, ds, aa, child(t, ds, aa, "aab")) + addLink(t, ds, ab, child(t, ds, ab, "aba")) + addLink(t, ds, ab, child(t, ds, ab, "abb")) + addLink(t, ds, a, aa) + addLink(t, ds, a, ab) return a } -func newBinaryDAG(t *testing.T) *mdag.Node { +func newBinaryDAG(t *testing.T, ds mdag.DAGService) *mdag.Node { a := &mdag.Node{Data: []byte("/a")} - aa := addChild(t, a, "aa") - aaa := addChild(t, aa, "aaa") - aaaa := addChild(t, aaa, "aaaa") - aaaaa := addChild(t, aaaa, "aaaaa") - addLink(t, a, aa) - addLink(t, aa, aaa) - addLink(t, aaa, aaaa) - addLink(t, aaaa, aaaaa) + aa := child(t, ds, a, "aa") + aaa := child(t, ds, aa, "aaa") + aaaa := child(t, ds, aaa, "aaaa") + aaaaa := child(t, ds, aaaa, "aaaaa") + addLink(t, ds, aaaa, aaaaa) + addLink(t, ds, aaaa, aaaaa) + addLink(t, ds, aaa, aaaa) + addLink(t, ds, aaa, aaaa) + addLink(t, ds, aa, aaa) + addLink(t, ds, aa, aaa) + addLink(t, ds, a, aa) + addLink(t, ds, a, aa) return a } -func addLink(t *testing.T, a, b *mdag.Node) { +func addLink(t *testing.T, ds mdag.DAGService, a, b *mdag.Node) { to := string(a.Data) + "2" + string(b.Data) + if _, err := ds.Add(b); err != nil { + t.Error(err) + } if err := a.AddNodeLink(to, b); err != nil { t.Error(err) } } -func addChild(t *testing.T, a *mdag.Node, name string) *mdag.Node { - c := &mdag.Node{Data: []byte(string(a.Data) + "/" + name)} - addLink(t, a, c) - return c +func child(t *testing.T, ds mdag.DAGService, a *mdag.Node, name string) *mdag.Node { + return &mdag.Node{Data: []byte(string(a.Data) + "/" + name)} }