1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-06-30 18:13:54 +08:00

iterator technique for unixfs dir listing

License: MIT
Signed-off-by: Jeromy <why@ipfs.io>
This commit is contained in:
Jeromy
2016-11-15 16:17:22 -08:00
committed by Jeromy
parent 06fb495df1
commit c8af993a8c
3 changed files with 54 additions and 51 deletions

View File

@ -221,71 +221,59 @@ func (d *Directory) ListNames() ([]string, error) {
d.lock.Lock() d.lock.Lock()
defer d.lock.Unlock() defer d.lock.Unlock()
names := make(map[string]struct{}) var out []string
for n, _ := range d.childDirs { err := d.dirbuilder.ForEachLink(func(l *node.Link) error {
names[n] = struct{}{} out = append(out, l.Name)
} return nil
for n, _ := range d.files { })
names[n] = struct{}{}
}
links, err := d.dirbuilder.Links()
if err != nil { if err != nil {
return nil, err return nil, err
} }
for _, l := range links {
names[l.Name] = struct{}{}
}
var out []string
for n, _ := range names {
out = append(out, n)
}
sort.Strings(out) sort.Strings(out)
return out, nil return out, nil
} }
func (d *Directory) List() ([]NodeListing, error) { func (d *Directory) List() ([]NodeListing, error) {
var out []NodeListing
err := d.ForEachEntry(context.TODO(), func(nl NodeListing) error {
out = append(out, nl)
return nil
})
return out, err
}
func (d *Directory) ForEachEntry(ctx context.Context, f func(NodeListing) error) error {
d.lock.Lock() d.lock.Lock()
defer d.lock.Unlock() defer d.lock.Unlock()
return d.dirbuilder.ForEachLink(func(l *node.Link) error {
var out []NodeListing
links, err := d.dirbuilder.Links()
if err != nil {
return nil, err
}
for _, l := range links {
child := NodeListing{}
child.Name = l.Name
c, err := d.childUnsync(l.Name) c, err := d.childUnsync(l.Name)
if err != nil { if err != nil {
return nil, err return err
}
nd, err := c.GetNode()
if err != nil {
return err
}
child := NodeListing{
Name: l.Name,
Type: int(c.Type()),
Hash: nd.Cid().String(),
} }
child.Type = int(c.Type())
if c, ok := c.(*File); ok { if c, ok := c.(*File); ok {
size, err := c.Size() size, err := c.Size()
if err != nil { if err != nil {
return nil, err return err
} }
child.Size = size child.Size = size
} }
nd, err := c.GetNode()
if err != nil {
return nil, err
}
child.Hash = nd.Cid().String() return f(child)
})
out = append(out, child)
}
return out, nil
} }
func (d *Directory) Mkdir(name string) (*Directory, error) { func (d *Directory) Mkdir(name string) (*Directory, error) {
@ -433,5 +421,5 @@ func (d *Directory) GetNode() (node.Node, error) {
return nil, err return nil, err
} }
return nd, err return nd.Copy(), err
} }

View File

@ -321,7 +321,15 @@ func (ds *HamtShard) getValue(ctx context.Context, hv *hashBits, key string, cb
func (ds *HamtShard) EnumLinks() ([]*node.Link, error) { func (ds *HamtShard) EnumLinks() ([]*node.Link, error) {
var links []*node.Link var links []*node.Link
err := ds.walkTrie(func(sv *shardValue) error { err := ds.ForEachLink(func(l *node.Link) error {
links = append(links, l)
return nil
})
return links, err
}
func (ds *HamtShard) ForEachLink(f func(*node.Link) error) error {
return ds.walkTrie(func(sv *shardValue) error {
lnk, err := node.MakeLink(sv.val) lnk, err := node.MakeLink(sv.val)
if err != nil { if err != nil {
return err return err
@ -329,14 +337,8 @@ func (ds *HamtShard) EnumLinks() ([]*node.Link, error) {
lnk.Name = sv.key lnk.Name = sv.key
links = append(links, lnk) return f(lnk)
return nil
}) })
if err != nil {
return nil, err
}
return links, nil
} }
func (ds *HamtShard) walkTrie(cb func(*shardValue) error) error { func (ds *HamtShard) walkTrie(cb func(*shardValue) error) error {

View File

@ -102,6 +102,19 @@ func (d *Directory) switchToSharding(ctx context.Context) error {
return nil return nil
} }
func (d *Directory) ForEachLink(f func(*node.Link) error) error {
if d.shard == nil {
for _, l := range d.dirnode.Links() {
if err := f(l); err != nil {
return err
}
}
return nil
}
return d.shard.ForEachLink(f)
}
func (d *Directory) Links() ([]*node.Link, error) { func (d *Directory) Links() ([]*node.Link, error) {
if d.shard == nil { if d.shard == nil {
return d.dirnode.Links(), nil return d.dirnode.Links(), nil