Skip to content

Commit

Permalink
merkledag: change 'Node' to be an interface
Browse files Browse the repository at this point in the history
Also change existing 'Node' type to 'ProtoNode' and use that most
everywhere for now. As we move forward with the integration we will try
and use the Node interface in more places that we're currently using
ProtoNode.

License: MIT
Signed-off-by: Jeromy <why@ipfs.io>
  • Loading branch information
whyrusleeping committed Oct 12, 2016
1 parent ada773f commit 4fe144d
Show file tree
Hide file tree
Showing 62 changed files with 850 additions and 546 deletions.
1 change: 0 additions & 1 deletion blocks/blocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
var ErrWrongHash = errors.New("data did not match given hash!")

type Block interface {
Multihash() mh.Multihash
RawData() []byte
Cid() *cid.Cid
String() string
Expand Down
26 changes: 6 additions & 20 deletions blockservice/test/blocks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,8 @@ import (
dssync "gx/ipfs/QmbzuUusHqaLLoNTDEVLcSF6vZDHZDLPC7p4bztRvvkXxU/go-datastore/sync"
)

func newObject(data []byte) *testObject {
return &testObject{
Block: blocks.NewBlock(data),
}
}

type testObject struct {
blocks.Block
}

func (o *testObject) Cid() *cid.Cid {
return cid.NewCidV0(o.Block.Multihash())
func newObject(data []byte) blocks.Block {
return blocks.NewBlock(data)
}

func TestBlocks(t *testing.T) {
Expand All @@ -38,12 +28,8 @@ func TestBlocks(t *testing.T) {
defer bs.Close()

o := newObject([]byte("beep boop"))
h := u.Hash([]byte("beep boop"))
if !bytes.Equal(o.Multihash(), h) {
t.Error("Block Multihash and data multihash not equal")
}

if !o.Cid().Equals(cid.NewCidV0(h)) {
h := cid.NewCidV0(u.Hash([]byte("beep boop")))
if !o.Cid().Equals(h) {
t.Error("Block key and data multihash key not equal")
}

Expand Down Expand Up @@ -74,8 +60,8 @@ func TestBlocks(t *testing.T) {
}
}

func makeObjects(n int) []*testObject {
var out []*testObject
func makeObjects(n int) []blocks.Block {
var out []blocks.Block
for i := 0; i < n; i++ {
out = append(out, newObject([]byte(fmt.Sprintf("object %d", i))))
}
Expand Down
16 changes: 13 additions & 3 deletions core/commands/files/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func statNode(ds dag.DAGService, fsn mfs.FSNode) (*Object, error) {

return &Object{
Hash: c.String(),
Blocks: len(nd.Links),
Blocks: len(nd.Links()),
Size: d.GetFilesize(),
CumulativeSize: cumulsize,
Type: ndtype,
Expand Down Expand Up @@ -245,15 +245,25 @@ var FilesCpCmd = &cmds.Command{
},
}

func getNodeFromPath(ctx context.Context, node *core.IpfsNode, p string) (*dag.Node, error) {
func getNodeFromPath(ctx context.Context, node *core.IpfsNode, p string) (*dag.ProtoNode, error) {
switch {
case strings.HasPrefix(p, "/ipfs/"):
np, err := path.ParsePath(p)
if err != nil {
return nil, err
}

return core.Resolve(ctx, node, np)
nd, err := core.Resolve(ctx, node, np)
if err != nil {
return nil, err
}

pbnd, ok := nd.(*dag.ProtoNode)
if !ok {
return nil, dag.ErrNotProtobuf
}

return pbnd, nil
default:
fsn, err := mfs.Lookup(node.FilesRoot, p)
if err != nil {
Expand Down
9 changes: 8 additions & 1 deletion core/commands/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

cmds "github.com/ipfs/go-ipfs/commands"
core "github.com/ipfs/go-ipfs/core"
dag "github.com/ipfs/go-ipfs/merkledag"
path "github.com/ipfs/go-ipfs/path"
tar "github.com/ipfs/go-ipfs/thirdparty/tar"
uarchive "github.com/ipfs/go-ipfs/unixfs/archive"
Expand Down Expand Up @@ -69,6 +70,12 @@ may also specify the level of compression by specifying '-l=<1-9>'.
return
}

pbnd, ok := dn.(*dag.ProtoNode)
if !ok {
res.SetError(err, cmds.ErrNormal)
return
}

size, err := dn.Size()
if err != nil {
res.SetError(err, cmds.ErrNormal)
Expand All @@ -78,7 +85,7 @@ may also specify the level of compression by specifying '-l=<1-9>'.
res.SetLength(size)

archive, _, _ := req.Option("archive").Bool()
reader, err := uarchive.DagArchive(ctx, dn, p.String(), node.DAG, archive, cmplvl)
reader, err := uarchive.DagArchive(ctx, pbnd, p.String(), node.DAG, archive, cmplvl)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
Expand Down
24 changes: 15 additions & 9 deletions core/commands/ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import (
path "github.com/ipfs/go-ipfs/path"
unixfs "github.com/ipfs/go-ipfs/unixfs"
unixfspb "github.com/ipfs/go-ipfs/unixfs/pb"

cid "gx/ipfs/QmXUuRadqDq5BuFWzVU6VuKaSjTcNm1gNCtLvvP1TJCW4z/go-cid"
)

type LsLink struct {
Expand Down Expand Up @@ -72,7 +70,7 @@ The JSON output contains type information.

paths := req.Arguments()

var dagnodes []*merkledag.Node
var dagnodes []merkledag.Node
for _, fpath := range paths {
dagnode, err := core.Resolve(req.Context(), node, path.Path(fpath))
if err != nil {
Expand All @@ -86,12 +84,12 @@ The JSON output contains type information.
for i, dagnode := range dagnodes {
output[i] = LsObject{
Hash: paths[i],
Links: make([]LsLink, len(dagnode.Links)),
Links: make([]LsLink, len(dagnode.Links())),
}
for j, link := range dagnode.Links {
var linkNode *merkledag.Node
for j, link := range dagnode.Links() {
var linkNode *merkledag.ProtoNode
t := unixfspb.Data_DataType(-1)
linkKey := cid.NewCidV0(link.Hash)
linkKey := link.Cid
if ok, err := node.Blockstore.Has(linkKey); ok && err == nil {
b, err := node.Blockstore.Get(linkKey)
if err != nil {
Expand All @@ -106,11 +104,19 @@ The JSON output contains type information.
}

if linkNode == nil && resolve {
linkNode, err = link.GetNode(req.Context(), node.DAG)
nd, err := link.GetNode(req.Context(), node.DAG)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}

pbnd, ok := nd.(*merkledag.ProtoNode)
if !ok {
res.SetError(merkledag.ErrNotProtobuf, cmds.ErrNormal)
return
}

linkNode = pbnd
}
if linkNode != nil {
d, err := unixfs.FromBytes(linkNode.Data())
Expand All @@ -123,7 +129,7 @@ The JSON output contains type information.
}
output[i].Links[j] = LsLink{
Name: link.Name,
Hash: link.Hash.B58String(),
Hash: link.Cid.String(),
Size: link.Size,
Type: t,
}
Expand Down
15 changes: 14 additions & 1 deletion core/commands/object/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

cmds "github.com/ipfs/go-ipfs/commands"
core "github.com/ipfs/go-ipfs/core"
dag "github.com/ipfs/go-ipfs/merkledag"
dagutils "github.com/ipfs/go-ipfs/merkledag/utils"
path "github.com/ipfs/go-ipfs/path"
)
Expand Down Expand Up @@ -85,7 +86,19 @@ Example:
return
}

changes, err := dagutils.Diff(ctx, node.DAG, obj_a, obj_b)
pbobj_a, ok := obj_a.(*dag.ProtoNode)
if !ok {
res.SetError(dag.ErrNotProtobuf, cmds.ErrNormal)
return
}

pbobj_b, ok := obj_b.(*dag.ProtoNode)
if !ok {
res.SetError(dag.ErrNotProtobuf, cmds.ErrNormal)
return
}

changes, err := dagutils.Diff(ctx, node.DAG, pbobj_a, pbobj_b)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
Expand Down
56 changes: 35 additions & 21 deletions core/commands/object/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import (
"strings"
"text/tabwriter"

mh "gx/ipfs/QmYDds3421prZgqKbLpEK7T9Aa2eVdQ7o3YarX1LVLdP2J/go-multihash"

cmds "github.com/ipfs/go-ipfs/commands"
core "github.com/ipfs/go-ipfs/core"
dag "github.com/ipfs/go-ipfs/merkledag"
path "github.com/ipfs/go-ipfs/path"
ft "github.com/ipfs/go-ipfs/unixfs"

cid "gx/ipfs/QmXUuRadqDq5BuFWzVU6VuKaSjTcNm1gNCtLvvP1TJCW4z/go-cid"
)

// ErrObjectTooLarge is returned when too much data was read from stdin. current limit 2m
Expand Down Expand Up @@ -98,7 +98,14 @@ is the raw data of the object.
res.SetError(err, cmds.ErrNormal)
return
}
res.SetOutput(bytes.NewReader(node.Data()))

pbnode, ok := node.(*dag.ProtoNode)
if !ok {
res.SetError(dag.ErrNotProtobuf, cmds.ErrNormal)
return
}

res.SetOutput(bytes.NewReader(pbnode.Data()))
},
}

Expand Down Expand Up @@ -137,6 +144,7 @@ multihash.
res.SetError(err, cmds.ErrNormal)
return
}

output, err := getOutput(node)
if err != nil {
res.SetError(err, cmds.ErrNormal)
Expand Down Expand Up @@ -201,14 +209,20 @@ This command outputs data in the following encodings:
return
}

pbo, ok := object.(*dag.ProtoNode)
if !ok {
res.SetError(dag.ErrNotProtobuf, cmds.ErrNormal)
return
}

node := &Node{
Links: make([]Link, len(object.Links)),
Data: string(object.Data()),
Links: make([]Link, len(object.Links())),
Data: string(pbo.Data()),
}

for i, link := range object.Links {
for i, link := range object.Links() {
node.Links[i] = Link{
Hash: link.Hash.B58String(),
Hash: link.Cid.String(),
Name: link.Name,
Size: link.Size,
}
Expand Down Expand Up @@ -413,7 +427,7 @@ Available templates:
return
}

node := new(dag.Node)
node := new(dag.ProtoNode)
if len(req.Arguments()) == 1 {
template := req.Arguments()[0]
var err error
Expand All @@ -440,7 +454,7 @@ Available templates:
Type: Object{},
}

func nodeFromTemplate(template string) (*dag.Node, error) {
func nodeFromTemplate(template string) (*dag.ProtoNode, error) {
switch template {
case "unixfs-dir":
return ft.EmptyDirNode(), nil
Expand All @@ -464,7 +478,7 @@ func objectPut(n *core.IpfsNode, input io.Reader, encoding string, dataFieldEnco
return nil, ErrObjectTooLarge
}

var dagnode *dag.Node
var dagnode *dag.ProtoNode
switch getObjectEnc(encoding) {
case objectEncodingJSON:
node := new(Node)
Expand Down Expand Up @@ -542,27 +556,27 @@ func getObjectEnc(o interface{}) objectEncoding {
return objectEncoding(v)
}

func getOutput(dagnode *dag.Node) (*Object, error) {
func getOutput(dagnode dag.Node) (*Object, error) {
c := dagnode.Cid()
output := &Object{
Hash: c.String(),
Links: make([]Link, len(dagnode.Links)),
Links: make([]Link, len(dagnode.Links())),
}

for i, link := range dagnode.Links {
for i, link := range dagnode.Links() {
output.Links[i] = Link{
Name: link.Name,
Hash: link.Hash.B58String(),
Hash: link.Cid.String(),
Size: link.Size,
}
}

return output, nil
}

// converts the Node object into a real dag.Node
func deserializeNode(node *Node, dataFieldEncoding string) (*dag.Node, error) {
dagnode := new(dag.Node)
// converts the Node object into a real dag.ProtoNode
func deserializeNode(node *Node, dataFieldEncoding string) (*dag.ProtoNode, error) {
dagnode := new(dag.ProtoNode)
switch dataFieldEncoding {
case "text":
dagnode.SetData([]byte(node.Data))
Expand All @@ -573,16 +587,16 @@ func deserializeNode(node *Node, dataFieldEncoding string) (*dag.Node, error) {
return nil, fmt.Errorf("Unkown data field encoding")
}

dagnode.Links = make([]*dag.Link, len(node.Links))
dagnode.SetLinks(make([]*dag.Link, len(node.Links)))
for i, link := range node.Links {
hash, err := mh.FromB58String(link.Hash)
c, err := cid.Decode(link.Hash)
if err != nil {
return nil, err
}
dagnode.Links[i] = &dag.Link{
dagnode.Links()[i] = &dag.Link{
Name: link.Name,
Size: link.Size,
Hash: hash,
Cid: c,
}
}

Expand Down
Loading

0 comments on commit 4fe144d

Please sign in to comment.