15
"github.com/ipfs/go-ipfs/tracing"
16
path "github.com/ipfs/go-path"
17
"github.com/ipfs/go-path/resolver"
18
+ options "github.com/ipfs/interface-go-ipfs-core/options"
19
ipath "github.com/ipfs/interface-go-ipfs-core/path"
20
"go.opentelemetry.io/otel/attribute"
21
"go.opentelemetry.io/otel/trace"
103
return
104
}
105
106
+ // Optimization 1:
107
+ // List children without fetching their root blocks (fast, but no size info)
108
+ results, err := i.api.Unixfs().Ls(ctx, resolvedPath, options.Unixfs.ResolveChildren(false))
109
+ if err != nil {
110
+ internalWebError(w, err)
111
+ return
112
+ }
113
+
114
// storage for directory listing
106
- var dirListing []directoryItem
107
- dirit := dir.Entries()
108
- for dirit.Next() {
109
- size := "?"
110
- if s, err := dirit.Node().Size(); err == nil {
111
- // Size may not be defined/supported. Continue anyways.
112
- size = humanize.Bytes(uint64(s))
113
- }
115
+ dirListing := make([]directoryItem, 0, len(results))
116
115
- resolved, err := i.api.ResolvePath(ctx, ipath.Join(resolvedPath, dirit.Name()))
116
- if err != nil {
117
+ for link := range results {
118
+ if link.Err != nil {
119
internalWebError(w, err)
120
return
121
}
120
- hash := resolved.Cid().String()
121
-
122
- // See comment above where originalUrlPath is declared.
122
+ hash := link.Cid.String()
123
di := directoryItem{
124
- Size: size,
125
- Name: dirit.Name(),
126
- Path: gopath.Join(originalUrlPath, dirit.Name()),
124
+ Size: "", // no size because we did not fetch child nodes
125
+ Name: link.Name,
126
+ Path: gopath.Join(originalUrlPath, link.Name),
127
Hash: hash,
128
ShortHash: shortHash(hash),
129
}
130
dirListing = append(dirListing, di)
131
}
132
- if dirit.Err() != nil {
133
- internalWebError(w, dirit.Err())
134
- return
132
+
133
+ // Optimization 2: fetch sizes only for dirs below FastDirIndexThreshold
134
+ if len(dirListing) < i.config.FastDirIndexThreshold {
135
+ dirit := dir.Entries()
136
+ linkNo := 0
137
+ for dirit.Next() {
138
+ size := "?"
139
+ if s, err := dirit.Node().Size(); err == nil {
140
+ // Size may not be defined/supported. Continue anyways.
141
+ size = humanize.Bytes(uint64(s))
142
+ }
143
+ dirListing[linkNo].Size = size
144
+ linkNo++
145
+ }
146
}
147
148
// construct the correct back link
191
192
// See comment above where originalUrlPath is declared.
193
tplData := listingTemplateData{
183
- GatewayURL: gwURL,
184
- DNSLink: dnslink,
185
- Listing: dirListing,
186
- Size: size,
187
- Path: contentPath.String(),
188
- Breadcrumbs: breadcrumbs(contentPath.String(), dnslink),
189
- BackLink: backLink,
190
- Hash: hash,
194
+ GatewayURL: gwURL,
195
+ DNSLink: dnslink,
196
+ Listing: dirListing,
197
+ Size: size,
198
+ Path: contentPath.String(),
199
+ Breadcrumbs: breadcrumbs(contentPath.String(), dnslink),
200
+ BackLink: backLink,
201
+ Hash: hash,
202
+ FastDirIndexThreshold: i.config.FastDirIndexThreshold,
203
}
204
205
logger.Debugw("request processed", "tplDataDNSLink", dnslink, "tplDataSize", size, "tplDataBackLink", backLink, "tplDataHash", hash)