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

Commit 542c06c

Browse files
committed
fs: Don't make implicit entries for actual files (fix #430)
This is actually a little more efficient, too.
1 parent c932b56 commit 542c06c

File tree

1 file changed

+16
-17
lines changed

1 file changed

+16
-17
lines changed

fs.go

+16-17
Original file line numberDiff line numberDiff line change
@@ -549,25 +549,28 @@ func (f *ArchiveFS) ReadDir(name string) ([]fs.DirEntry, error) {
549549
// index this file info for quick access
550550
f.contents[file.NameInArchive] = file
551551

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

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

594593
return nil

0 commit comments

Comments
 (0)