-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdag.go
91 lines (82 loc) · 2.02 KB
/
dag.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package rcpinner
import (
"context"
"github.com/ipfs/boxo/ipld/merkledag"
"github.com/ipfs/go-cid"
format "github.com/ipfs/go-ipld-format"
)
// NOTE(kmax): function forked from github.com/ipfs/boxo/ipld/merkledag package
// with refactoring to support with dag size stats.
// FetchGraphWithDepthLimit fetches all nodes that are children to the given
// node down to the given depth. maxDepth=0 means "only fetch root",
// maxDepth=1 means "fetch root and its direct children" and so on...
// maxDepth=-1 means unlimited.
func FetchGraphWithDepthLimit(
ctx context.Context,
root cid.Cid,
depthLim int,
serv format.DAGService,
) error {
var ng format.NodeGetter = merkledag.NewSession(ctx, serv)
set := make(map[cid.Cid]int)
// Visit function returns true when:
// * The element is not in the set and we're not over depthLim
// * The element is in the set but recorded depth is deeper
// than currently seen (if we find it higher in the tree we'll need
// to explore deeper than before).
// depthLim = -1 means we only return true if the element is not in the
// set.
visit := func(c cid.Cid, depth int) bool {
oldDepth, ok := set[c]
if (ok && depthLim < 0) || (depthLim >= 0 && depth > depthLim) {
return false
}
if !ok || oldDepth > depth {
set[c] = depth
return true
}
return false
}
st := DagSize(ctx)
pt := ProgressTracker(ctx)
cc := Concurrency(ctx)
if cc == 0 {
cc = 32
}
return merkledag.WalkDepth(
ctx,
func(
ctx context.Context,
c cid.Cid,
) ([]*format.Link, error) {
nd, err := ng.Get(ctx, c)
if err != nil {
return nil, err
}
links := nd.Links()
if st != nil {
var sz uint64
if len(links) == 0 {
if sz, err = nd.Size(); err != nil {
return nil, err
}
} else {
sz = uint64(len(nd.RawData()))
}
st.Add(sz)
}
return links, nil
},
root,
func(c cid.Cid, depth int) bool {
if visit(c, depth) {
if pt != nil {
pt.Increment()
}
return true
}
return false
},
merkledag.Concurrency(cc),
)
}