7
7
"sync"
8
8
9
9
bserv "github.com/ipfs/go-ipfs/blockservice"
10
+ offline "github.com/ipfs/go-ipfs/exchange/offline"
10
11
key "gx/ipfs/QmYEoKZXHoAToWfhGF3vryhMn3WWhE1o2MasQ8uzY5iDi9/go-key"
11
12
12
13
"context"
@@ -28,10 +29,20 @@ type DAGService interface {
28
29
GetMany (context.Context , []* cid.Cid ) <- chan * NodeOption
29
30
30
31
Batch () * Batch
32
+
33
+ LinkService
34
+ }
35
+
36
+ type LinkService interface {
37
+ // Return all links for a node, may be more effect than
38
+ // calling Get in DAGService
39
+ GetLinks (context.Context , * cid.Cid ) ([]* Link , error )
40
+
41
+ GetOfflineLinkService () LinkService
31
42
}
32
43
33
- func NewDAGService (bs * bserv.BlockService ) DAGService {
34
- return & dagService {bs }
44
+ func NewDAGService (bs * bserv.BlockService ) * dagService {
45
+ return & dagService {Blocks : bs }
35
46
}
36
47
37
48
// dagService is an IPFS Merkle DAG service.
@@ -93,13 +104,30 @@ func (n *dagService) Get(ctx context.Context, c *cid.Cid) (*Node, error) {
93
104
return res , nil
94
105
}
95
106
107
+ func (n * dagService ) GetLinks (ctx context.Context , c * cid.Cid ) ([]* Link , error ) {
108
+ node , err := n .Get (ctx , c )
109
+ if err != nil {
110
+ return nil , err
111
+ }
112
+ return node .Links , nil
113
+ }
114
+
115
+ func (n * dagService ) GetOfflineLinkService () LinkService {
116
+ if n .Blocks .Exchange .IsOnline () {
117
+ bsrv := bserv .New (n .Blocks .Blockstore , offline .Exchange (n .Blocks .Blockstore ))
118
+ return NewDAGService (bsrv )
119
+ } else {
120
+ return n
121
+ }
122
+ }
123
+
96
124
func (n * dagService ) Remove (nd * Node ) error {
97
125
return n .Blocks .DeleteObject (nd )
98
126
}
99
127
100
128
// FetchGraph fetches all nodes that are children of the given node
101
- func FetchGraph (ctx context.Context , root * Node , serv DAGService ) error {
102
- return EnumerateChildrenAsync (ctx , serv , root , cid .NewSet ().Visit )
129
+ func FetchGraph (ctx context.Context , c * cid. Cid , serv DAGService ) error {
130
+ return EnumerateChildrenAsync (ctx , serv , c , cid .NewSet ().Visit )
103
131
}
104
132
105
133
// FindLinks searches this nodes links for the given key,
@@ -366,19 +394,17 @@ func legacyCidFromLink(lnk *Link) *cid.Cid {
366
394
// EnumerateChildren will walk the dag below the given root node and add all
367
395
// unseen children to the passed in set.
368
396
// TODO: parallelize to avoid disk latency perf hits?
369
- func EnumerateChildren (ctx context.Context , ds DAGService , root * Node , visit func (* cid.Cid ) bool , bestEffort bool ) error {
370
- for _ , lnk := range root .Links {
397
+ func EnumerateChildren (ctx context.Context , ds LinkService , root * cid.Cid , visit func (* cid.Cid ) bool , bestEffort bool ) error {
398
+ links , err := ds .GetLinks (ctx , root )
399
+ if bestEffort && err == ErrNotFound {
400
+ return nil
401
+ } else if err != nil {
402
+ return err
403
+ }
404
+ for _ , lnk := range links {
371
405
c := legacyCidFromLink (lnk )
372
406
if visit (c ) {
373
- child , err := ds .Get (ctx , c )
374
- if err != nil {
375
- if bestEffort && err == ErrNotFound {
376
- continue
377
- } else {
378
- return err
379
- }
380
- }
381
- err = EnumerateChildren (ctx , ds , child , visit , bestEffort )
407
+ err = EnumerateChildren (ctx , ds , c , visit , bestEffort )
382
408
if err != nil {
383
409
return err
384
410
}
@@ -387,7 +413,7 @@ func EnumerateChildren(ctx context.Context, ds DAGService, root *Node, visit fun
387
413
return nil
388
414
}
389
415
390
- func EnumerateChildrenAsync (ctx context.Context , ds DAGService , root * Node , visit func (* cid.Cid ) bool ) error {
416
+ func EnumerateChildrenAsync (ctx context.Context , ds DAGService , c * cid. Cid , visit func (* cid.Cid ) bool ) error {
391
417
toprocess := make (chan []* cid.Cid , 8 )
392
418
nodes := make (chan * NodeOption , 8 )
393
419
@@ -397,6 +423,11 @@ func EnumerateChildrenAsync(ctx context.Context, ds DAGService, root *Node, visi
397
423
398
424
go fetchNodes (ctx , ds , toprocess , nodes )
399
425
426
+ root , err := ds .Get (ctx , c )
427
+ if err != nil {
428
+ return err
429
+ }
430
+
400
431
nodes <- & NodeOption {Node : root }
401
432
live := 1
402
433
0 commit comments