@cryptotaxi247 / kubo / commits / c8af993a8

iterator technique for unixfs dir listing

License: MIT Signed-off-by: Jeromy <why@ipfs.io>

Jeromy committed Nov 15, 2016 at 16:17 UTC c8af993a8c89d8301be7fe77c5714d4fd5b9e95d
3 files changed +54 -51
mfs/dir.go
+31 -43
@@ -221,71 +221,59 @@ func (d *Directory) ListNames() ([]string, error) {
221 d.lock.Lock()
222 defer d.lock.Unlock()
223
224 - names := make(map[string]struct{})
225 - for n, _ := range d.childDirs {
226 - names[n] = struct{}{}
227 - }
228 - for n, _ := range d.files {
229 - names[n] = struct{}{}
230 - }
231 -
232 - links, err := d.dirbuilder.Links()
224 + var out []string
225 + err := d.dirbuilder.ForEachLink(func(l *node.Link) error {
226 + out = append(out, l.Name)
227 + return nil
228 + })
229 if err != nil {
230 return nil, err
231 }
232
237 - for _, l := range links {
238 - names[l.Name] = struct{}{}
239 - }
240 -
241 - var out []string
242 - for n, _ := range names {
243 - out = append(out, n)
244 - }
233 sort.Strings(out)
234
235 return out, nil
236 }
237
238 func (d *Directory) List() ([]NodeListing, error) {
251 - d.lock.Lock()
252 - defer d.lock.Unlock()
253 -
239 var out []NodeListing
240 + err := d.ForEachEntry(context.TODO(), func(nl NodeListing) error {
241 + out = append(out, nl)
242 + return nil
243 + })
244 + return out, err
245 +}
246
256 - links, err := d.dirbuilder.Links()
257 - if err != nil {
258 - return nil, err
259 - }
260 -
261 - for _, l := range links {
262 - child := NodeListing{}
263 - child.Name = l.Name
264 -
247 +func (d *Directory) ForEachEntry(ctx context.Context, f func(NodeListing) error) error {
248 + d.lock.Lock()
249 + defer d.lock.Unlock()
250 + return d.dirbuilder.ForEachLink(func(l *node.Link) error {
251 c, err := d.childUnsync(l.Name)
252 if err != nil {
267 - return nil, err
253 + return err
254 + }
255 +
256 + nd, err := c.GetNode()
257 + if err != nil {
258 + return err
259 + }
260 +
261 + child := NodeListing{
262 + Name: l.Name,
263 + Type: int(c.Type()),
264 + Hash: nd.Cid().String(),
265 }
266
270 - child.Type = int(c.Type())
267 if c, ok := c.(*File); ok {
268 size, err := c.Size()
269 if err != nil {
274 - return nil, err
270 + return err
271 }
272 child.Size = size
273 }
278 - nd, err := c.GetNode()
279 - if err != nil {
280 - return nil, err
281 - }
274
283 - child.Hash = nd.Cid().String()
284 -
285 - out = append(out, child)
286 - }
287 -
288 - return out, nil
275 + return f(child)
276 + })
277 }
278
279 func (d *Directory) Mkdir(name string) (*Directory, error) {
@@ -433,5 +421,5 @@ func (d *Directory) GetNode() (node.Node, error) {
421 return nil, err
422 }
423
436 - return nd, err
424 + return nd.Copy(), err
425 }
unixfs/hamt/hamt.go
+10 -8
@@ -321,7 +321,15 @@ func (ds *HamtShard) getValue(ctx context.Context, hv *hashBits, key string, cb
321
322 func (ds *HamtShard) EnumLinks() ([]*node.Link, error) {
323 var links []*node.Link
324 - err := ds.walkTrie(func(sv *shardValue) error {
324 + err := ds.ForEachLink(func(l *node.Link) error {
325 + links = append(links, l)
326 + return nil
327 + })
328 + return links, err
329 +}
330 +
331 +func (ds *HamtShard) ForEachLink(f func(*node.Link) error) error {
332 + return ds.walkTrie(func(sv *shardValue) error {
333 lnk, err := node.MakeLink(sv.val)
334 if err != nil {
335 return err
@@ -329,14 +337,8 @@ func (ds *HamtShard) EnumLinks() ([]*node.Link, error) {
337
338 lnk.Name = sv.key
339
332 - links = append(links, lnk)
333 - return nil
340 + return f(lnk)
341 })
335 - if err != nil {
336 - return nil, err
337 - }
338 -
339 - return links, nil
342 }
343
344 func (ds *HamtShard) walkTrie(cb func(*shardValue) error) error {
unixfs/io/dirbuilder.go
+13
@@ -102,6 +102,19 @@ func (d *Directory) switchToSharding(ctx context.Context) error {
102 return nil
103 }
104
105 +func (d *Directory) ForEachLink(f func(*node.Link) error) error {
106 + if d.shard == nil {
107 + for _, l := range d.dirnode.Links() {
108 + if err := f(l); err != nil {
109 + return err
110 + }
111 + }
112 + return nil
113 + }
114 +
115 + return d.shard.ForEachLink(f)
116 +}
117 +
118 func (d *Directory) Links() ([]*node.Link, error) {
119 if d.shard == nil {
120 return d.dirnode.Links(), nil