Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
dms3
go-merkledag
Commits
196e996d
Commit
196e996d
authored
Jul 10, 2016
by
Jeromy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cache encoded data when reading dag nodes from disk
License: MIT Signed-off-by:
Jeromy
<
why@ipfs.io
>
parent
1655cd1a
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
50 additions
and
29 deletions
+50
-29
coding.go
coding.go
+8
-3
merkledag.go
merkledag.go
+4
-0
merkledag_test.go
merkledag_test.go
+9
-9
node.go
node.go
+20
-6
traverse/traverse_test.go
traverse/traverse_test.go
+7
-7
utils/utils_test.go
utils/utils_test.go
+2
-4
No files found.
coding.go
View file @
196e996d
...
...
@@ -33,7 +33,8 @@ func (n *Node) unmarshal(encoded []byte) error {
}
sort
.
Stable
(
LinkSlice
(
n
.
Links
))
// keep links sorted
n
.
Data
=
pbn
.
GetData
()
n
.
data
=
pbn
.
GetData
()
n
.
encoded
=
encoded
return
nil
}
...
...
@@ -62,8 +63,8 @@ func (n *Node) getPBNode() *pb.PBNode {
pbn
.
Links
[
i
]
.
Hash
=
[]
byte
(
l
.
Hash
)
}
if
len
(
n
.
D
ata
)
>
0
{
pbn
.
Data
=
n
.
D
ata
if
len
(
n
.
d
ata
)
>
0
{
pbn
.
Data
=
n
.
d
ata
}
return
pbn
}
...
...
@@ -73,11 +74,15 @@ func (n *Node) getPBNode() *pb.PBNode {
func
(
n
*
Node
)
EncodeProtobuf
(
force
bool
)
([]
byte
,
error
)
{
sort
.
Stable
(
LinkSlice
(
n
.
Links
))
// keep links sorted
if
n
.
encoded
==
nil
||
force
{
n
.
cached
=
nil
var
err
error
n
.
encoded
,
err
=
n
.
Marshal
()
if
err
!=
nil
{
return
nil
,
err
}
}
if
n
.
cached
==
nil
{
n
.
cached
=
u
.
Hash
(
n
.
encoded
)
}
...
...
merkledag.go
View file @
196e996d
...
...
@@ -93,6 +93,9 @@ func (n *dagService) Get(ctx context.Context, k key.Key) (*Node, error) {
}
return
nil
,
fmt
.
Errorf
(
"Failed to decode Protocol Buffers: %v"
,
err
)
}
res
.
cached
=
k
.
ToMultihash
()
return
res
,
nil
}
...
...
@@ -147,6 +150,7 @@ func (ds *dagService) GetMany(ctx context.Context, keys []key.Key) <-chan *NodeO
out
<-
&
NodeOption
{
Err
:
err
}
return
}
nd
.
cached
=
b
.
Key
()
.
ToMultihash
()
// buffered, no need to select
out
<-
&
NodeOption
{
Node
:
nd
}
...
...
merkledag_test.go
View file @
196e996d
...
...
@@ -46,9 +46,9 @@ func getDagservAndPinner(t *testing.T) dagservAndPinner {
func
TestNode
(
t
*
testing
.
T
)
{
n1
:=
&
Node
{
Data
:
[]
byte
(
"beep"
)
}
n2
:=
&
Node
{
Data
:
[]
byte
(
"boop"
)
}
n3
:=
&
Node
{
Data
:
[]
byte
(
"beep boop"
)
}
n1
:=
Node
With
Data
(
[]
byte
(
"beep"
)
)
n2
:=
Node
With
Data
(
[]
byte
(
"boop"
)
)
n3
:=
Node
With
Data
(
[]
byte
(
"beep boop"
)
)
if
err
:=
n3
.
AddNodeLink
(
"beep-link"
,
n1
);
err
!=
nil
{
t
.
Error
(
err
)
}
...
...
@@ -58,7 +58,7 @@ func TestNode(t *testing.T) {
printn
:=
func
(
name
string
,
n
*
Node
)
{
fmt
.
Println
(
">"
,
name
)
fmt
.
Println
(
"data:"
,
string
(
n
.
Data
))
fmt
.
Println
(
"data:"
,
string
(
n
.
Data
()
))
fmt
.
Println
(
"links:"
)
for
_
,
l
:=
range
n
.
Links
{
...
...
@@ -118,8 +118,8 @@ func SubtestNodeStat(t *testing.T, n *Node) {
expected
:=
NodeStat
{
NumLinks
:
len
(
n
.
Links
),
BlockSize
:
len
(
enc
),
LinksSize
:
len
(
enc
)
-
len
(
n
.
Data
),
// includes framing.
DataSize
:
len
(
n
.
Data
),
LinksSize
:
len
(
enc
)
-
len
(
n
.
Data
()
),
// includes framing.
DataSize
:
len
(
n
.
Data
()
),
CumulativeSize
:
int
(
cumSize
),
Hash
:
k
.
B58String
(),
}
...
...
@@ -255,7 +255,7 @@ func TestEmptyKey(t *testing.T) {
func
TestCantGet
(
t
*
testing
.
T
)
{
dsp
:=
getDagservAndPinner
(
t
)
a
:=
&
Node
{
Data
:
[]
byte
(
"A"
)
}
a
:=
Node
With
Data
(
[]
byte
(
"A"
)
)
k
,
err
:=
a
.
Key
()
if
err
!=
nil
{
...
...
@@ -339,7 +339,7 @@ func TestFetchFailure(t *testing.T) {
top
:=
new
(
Node
)
for
i
:=
0
;
i
<
10
;
i
++
{
nd
:=
&
Node
{
Data
:
[]
byte
{
byte
(
'a'
+
i
)}
}
nd
:=
Node
With
Data
(
[]
byte
{
byte
(
'a'
+
i
)}
)
_
,
err
:=
ds
.
Add
(
nd
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
...
...
@@ -352,7 +352,7 @@ func TestFetchFailure(t *testing.T) {
}
for
i
:=
0
;
i
<
10
;
i
++
{
nd
:=
&
Node
{
Data
:
[]
byte
{
'f'
,
'a'
+
byte
(
i
)}
}
nd
:=
Node
With
Data
(
[]
byte
{
'f'
,
'a'
+
byte
(
i
)}
)
_
,
err
:=
ds_bad
.
Add
(
nd
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
...
...
node.go
View file @
196e996d
...
...
@@ -15,7 +15,7 @@ var ErrLinkNotFound = fmt.Errorf("no link by that name")
// nodes have opaque data and a set of navigable links.
type
Node
struct
{
Links
[]
*
Link
D
ata
[]
byte
d
ata
[]
byte
// cache encoded/marshaled value
encoded
[]
byte
...
...
@@ -78,6 +78,10 @@ func (l *Link) GetNode(ctx context.Context, serv DAGService) (*Node, error) {
return
serv
.
Get
(
ctx
,
key
.
Key
(
l
.
Hash
))
}
func
NodeWithData
(
d
[]
byte
)
*
Node
{
return
&
Node
{
data
:
d
}
}
// AddNodeLink adds a link to another node.
func
(
n
*
Node
)
AddNodeLink
(
name
string
,
that
*
Node
)
error
{
n
.
encoded
=
nil
...
...
@@ -168,9 +172,9 @@ func (n *Node) GetLinkedNode(ctx context.Context, ds DAGService, name string) (*
// NOTE: Does not make copies of Node objects in the links.
func
(
n
*
Node
)
Copy
()
*
Node
{
nnode
:=
new
(
Node
)
if
len
(
n
.
D
ata
)
>
0
{
nnode
.
D
ata
=
make
([]
byte
,
len
(
n
.
D
ata
))
copy
(
nnode
.
D
ata
,
n
.
D
ata
)
if
len
(
n
.
d
ata
)
>
0
{
nnode
.
d
ata
=
make
([]
byte
,
len
(
n
.
d
ata
))
copy
(
nnode
.
d
ata
,
n
.
d
ata
)
}
if
len
(
n
.
Links
)
>
0
{
...
...
@@ -180,6 +184,16 @@ func (n *Node) Copy() *Node {
return
nnode
}
func
(
n
*
Node
)
Data
()
[]
byte
{
return
n
.
data
}
func
(
n
*
Node
)
SetData
(
d
[]
byte
)
{
n
.
encoded
=
nil
n
.
cached
=
nil
n
.
data
=
d
}
// UpdateNodeLink return a copy of the node with the link name set to point to
// that. If a link of the same name existed, it is removed.
func
(
n
*
Node
)
UpdateNodeLink
(
name
string
,
that
*
Node
)
(
*
Node
,
error
)
{
...
...
@@ -226,8 +240,8 @@ func (n *Node) Stat() (*NodeStat, error) {
Hash
:
key
.
B58String
(),
NumLinks
:
len
(
n
.
Links
),
BlockSize
:
len
(
enc
),
LinksSize
:
len
(
enc
)
-
len
(
n
.
D
ata
),
// includes framing.
DataSize
:
len
(
n
.
D
ata
),
LinksSize
:
len
(
enc
)
-
len
(
n
.
d
ata
),
// includes framing.
DataSize
:
len
(
n
.
d
ata
),
CumulativeSize
:
int
(
cumSize
),
},
nil
}
...
...
traverse/traverse_test.go
View file @
196e996d
...
...
@@ -326,7 +326,7 @@ func testWalkOutputs(t *testing.T, root *mdag.Node, opts Options, expect []byte)
buf
:=
new
(
bytes
.
Buffer
)
walk
:=
func
(
current
State
)
error
{
s
:=
fmt
.
Sprintf
(
"%d %s
\n
"
,
current
.
Depth
,
current
.
Node
.
Data
)
s
:=
fmt
.
Sprintf
(
"%d %s
\n
"
,
current
.
Depth
,
current
.
Node
.
Data
()
)
t
.
Logf
(
"walk: %s"
,
s
)
buf
.
Write
([]
byte
(
s
))
return
nil
...
...
@@ -349,7 +349,7 @@ func testWalkOutputs(t *testing.T, root *mdag.Node, opts Options, expect []byte)
}
func
newFan
(
t
*
testing
.
T
,
ds
mdag
.
DAGService
)
*
mdag
.
Node
{
a
:=
&
mdag
.
Node
{
Data
:
[]
byte
(
"/a"
)
}
a
:=
mdag
.
Node
With
Data
(
[]
byte
(
"/a"
)
)
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"
))
...
...
@@ -358,7 +358,7 @@ func newFan(t *testing.T, ds mdag.DAGService) *mdag.Node {
}
func
newLinkedList
(
t
*
testing
.
T
,
ds
mdag
.
DAGService
)
*
mdag
.
Node
{
a
:=
&
mdag
.
Node
{
Data
:
[]
byte
(
"/a"
)
}
a
:=
mdag
.
Node
With
Data
(
[]
byte
(
"/a"
)
)
aa
:=
child
(
t
,
ds
,
a
,
"aa"
)
aaa
:=
child
(
t
,
ds
,
aa
,
"aaa"
)
aaaa
:=
child
(
t
,
ds
,
aaa
,
"aaaa"
)
...
...
@@ -371,7 +371,7 @@ func newLinkedList(t *testing.T, ds mdag.DAGService) *mdag.Node {
}
func
newBinaryTree
(
t
*
testing
.
T
,
ds
mdag
.
DAGService
)
*
mdag
.
Node
{
a
:=
&
mdag
.
Node
{
Data
:
[]
byte
(
"/a"
)
}
a
:=
mdag
.
Node
With
Data
(
[]
byte
(
"/a"
)
)
aa
:=
child
(
t
,
ds
,
a
,
"aa"
)
ab
:=
child
(
t
,
ds
,
a
,
"ab"
)
addLink
(
t
,
ds
,
aa
,
child
(
t
,
ds
,
aa
,
"aaa"
))
...
...
@@ -384,7 +384,7 @@ func newBinaryTree(t *testing.T, ds mdag.DAGService) *mdag.Node {
}
func
newBinaryDAG
(
t
*
testing
.
T
,
ds
mdag
.
DAGService
)
*
mdag
.
Node
{
a
:=
&
mdag
.
Node
{
Data
:
[]
byte
(
"/a"
)
}
a
:=
mdag
.
Node
With
Data
(
[]
byte
(
"/a"
)
)
aa
:=
child
(
t
,
ds
,
a
,
"aa"
)
aaa
:=
child
(
t
,
ds
,
aa
,
"aaa"
)
aaaa
:=
child
(
t
,
ds
,
aaa
,
"aaaa"
)
...
...
@@ -401,7 +401,7 @@ func newBinaryDAG(t *testing.T, ds mdag.DAGService) *mdag.Node {
}
func
addLink
(
t
*
testing
.
T
,
ds
mdag
.
DAGService
,
a
,
b
*
mdag
.
Node
)
{
to
:=
string
(
a
.
Data
)
+
"2"
+
string
(
b
.
Data
)
to
:=
string
(
a
.
Data
()
)
+
"2"
+
string
(
b
.
Data
()
)
if
_
,
err
:=
ds
.
Add
(
b
);
err
!=
nil
{
t
.
Error
(
err
)
}
...
...
@@ -411,5 +411,5 @@ func addLink(t *testing.T, ds mdag.DAGService, a, b *mdag.Node) {
}
func
child
(
t
*
testing
.
T
,
ds
mdag
.
DAGService
,
a
*
mdag
.
Node
,
name
string
)
*
mdag
.
Node
{
return
&
mdag
.
Node
{
Data
:
[]
byte
(
string
(
a
.
Data
)
+
"/"
+
name
)
}
return
mdag
.
Node
With
Data
(
[]
byte
(
string
(
a
.
Data
()
)
+
"/"
+
name
)
)
}
utils/utils_test.go
View file @
196e996d
...
...
@@ -13,9 +13,7 @@ import (
func
TestAddLink
(
t
*
testing
.
T
)
{
ds
:=
mdtest
.
Mock
()
fishnode
:=
&
dag
.
Node
{
Data
:
[]
byte
(
"fishcakes!"
),
}
fishnode
:=
dag
.
NodeWithData
([]
byte
(
"fishcakes!"
))
fk
,
err
:=
ds
.
Add
(
fishnode
)
if
err
!=
nil
{
...
...
@@ -90,7 +88,7 @@ func TestInsertNode(t *testing.T) {
}
func
testInsert
(
t
*
testing
.
T
,
e
*
Editor
,
path
,
data
string
,
create
bool
,
experr
string
)
{
child
:=
&
dag
.
Node
{
Data
:
[]
byte
(
data
)
}
child
:=
dag
.
Node
With
Data
(
[]
byte
(
data
)
)
ck
,
err
:=
e
.
tmp
.
Add
(
child
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment