Skip to content

Commit f72c37e

Browse files
committed
add global config switch for sharding
License: MIT Signed-off-by: Jeromy <[email protected]>
1 parent e876434 commit f72c37e

File tree

10 files changed

+104
-34
lines changed

10 files changed

+104
-34
lines changed

core/builder.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
pin "github.com/ipfs/go-ipfs/pin"
1919
repo "github.com/ipfs/go-ipfs/repo"
2020
cfg "github.com/ipfs/go-ipfs/repo/config"
21+
uio "github.com/ipfs/go-ipfs/unixfs/io"
2122

2223
ci "gx/ipfs/QmPGxZ1DP2w45WcogpW1h43BvseXbfke9N91qotpoQcUeS/go-libp2p-crypto"
2324
ds "gx/ipfs/QmRWDav6mzWseLWeYfVd5fvUKiVe9xNH29YfMF438fG364/go-datastore"
@@ -175,6 +176,9 @@ func setupNode(ctx context.Context, n *IpfsNode, cfg *BuildCfg) error {
175176
return err
176177
}
177178

179+
// TEMP: setting global sharding switch here
180+
uio.UseHAMTSharding = conf.Experimental.ShardingEnabled
181+
178182
opts.HasBloomFilterSize = conf.Datastore.BloomFilterSize
179183
if !cfg.Permament {
180184
opts.HasBloomFilterSize = 0

core/commands/ls.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,24 @@ The JSON output contains type information.
105105

106106
output := make([]LsObject, len(req.Arguments()))
107107
for i, dagnode := range dagnodes {
108+
dir, err := uio.NewDirectoryFromNode(nd.DAG, dagnode)
109+
if err != nil {
110+
res.SetError(err, cmds.ErrNormal)
111+
return
112+
}
113+
114+
links, err := dir.Links()
115+
if err != nil {
116+
res.SetError(err, cmds.ErrNormal)
117+
return
118+
}
119+
108120
output[i] = LsObject{
109121
Hash: paths[i],
110-
Links: make([]LsLink, len(dagnode.Links())),
122+
Links: make([]LsLink, len(links)),
111123
}
112-
for j, link := range dagnode.Links() {
124+
125+
for j, link := range links {
113126
t := unixfspb.Data_DataType(-1)
114127

115128
linkNode, err := link.GetNode(req.Context(), dserv)

core/coreunix/add.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,15 +190,18 @@ func (adder *Adder) PinRoot() error {
190190
func (adder *Adder) Finalize() (node.Node, error) {
191191
root := adder.mr.GetValue()
192192

193-
// cant just call adder.RootNode() here as we need the name for printing
194-
rootNode, err := root.GetNode()
193+
err := root.Flush()
195194
if err != nil {
196195
return nil, err
197196
}
198197

199198
var name string
200199
if !adder.Wrap {
201-
name = rootNode.Links()[0].Name
200+
children, err := root.(*mfs.Directory).ListNames()
201+
if err != nil {
202+
return nil, err
203+
}
204+
name = children[0]
202205

203206
dir, ok := adder.mr.GetValue().(*mfs.Directory)
204207
if !ok {

mfs/dir.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func NewDirectory(ctx context.Context, name string, node node.Node, parent child
5959

6060
// closeChild updates the child by the given name to the dag node 'nd'
6161
// and changes its own dag node
62-
func (d *Directory) closeChild(name string, nd *dag.ProtoNode, sync bool) error {
62+
func (d *Directory) closeChild(name string, nd node.Node, sync bool) error {
6363
mynd, err := d.closeChildUpdate(name, nd, sync)
6464
if err != nil {
6565
return err
@@ -72,7 +72,7 @@ func (d *Directory) closeChild(name string, nd *dag.ProtoNode, sync bool) error
7272
}
7373

7474
// closeChildUpdate is the portion of closeChild that needs to be locked around
75-
func (d *Directory) closeChildUpdate(name string, nd *dag.ProtoNode, sync bool) (*dag.ProtoNode, error) {
75+
func (d *Directory) closeChildUpdate(name string, nd node.Node, sync bool) (*dag.ProtoNode, error) {
7676
d.lock.Lock()
7777
defer d.lock.Unlock()
7878

@@ -329,13 +329,10 @@ func (d *Directory) Unlink(name string) error {
329329
}
330330

331331
func (d *Directory) Flush() error {
332-
d.lock.Lock()
333-
nd, err := d.flushCurrentNode()
332+
nd, err := d.GetNode()
334333
if err != nil {
335-
d.lock.Unlock()
336334
return err
337335
}
338-
d.lock.Unlock()
339336

340337
return d.parent.closeChild(d.name, nd, true)
341338
}

mfs/mfs_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ func TestMfsHugeDir(t *testing.T) {
752752
defer cancel()
753753
_, rt := setupRoot(ctx, t)
754754

755-
for i := 0; i < 100000; i++ {
755+
for i := 0; i < 10000; i++ {
756756
err := Mkdir(rt, fmt.Sprintf("/dir%d", i), false, false)
757757
if err != nil {
758758
t.Fatal(err)

mfs/system.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ var log = logging.Logger("mfs")
3030
var ErrIsDirectory = errors.New("error: is a directory")
3131

3232
type childCloser interface {
33-
closeChild(string, *dag.ProtoNode, bool) error
33+
closeChild(string, node.Node, bool) error
3434
}
3535

3636
type NodeType int
@@ -124,7 +124,7 @@ func (kr *Root) Flush() error {
124124

125125
// closeChild implements the childCloser interface, and signals to the publisher that
126126
// there are changes ready to be published
127-
func (kr *Root) closeChild(name string, nd *dag.ProtoNode, sync bool) error {
127+
func (kr *Root) closeChild(name string, nd node.Node, sync bool) error {
128128
c, err := kr.dserv.Add(nd)
129129
if err != nil {
130130
return err

repo/config/experiments.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ package config
22

33
type Experiments struct {
44
FilestoreEnabled bool
5+
ShardingEnabled bool
56
}

test/sharness/t0040-add-and-cat.sh

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -207,20 +207,6 @@ test_add_named_pipe() {
207207
'
208208
}
209209

210-
test_add_sharded_dir() {
211-
mkdir testdata
212-
for i in `seq 2000`
213-
do
214-
echo $i > testdata/file$i
215-
done
216-
217-
test_expect_success "ipfs add on very large directory succeeds" '
218-
ipfs add -r -q testdata | tail -n1 > sharddir_out &&
219-
echo QmSCJD1KYLhVVHqBK3YyXuoEqHt7vggyJhzoFYbT8v1XYL > sharddir_exp &&
220-
test_cmp sharddir_exp sharddir_out
221-
'
222-
}
223-
224210
test_add_pwd_is_symlink() {
225211
test_expect_success "ipfs add -r adds directory content when ./ is symlink" '
226212
mkdir hellodir &&
@@ -453,8 +439,6 @@ test_kill_ipfs_daemon
453439

454440
test_add_cat_file
455441

456-
test_add_sharded_dir
457-
458442
test_add_cat_raw
459443

460444
test_expect_success "ipfs add --only-hash succeeds" '
@@ -475,8 +459,6 @@ test_launch_ipfs_daemon --offline
475459

476460
test_add_cat_file
477461

478-
test_add_sharded_dir
479-
480462
test_kill_ipfs_daemon
481463

482464
test_done

test/sharness/t0260-sharding-flag.sh

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#!/bin/sh
2+
#
3+
# Copyright (c) 2014 Christian Couder
4+
# MIT Licensed; see the LICENSE file in this repository.
5+
#
6+
7+
test_description="Test global enable sharding flag"
8+
9+
. lib/test-lib.sh
10+
11+
test_expect_success "set up test data" '
12+
mkdir testdata
13+
for i in `seq 2000`
14+
do
15+
echo $i > testdata/file$i
16+
done
17+
'
18+
19+
test_add_large_dir() {
20+
exphash="$1"
21+
test_expect_success "ipfs add on very large directory succeeds" '
22+
ipfs add -r -q testdata | tail -n1 > sharddir_out &&
23+
echo "$exphash" > sharddir_exp &&
24+
test_cmp sharddir_exp sharddir_out
25+
'
26+
}
27+
28+
test_init_ipfs
29+
30+
UNSHARDED="QmavrTrQG4VhoJmantURAYuw3bowq3E2WcvP36NRQDAC1N"
31+
test_add_large_dir "$UNSHARDED"
32+
33+
test_launch_ipfs_daemon
34+
35+
test_add_large_dir "$UNSHARDED"
36+
37+
test_kill_ipfs_daemon
38+
39+
test_expect_success "enable sharding" '
40+
ipfs config --json Experimental.ShardingEnabled true
41+
'
42+
43+
SHARDED="QmSCJD1KYLhVVHqBK3YyXuoEqHt7vggyJhzoFYbT8v1XYL"
44+
test_add_large_dir "$SHARDED"
45+
46+
test_launch_ipfs_daemon
47+
48+
test_add_large_dir "$SHARDED"
49+
50+
test_kill_ipfs_daemon
51+
52+
test_expect_success "sharded and unsharded output look the same" '
53+
ipfs ls "$SHARDED" | sort > sharded_out &&
54+
ipfs ls "$UNSHARDED" | sort > unsharded_out &&
55+
test_cmp sharded_out unsharded_out
56+
'
57+
58+
test_done

unixfs/io/dirbuilder.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ import (
1717
// result in the node being restructured into a sharded object.
1818
var ShardSplitThreshold = 1000
1919

20+
// UseHAMTSharding is a global flag that signifies whether or not to use the
21+
// HAMT sharding scheme for directory creation
22+
var UseHAMTSharding = false
23+
2024
// DefaultShardWidth is the default value used for hamt sharding width.
2125
var DefaultShardWidth = 256
2226

@@ -31,7 +35,15 @@ type Directory struct {
3135
func NewDirectory(dserv mdag.DAGService) *Directory {
3236
db := new(Directory)
3337
db.dserv = dserv
34-
db.dirnode = format.EmptyDirNode()
38+
if UseHAMTSharding {
39+
s, err := hamt.NewHamtShard(dserv, DefaultShardWidth)
40+
if err != nil {
41+
panic(err) // will only panic if DefaultShardWidth is a bad value
42+
}
43+
db.shard = s
44+
} else {
45+
db.dirnode = format.EmptyDirNode()
46+
}
3547
return db
3648
}
3749

@@ -70,7 +82,7 @@ func NewDirectoryFromNode(dserv mdag.DAGService, nd node.Node) (*Directory, erro
7082
// AddChild adds a (name, key)-pair to the root node.
7183
func (d *Directory) AddChild(ctx context.Context, name string, nd node.Node) error {
7284
if d.shard == nil {
73-
if len(d.dirnode.Links()) < ShardSplitThreshold {
85+
if !UseHAMTSharding {
7486
_ = d.dirnode.RemoveNodeLink(name)
7587
return d.dirnode.AddNodeLinkClean(name, nd)
7688
}

0 commit comments

Comments
 (0)