Skip to content
This repository has been archived by the owner on Nov 19, 2024. It is now read-only.

Commit

Permalink
fs: Don't make implicit entries for actual files (fix #430)
Browse files Browse the repository at this point in the history
This is actually a little more efficient, too.
  • Loading branch information
mholt committed Nov 18, 2024
1 parent c932b56 commit 542c06c
Showing 1 changed file with 16 additions and 17 deletions.
33 changes: 16 additions & 17 deletions fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,25 +549,28 @@ func (f *ArchiveFS) ReadDir(name string) ([]fs.DirEntry, error) {
// index this file info for quick access
f.contents[file.NameInArchive] = file

// this is a real directory; prefer its DirEntry over an implicit/fake one we may have created earlier;
// first try to find if it exists, and if so, replace the value; otherwise insert it in sorted position
if file.IsDir() {
dirEntry := fs.FileInfoToDirEntry(file)
idx, found := slices.BinarySearchFunc(f.dirs[path.Dir(file.NameInArchive)], dirEntry, func(a, b fs.DirEntry) int {
return strings.Compare(a.Name(), b.Name())
})
if found {
f.dirs[path.Dir(file.NameInArchive)][idx] = dirEntry
} else {
f.dirs[path.Dir(file.NameInArchive)] = slices.Insert(f.dirs[path.Dir(file.NameInArchive)], idx, dirEntry)
}
// amortize the DirEntry list per directory, and prefer the real entry's DirEntry over an implicit/fake
// one we may have created earlier; first try to find if it exists, and if so, replace the value;
// otherwise insert it in sorted position
dir := path.Dir(file.NameInArchive)
dirEntry := fs.FileInfoToDirEntry(file)
idx, found := slices.BinarySearchFunc(f.dirs[dir], dirEntry, func(a, b fs.DirEntry) int {
return strings.Compare(a.Name(), b.Name())
})
if found {
f.dirs[dir][idx] = dirEntry
} else {
f.dirs[dir] = slices.Insert(f.dirs[dir], idx, dirEntry)
}

// this loop looks like an abomination, but it's really quite simple: we're
// just iterating the directories of the path up to the root; i.e. we lob off
// the base (last component) of the path until no separators remain, i.e. only
// one component remains -- then loop again to make sure it's not a duplicate
for dir, base := path.Dir(file.NameInArchive), path.Base(file.NameInArchive); ; dir, base = path.Dir(dir), path.Base(dir) {
// (start without the base, since we know the full filename is an actual entry
// in the archive, we don't need to create an implicit directory entry for it)
startingPath := path.Dir(file.NameInArchive)
for dir, base := path.Dir(startingPath), path.Base(startingPath); base != "."; dir, base = path.Dir(dir), path.Base(dir) {
if err := ctx.Err(); err != nil {
return err
}
Expand All @@ -585,10 +588,6 @@ func (f *ArchiveFS) ReadDir(name string) ([]fs.DirEntry, error) {
if !found {
f.dirs[dir] = slices.Insert(f.dirs[dir], idx, dirInfo)
}

if dir == "." {
break
}
}

return nil
Expand Down

0 comments on commit 542c06c

Please sign in to comment.