Skip to content
This repository was archived by the owner on Jun 27, 2023. It is now read-only.

Commit 45f703f

Browse files
committed
Refactor for readability, consistency
1 parent f1b6104 commit 45f703f

File tree

1 file changed

+53
-23
lines changed

1 file changed

+53
-23
lines changed

hamt/hamt.go

+53-23
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ import (
2828

2929
dag "github.com/ipfs/go-merkledag"
3030

31-
format "github.com/ipfs/go-unixfs"
3231
bitfield "github.com/Stebalien/go-bitfield"
3332
cid "github.com/ipfs/go-cid"
3433
ipld "github.com/ipfs/go-ipld-format"
3534
"github.com/spaolacci/murmur3"
35+
36+
format "github.com/ipfs/go-unixfs"
3637
)
3738

3839
const (
@@ -106,7 +107,6 @@ func NewHamtFromDag(dserv ipld.DAGService, nd ipld.Node) (*Shard, error) {
106107
return nil, err
107108
}
108109

109-
110110
if fsn.Type() != format.THAMTShard {
111111
return nil, fmt.Errorf("node was not a dir shard")
112112
}
@@ -204,6 +204,14 @@ func (sv *shardValue) Label() string {
204204
return sv.key
205205
}
206206

207+
func (ds *Shard) makeShardValue(lnk *ipld.Link) *shardValue {
208+
lnk2 := *lnk
209+
return &shardValue{
210+
key: lnk.Name[ds.maxpadlen:],
211+
val: &lnk2,
212+
}
213+
}
214+
207215
func hash(val []byte) []byte {
208216
h := murmur3.New64()
209217
h.Write(val)
@@ -255,6 +263,24 @@ func (ds *Shard) Find(ctx context.Context, name string) (*ipld.Link, error) {
255263
return out, nil
256264
}
257265

266+
type linkType int
267+
268+
const (
269+
invalidLink linkType = iota
270+
shardLink
271+
shardValueLink
272+
)
273+
274+
func (ds *Shard) childLinkType(lnk *ipld.Link) (linkType, error) {
275+
if len(lnk.Name) < ds.maxpadlen {
276+
return invalidLink, fmt.Errorf("invalid link name '%s'", lnk.Name)
277+
}
278+
if len(lnk.Name) == ds.maxpadlen {
279+
return shardLink, nil
280+
}
281+
return shardValueLink, nil
282+
}
283+
258284
// getChild returns the i'th child of this shard. If it is cached in the
259285
// children array, it will return it from there. Otherwise, it loads the child
260286
// node from disk.
@@ -279,12 +305,13 @@ func (ds *Shard) getChild(ctx context.Context, i int) (child, error) {
279305
// as a 'child' interface
280306
func (ds *Shard) loadChild(ctx context.Context, i int) (child, error) {
281307
lnk := ds.nd.Links()[i]
282-
if len(lnk.Name) < ds.maxpadlen {
283-
return nil, fmt.Errorf("invalid link name '%s'", lnk.Name)
308+
lnkLinkType, err := ds.childLinkType(lnk)
309+
if err != nil {
310+
return nil, err
284311
}
285312

286313
var c child
287-
if len(lnk.Name) == ds.maxpadlen {
314+
if lnkLinkType == shardLink {
288315
nd, err := lnk.GetNode(ctx, ds.dserv)
289316
if err != nil {
290317
return nil, err
@@ -296,11 +323,7 @@ func (ds *Shard) loadChild(ctx context.Context, i int) (child, error) {
296323

297324
c = cds
298325
} else {
299-
lnk2 := *lnk
300-
c = &shardValue{
301-
key: lnk.Name[ds.maxpadlen:],
302-
val: &lnk2,
303-
}
326+
c = ds.makeShardValue(lnk)
304327
}
305328

306329
ds.children[i] = c
@@ -387,9 +410,11 @@ func (ds *Shard) EnumLinks(ctx context.Context) ([]*ipld.Link, error) {
387410
var links []*ipld.Link
388411
var setlk sync.Mutex
389412

390-
getLinks := ds.makeAsyncTrieGetLinks(func(l *ipld.Link) error {
413+
getLinks := makeAsyncTrieGetLinks(ds.dserv, func(sv *shardValue) error {
414+
lnk := sv.val
415+
lnk.Name = sv.key
391416
setlk.Lock()
392-
links = append(links, l)
417+
links = append(links, lnk)
393418
setlk.Unlock()
394419
return nil
395420
})
@@ -410,29 +435,34 @@ func (ds *Shard) ForEachLink(ctx context.Context, f func(*ipld.Link) error) erro
410435
})
411436
}
412437

413-
func (ds *Shard) makeAsyncTrieGetLinks(cb func(*ipld.Link) error) dag.GetLinks {
438+
// makeAsyncTrieGetLinks builds a getLinks function that can be used with EnumerateChildrenAsync
439+
// to iterate a HAMT shard. It takes an IPLD Dag Service to fetch nodes, and a call back that will get called
440+
// on all links to leaf nodes in a HAMT tree, so they can be collected for an EnumLinks operation
441+
func makeAsyncTrieGetLinks(dagService ipld.DAGService, onShardValue func(*shardValue) error) dag.GetLinks {
414442

415-
return func(ctx context.Context, c cid.Cid) ([]*ipld.Link, error) {
416-
node, err := ds.dserv.Get(ctx, c)
443+
return func(ctx context.Context, currentCid cid.Cid) ([]*ipld.Link, error) {
444+
node, err := dagService.Get(ctx, currentCid)
417445
if err != nil {
418446
return nil, err
419447
}
420-
cds, err := NewHamtFromDag(ds.dserv, node)
448+
directoryShard, err := NewHamtFromDag(dagService, node)
421449
if err != nil {
422450
return nil, err
423451
}
424452

425-
childShards := make([]*ipld.Link, 0, len(cds.children))
426-
for idx := range cds.children {
427-
lnk := cds.nd.Links()[idx]
453+
childShards := make([]*ipld.Link, 0, len(directoryShard.children))
454+
for idx := range directoryShard.children {
455+
lnk := directoryShard.nd.Links()[idx]
456+
lnkLinkType, err := directoryShard.childLinkType(lnk)
428457

429-
if len(lnk.Name) < cds.maxpadlen {
430-
return nil, fmt.Errorf("invalid link name '%s'", lnk.Name)
458+
if err != nil {
459+
return nil, err
431460
}
432-
if len(lnk.Name) == cds.maxpadlen {
461+
if lnkLinkType == shardLink {
433462
childShards = append(childShards, lnk)
434463
} else {
435-
cb(lnk)
464+
sv := directoryShard.makeShardValue(lnk)
465+
onShardValue(sv)
436466
}
437467
}
438468
return childShards, nil

0 commit comments

Comments
 (0)