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

Commit c930522

Browse files
committed
cleanup and switch to errgrp
1 parent 29ffa00 commit c930522

File tree

3 files changed

+42
-58
lines changed

3 files changed

+42
-58
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ require (
2121
github.com/spaolacci/murmur3 v1.1.0
2222
github.com/stretchr/testify v1.7.0
2323
github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830 // indirect
24+
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
2425
)
2526

2627
go 1.16

go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
335335
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
336336
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
337337
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
338+
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
338339
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
339340
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
340341
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=

hamt/hamt.go

Lines changed: 40 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import (
2626
"os"
2727
"sync"
2828

29+
"golang.org/x/sync/errgroup"
30+
2931
format "github.com/ipfs/go-unixfs"
3032
"github.com/ipfs/go-unixfs/internal"
3133

@@ -438,91 +440,71 @@ func (ds *Shard) walkLinks(processLinkValues func(formattedLink *ipld.Link) erro
438440

439441
func parallelWalkDepth(ctx context.Context, root *Shard, dserv ipld.DAGService, processShardValues func(formattedLink *ipld.Link) error) error {
440442
const concurrency = 32
441-
visit := cid.NewSet().Visit
443+
444+
var visitlk sync.Mutex
445+
visitSet := cid.NewSet()
446+
visit := visitSet.Visit
442447

443448
type shardCidUnion struct {
444449
cid cid.Cid
445450
shard *Shard
446451
}
447452

453+
// Setup synchronization
454+
grp, errGrpCtx := errgroup.WithContext(ctx)
455+
456+
// Input and output queues for workers.
448457
feed := make(chan *shardCidUnion)
449458
out := make(chan *listCidShardUnion)
450459
done := make(chan struct{})
451460

452-
var visitlk sync.Mutex
453-
var wg sync.WaitGroup
454-
455-
errChan := make(chan error)
456-
fetchersCtx, cancel := context.WithCancel(ctx)
457-
defer wg.Wait()
458-
defer cancel()
459461
for i := 0; i < concurrency; i++ {
460-
wg.Add(1)
461-
go func() {
462-
defer wg.Done()
463-
for cdepth := range feed {
462+
grp.Go(func() error {
463+
for shardOrCID := range feed {
464464
var shouldVisit bool
465465

466-
if cdepth.shard != nil {
466+
if shardOrCID.shard != nil {
467467
shouldVisit = true
468468
} else {
469469
visitlk.Lock()
470-
shouldVisit = visit(cdepth.cid)
470+
shouldVisit = visit(shardOrCID.cid)
471471
visitlk.Unlock()
472472
}
473473

474474
if shouldVisit {
475475
var nextShard *Shard
476-
if cdepth.shard != nil {
477-
nextShard = cdepth.shard
476+
if shardOrCID.shard != nil {
477+
nextShard = shardOrCID.shard
478478
} else {
479-
nd, err := dserv.Get(ctx, cdepth.cid)
479+
nd, err := dserv.Get(ctx, shardOrCID.cid)
480480
if err != nil {
481-
if err != nil {
482-
select {
483-
case errChan <- err:
484-
case <-fetchersCtx.Done():
485-
}
486-
return
487-
}
481+
return err
488482
}
489483
nextShard, err = NewHamtFromDag(dserv, nd)
490484
if err != nil {
491-
if err != nil {
492-
if err != nil {
493-
select {
494-
case errChan <- err:
495-
case <-fetchersCtx.Done():
496-
}
497-
return
498-
}
499-
}
485+
return err
500486
}
501487
}
502488

503489
nextLinks, err := nextShard.walkLinks(processShardValues)
504490
if err != nil {
505-
select {
506-
case errChan <- err:
507-
case <-fetchersCtx.Done():
508-
}
509-
return
491+
return err
510492
}
511493

512494
select {
513495
case out <- nextLinks:
514-
case <-fetchersCtx.Done():
515-
return
496+
case <-errGrpCtx.Done():
497+
return nil
516498
}
517499
}
518500
select {
519501
case done <- struct{}{}:
520-
case <-fetchersCtx.Done():
502+
case <-errGrpCtx.Done():
521503
}
522504
}
523-
}()
505+
return nil
506+
})
524507
}
525-
defer close(feed)
526508

527509
send := feed
528510
var todoQueue []*shardCidUnion
@@ -532,6 +514,7 @@ func parallelWalkDepth(ctx context.Context, root *Shard, dserv ipld.DAGService,
532514
shard: root,
533515
}
534516

517+
dispatcherLoop:
535518
for {
536519
select {
537520
case send <- next:
@@ -546,40 +529,39 @@ func parallelWalkDepth(ctx context.Context, root *Shard, dserv ipld.DAGService,
546529
case <-done:
547530
inProgress--
548531
if inProgress == 0 && next == nil {
549-
return nil
532+
break dispatcherLoop
550533
}
551-
case linksDepth := <-out:
552-
for _, c := range linksDepth.links {
553-
cd := &shardCidUnion{
534+
case nextNodes := <-out:
535+
for _, c := range nextNodes.links {
536+
shardOrCid := &shardCidUnion{
554537
cid: c,
555538
}
556539

557540
if next == nil {
558-
next = cd
541+
next = shardOrCid
559542
send = feed
560543
} else {
561-
todoQueue = append(todoQueue, cd)
544+
todoQueue = append(todoQueue, shardOrCid)
562545
}
563546
}
564-
for _, shard := range linksDepth.shards {
565-
cd := &shardCidUnion{
547+
for _, shard := range nextNodes.shards {
548+
shardOrCid := &shardCidUnion{
566549
shard: shard,
567550
}
568551

569552
if next == nil {
570-
next = cd
553+
next = shardOrCid
571554
send = feed
572555
} else {
573-
todoQueue = append(todoQueue, cd)
556+
todoQueue = append(todoQueue, shardOrCid)
574557
}
575558
}
576-
case err := <-errChan:
577-
return err
578-
579-
case <-ctx.Done():
580-
return ctx.Err()
559+
case <-errGrpCtx.Done():
560+
break dispatcherLoop
581561
}
582562
}
563+
close(feed)
564+
return grp.Wait()
583565
}
584566

585567
func emitResult(ctx context.Context, linkResults chan<- format.LinkResult, r format.LinkResult) {

0 commit comments

Comments
 (0)