merkledag: split off node.go
Juan Batiz-Benet committed
Jan 7, 2015 at 02:15 UTC
f63d45ca56733c4b899ab97483ebc01fbd592770
2 files changed
+188
-181
merkledag/merkledag.go
-181
@@ -9,7 +9,6 @@ import (
9
10
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
11
12
- mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
12
blocks "github.com/jbenet/go-ipfs/blocks"
13
bserv "github.com/jbenet/go-ipfs/blockservice"
14
u "github.com/jbenet/go-ipfs/util"
@@ -18,11 +17,6 @@ import (
17
var log = u.Logger("merkledag")
18
var ErrNotFound = fmt.Errorf("merkledag: not found")
19
21
-// NodeMap maps u.Keys to Nodes.
22
-// We cannot use []byte/Multihash for keys :(
23
-// so have to convert Multihash bytes to string (u.Key)
24
-type NodeMap map[u.Key]*Node
25
-
20
// DAGService is an IPFS Merkle DAG service.
21
type DAGService interface {
22
Add(*Node) (u.Key, error)
@@ -39,181 +33,6 @@ func NewDAGService(bs *bserv.BlockService) DAGService {
33
return &dagService{bs}
34
}
35
42
-// Node represents a node in the IPFS Merkle DAG.
43
-// nodes have opaque data and a set of navigable links.
44
-type Node struct {
45
- Links []*Link
46
- Data []byte
47
-
48
- // cache encoded/marshaled value
49
- encoded []byte
50
-
51
- cached mh.Multihash
52
-}
53
-
54
-// NodeStat is a statistics object for a Node. Mostly sizes.
55
-type NodeStat struct {
56
- NumLinks int // number of links in link table
57
- BlockSize int // size of the raw data
58
- LinksSize int // size of the links segment
59
- DataSize int // size of the data segment
60
- CumulativeSize int // cumulatie size of object + all it references
61
-}
62
-
63
-func (ns NodeStat) String() string {
64
- f := "NodeStat{NumLinks: %d, BlockSize: %d, LinksSize: %d, DataSize: %d, CumulativeSize: %d}"
65
- return fmt.Sprintf(f, ns.NumLinks, ns.BlockSize, ns.LinksSize, ns.DataSize, ns.CumulativeSize)
66
-}
67
-
68
-// Link represents an IPFS Merkle DAG Link between Nodes.
69
-type Link struct {
70
- // utf string name. should be unique per object
71
- Name string // utf8
72
-
73
- // cumulative size of target object
74
- Size uint64
75
-
76
- // multihash of the target object
77
- Hash mh.Multihash
78
-
79
- // a ptr to the actual node for graph manipulation
80
- Node *Node
81
-}
82
-
83
-type LinkSlice []*Link
84
-
85
-func (ls LinkSlice) Len() int { return len(ls) }
86
-func (ls LinkSlice) Swap(a, b int) { ls[a], ls[b] = ls[b], ls[a] }
87
-func (ls LinkSlice) Less(a, b int) bool { return ls[a].Name < ls[b].Name }
88
-
89
-// MakeLink creates a link to the given node
90
-func MakeLink(n *Node) (*Link, error) {
91
- s, err := n.Size()
92
- if err != nil {
93
- return nil, err
94
- }
95
-
96
- h, err := n.Multihash()
97
- if err != nil {
98
- return nil, err
99
- }
100
- return &Link{
101
- Size: s,
102
- Hash: h,
103
- }, nil
104
-}
105
-
106
-// GetNode returns the MDAG Node that this link points to
107
-func (l *Link) GetNode(serv DAGService) (*Node, error) {
108
- if l.Node != nil {
109
- return l.Node, nil
110
- }
111
-
112
- return serv.Get(u.Key(l.Hash))
113
-}
114
-
115
-// AddNodeLink adds a link to another node.
116
-func (n *Node) AddNodeLink(name string, that *Node) error {
117
- lnk, err := MakeLink(that)
118
- if err != nil {
119
- return err
120
- }
121
- lnk.Name = name
122
- lnk.Node = that
123
-
124
- n.Links = append(n.Links, lnk)
125
- return nil
126
-}
127
-
128
-// AddNodeLink adds a link to another node. without keeping a reference to
129
-// the child node
130
-func (n *Node) AddNodeLinkClean(name string, that *Node) error {
131
- lnk, err := MakeLink(that)
132
- if err != nil {
133
- return err
134
- }
135
- lnk.Name = name
136
-
137
- n.Links = append(n.Links, lnk)
138
- return nil
139
-}
140
-
141
-// Remove a link on this node by the given name
142
-func (n *Node) RemoveNodeLink(name string) error {
143
- for i, l := range n.Links {
144
- if l.Name == name {
145
- n.Links = append(n.Links[:i], n.Links[i+1:]...)
146
- return nil
147
- }
148
- }
149
- return ErrNotFound
150
-}
151
-
152
-// Copy returns a copy of the node.
153
-// NOTE: does not make copies of Node objects in the links.
154
-func (n *Node) Copy() *Node {
155
- nnode := new(Node)
156
- nnode.Data = make([]byte, len(n.Data))
157
- copy(nnode.Data, n.Data)
158
-
159
- nnode.Links = make([]*Link, len(n.Links))
160
- copy(nnode.Links, n.Links)
161
- return nnode
162
-}
163
-
164
-// Size returns the total size of the data addressed by node,
165
-// including the total sizes of references.
166
-func (n *Node) Size() (uint64, error) {
167
- b, err := n.Encoded(false)
168
- if err != nil {
169
- return 0, err
170
- }
171
-
172
- s := uint64(len(b))
173
- for _, l := range n.Links {
174
- s += l.Size
175
- }
176
- return s, nil
177
-}
178
-
179
-// Stat returns statistics on the node.
180
-func (n *Node) Stat() (NodeStat, error) {
181
- enc, err := n.Encoded(false)
182
- if err != nil {
183
- return NodeStat{}, err
184
- }
185
-
186
- cumSize, err := n.Size()
187
- if err != nil {
188
- return NodeStat{}, err
189
- }
190
-
191
- return NodeStat{
192
- NumLinks: len(n.Links),
193
- BlockSize: len(enc),
194
- LinksSize: len(enc) - len(n.Data), // includes framing.
195
- DataSize: len(n.Data),
196
- CumulativeSize: int(cumSize),
197
- }, nil
198
-}
199
-
200
-// Multihash hashes the encoded data of this node.
201
-func (n *Node) Multihash() (mh.Multihash, error) {
202
- // Note: Encoded generates the hash and puts it in n.cached.
203
- _, err := n.Encoded(false)
204
- if err != nil {
205
- return nil, err
206
- }
207
-
208
- return n.cached, nil
209
-}
210
-
211
-// Key returns the Multihash as a key, for maps.
212
-func (n *Node) Key() (u.Key, error) {
213
- h, err := n.Multihash()
214
- return u.Key(h), err
215
-}
216
-
36
// dagService is an IPFS Merkle DAG service.
37
// - the root is virtual (like a forest)
38
// - stores nodes' data in a BlockService
merkledag/node.go
new
+188
@@ -0,0 +1,188 @@
1
+package merkledag
2
+
3
+import (
4
+ "fmt"
5
+
6
+ mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
7
+ u "github.com/jbenet/go-ipfs/util"
8
+)
9
+
10
+// NodeMap maps u.Keys to Nodes.
11
+// We cannot use []byte/Multihash for keys :(
12
+// so have to convert Multihash bytes to string (u.Key)
13
+type NodeMap map[u.Key]*Node
14
+
15
+// Node represents a node in the IPFS Merkle DAG.
16
+// nodes have opaque data and a set of navigable links.
17
+type Node struct {
18
+ Links []*Link
19
+ Data []byte
20
+
21
+ // cache encoded/marshaled value
22
+ encoded []byte
23
+
24
+ cached mh.Multihash
25
+}
26
+
27
+// NodeStat is a statistics object for a Node. Mostly sizes.
28
+type NodeStat struct {
29
+ NumLinks int // number of links in link table
30
+ BlockSize int // size of the raw data
31
+ LinksSize int // size of the links segment
32
+ DataSize int // size of the data segment
33
+ CumulativeSize int // cumulatie size of object + all it references
34
+}
35
+
36
+func (ns NodeStat) String() string {
37
+ f := "NodeStat{NumLinks: %d, BlockSize: %d, LinksSize: %d, DataSize: %d, CumulativeSize: %d}"
38
+ return fmt.Sprintf(f, ns.NumLinks, ns.BlockSize, ns.LinksSize, ns.DataSize, ns.CumulativeSize)
39
+}
40
+
41
+// Link represents an IPFS Merkle DAG Link between Nodes.
42
+type Link struct {
43
+ // utf string name. should be unique per object
44
+ Name string // utf8
45
+
46
+ // cumulative size of target object
47
+ Size uint64
48
+
49
+ // multihash of the target object
50
+ Hash mh.Multihash
51
+
52
+ // a ptr to the actual node for graph manipulation
53
+ Node *Node
54
+}
55
+
56
+type LinkSlice []*Link
57
+
58
+func (ls LinkSlice) Len() int { return len(ls) }
59
+func (ls LinkSlice) Swap(a, b int) { ls[a], ls[b] = ls[b], ls[a] }
60
+func (ls LinkSlice) Less(a, b int) bool { return ls[a].Name < ls[b].Name }
61
+
62
+// MakeLink creates a link to the given node
63
+func MakeLink(n *Node) (*Link, error) {
64
+ s, err := n.Size()
65
+ if err != nil {
66
+ return nil, err
67
+ }
68
+
69
+ h, err := n.Multihash()
70
+ if err != nil {
71
+ return nil, err
72
+ }
73
+ return &Link{
74
+ Size: s,
75
+ Hash: h,
76
+ }, nil
77
+}
78
+
79
+// GetNode returns the MDAG Node that this link points to
80
+func (l *Link) GetNode(serv DAGService) (*Node, error) {
81
+ if l.Node != nil {
82
+ return l.Node, nil
83
+ }
84
+
85
+ return serv.Get(u.Key(l.Hash))
86
+}
87
+
88
+// AddNodeLink adds a link to another node.
89
+func (n *Node) AddNodeLink(name string, that *Node) error {
90
+ lnk, err := MakeLink(that)
91
+ if err != nil {
92
+ return err
93
+ }
94
+ lnk.Name = name
95
+ lnk.Node = that
96
+
97
+ n.Links = append(n.Links, lnk)
98
+ return nil
99
+}
100
+
101
+// AddNodeLink adds a link to another node. without keeping a reference to
102
+// the child node
103
+func (n *Node) AddNodeLinkClean(name string, that *Node) error {
104
+ lnk, err := MakeLink(that)
105
+ if err != nil {
106
+ return err
107
+ }
108
+ lnk.Name = name
109
+
110
+ n.Links = append(n.Links, lnk)
111
+ return nil
112
+}
113
+
114
+// Remove a link on this node by the given name
115
+func (n *Node) RemoveNodeLink(name string) error {
116
+ for i, l := range n.Links {
117
+ if l.Name == name {
118
+ n.Links = append(n.Links[:i], n.Links[i+1:]...)
119
+ return nil
120
+ }
121
+ }
122
+ return ErrNotFound
123
+}
124
+
125
+// Copy returns a copy of the node.
126
+// NOTE: does not make copies of Node objects in the links.
127
+func (n *Node) Copy() *Node {
128
+ nnode := new(Node)
129
+ nnode.Data = make([]byte, len(n.Data))
130
+ copy(nnode.Data, n.Data)
131
+
132
+ nnode.Links = make([]*Link, len(n.Links))
133
+ copy(nnode.Links, n.Links)
134
+ return nnode
135
+}
136
+
137
+// Size returns the total size of the data addressed by node,
138
+// including the total sizes of references.
139
+func (n *Node) Size() (uint64, error) {
140
+ b, err := n.Encoded(false)
141
+ if err != nil {
142
+ return 0, err
143
+ }
144
+
145
+ s := uint64(len(b))
146
+ for _, l := range n.Links {
147
+ s += l.Size
148
+ }
149
+ return s, nil
150
+}
151
+
152
+// Stat returns statistics on the node.
153
+func (n *Node) Stat() (NodeStat, error) {
154
+ enc, err := n.Encoded(false)
155
+ if err != nil {
156
+ return NodeStat{}, err
157
+ }
158
+
159
+ cumSize, err := n.Size()
160
+ if err != nil {
161
+ return NodeStat{}, err
162
+ }
163
+
164
+ return NodeStat{
165
+ NumLinks: len(n.Links),
166
+ BlockSize: len(enc),
167
+ LinksSize: len(enc) - len(n.Data), // includes framing.
168
+ DataSize: len(n.Data),
169
+ CumulativeSize: int(cumSize),
170
+ }, nil
171
+}
172
+
173
+// Multihash hashes the encoded data of this node.
174
+func (n *Node) Multihash() (mh.Multihash, error) {
175
+ // Note: Encoded generates the hash and puts it in n.cached.
176
+ _, err := n.Encoded(false)
177
+ if err != nil {
178
+ return nil, err
179
+ }
180
+
181
+ return n.cached, nil
182
+}
183
+
184
+// Key returns the Multihash as a key, for maps.
185
+func (n *Node) Key() (u.Key, error) {
186
+ h, err := n.Multihash()
187
+ return u.Key(h), err
188
+}