Skip to content

Commit d0e69a0

Browse files
committed
Merge pull request #865 from jbenet/ipns/refactor-unixfs
Ipns/refactor unixfs
2 parents f17521b + 0e9772c commit d0e69a0

File tree

4 files changed

+103
-26
lines changed

4 files changed

+103
-26
lines changed

importer/helpers/dagbuilder.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ func (db *DagBuilderHelper) Next() []byte {
7878
return d
7979
}
8080

81+
// GetDagServ returns the dagservice object this Helper is using
82+
func (db *DagBuilderHelper) GetDagServ() dag.DAGService {
83+
return db.dserv
84+
}
85+
8186
// FillNodeLayer will add datanodes as children to the give node until
8287
// at most db.indirSize ndoes are added
8388
//
@@ -86,7 +91,7 @@ func (db *DagBuilderHelper) FillNodeLayer(node *UnixfsNode) error {
8691

8792
// while we have room AND we're not done
8893
for node.NumChildren() < db.maxlinks && !db.Done() {
89-
child := NewUnixfsNode()
94+
child := NewUnixfsBlock()
9095

9196
if err := db.FillNodeWithData(child); err != nil {
9297
return err
@@ -110,7 +115,7 @@ func (db *DagBuilderHelper) FillNodeWithData(node *UnixfsNode) error {
110115
return ErrSizeLimitExceeded
111116
}
112117

113-
node.setData(data)
118+
node.SetData(data)
114119
return nil
115120
}
116121

importer/helpers/helpers.go

+40-3
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,51 @@ var ErrSizeLimitExceeded = fmt.Errorf("object size limit exceeded")
3838
// of unixfs DAG trees
3939
type UnixfsNode struct {
4040
node *dag.Node
41-
ufmt *ft.MultiBlock
41+
ufmt *ft.FSNode
4242
}
4343

44+
// NewUnixfsNode creates a new Unixfs node to represent a file
4445
func NewUnixfsNode() *UnixfsNode {
4546
return &UnixfsNode{
4647
node: new(dag.Node),
47-
ufmt: new(ft.MultiBlock),
48+
ufmt: &ft.FSNode{Type: ft.TFile},
4849
}
4950
}
5051

52+
// NewUnixfsBlock creates a new Unixfs node to represent a raw data block
53+
func NewUnixfsBlock() *UnixfsNode {
54+
return &UnixfsNode{
55+
node: new(dag.Node),
56+
ufmt: &ft.FSNode{Type: ft.TRaw},
57+
}
58+
}
59+
60+
// NewUnixfsNodeFromDag reconstructs a Unixfs node from a given dag node
61+
func NewUnixfsNodeFromDag(nd *dag.Node) (*UnixfsNode, error) {
62+
mb, err := ft.FSNodeFromBytes(nd.Data)
63+
if err != nil {
64+
return nil, err
65+
}
66+
67+
return &UnixfsNode{
68+
node: nd,
69+
ufmt: mb,
70+
}, nil
71+
}
72+
5173
func (n *UnixfsNode) NumChildren() int {
5274
return n.ufmt.NumChildren()
5375
}
5476

77+
func (n *UnixfsNode) GetChild(i int, ds dag.DAGService) (*UnixfsNode, error) {
78+
nd, err := n.node.Links[i].GetNode(ds)
79+
if err != nil {
80+
return nil, err
81+
}
82+
83+
return NewUnixfsNodeFromDag(nd)
84+
}
85+
5586
// addChild will add the given UnixfsNode as a child of the receiver.
5687
// the passed in DagBuilderHelper is used to store the child node an
5788
// pin it locally so it doesnt get lost
@@ -83,7 +114,13 @@ func (n *UnixfsNode) AddChild(child *UnixfsNode, db *DagBuilderHelper) error {
83114
return nil
84115
}
85116

86-
func (n *UnixfsNode) setData(data []byte) {
117+
// Removes the child node at the given index
118+
func (n *UnixfsNode) RemoveChild(index int) {
119+
n.ufmt.RemoveBlockSize(index)
120+
n.node.Links = append(n.node.Links[:index], n.node.Links[index+1:]...)
121+
}
122+
123+
func (n *UnixfsNode) SetData(data []byte) {
87124
n.ufmt.Data = data
88125
}
89126

unixfs/format.go

+50-16
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ import (
99
pb "github.com/jbenet/go-ipfs/unixfs/pb"
1010
)
1111

12+
const (
13+
TRaw = pb.Data_Raw
14+
TFile = pb.Data_File
15+
TDirectory = pb.Data_Directory
16+
TMetadata = pb.Data_Metadata
17+
)
18+
1219
var ErrMalformedFileFormat = errors.New("malformed data in file format")
1320
var ErrInvalidDirLocation = errors.New("found directory node in unexpected place")
1421
var ErrUnrecognizedType = errors.New("unrecognized node type")
@@ -98,33 +105,60 @@ func DataSize(data []byte) (uint64, error) {
98105
}
99106
}
100107

101-
type MultiBlock struct {
102-
Data []byte
108+
type FSNode struct {
109+
Data []byte
110+
111+
// total data size for each child
103112
blocksizes []uint64
104-
subtotal uint64
113+
114+
// running sum of blocksizes
115+
subtotal uint64
116+
117+
// node type of this node
118+
Type pb.Data_DataType
119+
}
120+
121+
func FSNodeFromBytes(b []byte) (*FSNode, error) {
122+
pbn := new(pb.Data)
123+
err := proto.Unmarshal(b, pbn)
124+
if err != nil {
125+
return nil, err
126+
}
127+
128+
n := new(FSNode)
129+
n.Data = pbn.Data
130+
n.blocksizes = pbn.Blocksizes
131+
n.subtotal = pbn.GetFilesize() - uint64(len(n.Data))
132+
n.Type = pbn.GetType()
133+
return n, nil
134+
}
135+
136+
// AddBlockSize adds the size of the next child block of this node
137+
func (n *FSNode) AddBlockSize(s uint64) {
138+
n.subtotal += s
139+
n.blocksizes = append(n.blocksizes, s)
105140
}
106141

107-
func (mb *MultiBlock) AddBlockSize(s uint64) {
108-
mb.subtotal += s
109-
mb.blocksizes = append(mb.blocksizes, s)
142+
func (n *FSNode) RemoveBlockSize(i int) {
143+
n.subtotal -= n.blocksizes[i]
144+
n.blocksizes = append(n.blocksizes[:i], n.blocksizes[i+1:]...)
110145
}
111146

112-
func (mb *MultiBlock) GetBytes() ([]byte, error) {
147+
func (n *FSNode) GetBytes() ([]byte, error) {
113148
pbn := new(pb.Data)
114-
t := pb.Data_File
115-
pbn.Type = &t
116-
pbn.Filesize = proto.Uint64(uint64(len(mb.Data)) + mb.subtotal)
117-
pbn.Blocksizes = mb.blocksizes
118-
pbn.Data = mb.Data
149+
pbn.Type = &n.Type
150+
pbn.Filesize = proto.Uint64(uint64(len(n.Data)) + n.subtotal)
151+
pbn.Blocksizes = n.blocksizes
152+
pbn.Data = n.Data
119153
return proto.Marshal(pbn)
120154
}
121155

122-
func (mb *MultiBlock) FileSize() uint64 {
123-
return uint64(len(mb.Data)) + mb.subtotal
156+
func (n *FSNode) FileSize() uint64 {
157+
return uint64(len(n.Data)) + n.subtotal
124158
}
125159

126-
func (mb *MultiBlock) NumChildren() int {
127-
return len(mb.blocksizes)
160+
func (n *FSNode) NumChildren() int {
161+
return len(n.blocksizes)
128162
}
129163

130164
type Metadata struct {

unixfs/format_test.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@ import (
77
pb "github.com/jbenet/go-ipfs/unixfs/pb"
88
)
99

10-
func TestMultiBlock(t *testing.T) {
11-
mbf := new(MultiBlock)
10+
func TestFSNode(t *testing.T) {
11+
fsn := new(FSNode)
12+
fsn.Type = TFile
1213
for i := 0; i < 15; i++ {
13-
mbf.AddBlockSize(100)
14+
fsn.AddBlockSize(100)
1415
}
1516

16-
mbf.Data = make([]byte, 128)
17+
fsn.Data = make([]byte, 128)
1718

18-
b, err := mbf.GetBytes()
19+
b, err := fsn.GetBytes()
1920
if err != nil {
2021
t.Fatal(err)
2122
}

0 commit comments

Comments
 (0)