hugofs: Make FileMeta a struct

This commit started out investigating a `concurrent map read write` issue, ending by replacing the map with a struct.

This is easier to reason about, and it's more effective:

```
name                                  old time/op    new time/op    delta
SiteNew/Regular_Deep_content_tree-16    71.5ms ± 3%    69.4ms ± 5%    ~     (p=0.200 n=4+4)

name                                  old alloc/op   new alloc/op   delta
SiteNew/Regular_Deep_content_tree-16    29.7MB ± 0%    27.9MB ± 0%  -5.82%  (p=0.029 n=4+4)

name                                  old allocs/op  new allocs/op  delta
SiteNew/Regular_Deep_content_tree-16      313k ± 0%      303k ± 0%  -3.35%  (p=0.029 n=4+4)
```

See #8749
This commit is contained in:
Bjørn Erik Pedersen
2021-07-13 11:41:02 +02:00
parent f27e542442
commit 022c479551
44 changed files with 434 additions and 451 deletions

View File

@@ -73,7 +73,7 @@ type WalkwayConfig struct {
func NewWalkway(cfg WalkwayConfig) *Walkway {
var fs afero.Fs
if cfg.Info != nil {
fs = cfg.Info.Meta().Fs()
fs = cfg.Info.Meta().Fs
} else {
fs = cfg.Fs
}
@@ -184,7 +184,7 @@ func (w *Walkway) walk(path string, info FileMetaInfo, dirEntries []FileMetaInfo
}
meta := info.Meta()
filename := meta.Filename()
filename := meta.Filename
if dirEntries == nil {
f, err := w.fs.Open(path)
@@ -206,7 +206,7 @@ func (w *Walkway) walk(path string, info FileMetaInfo, dirEntries []FileMetaInfo
dirEntries = fileInfosToFileMetaInfos(fis)
if !meta.IsOrdered() {
if !meta.IsOrdered {
sort.Slice(dirEntries, func(i, j int) bool {
fii := dirEntries[i]
fij := dirEntries[j]
@@ -214,7 +214,7 @@ func (w *Walkway) walk(path string, info FileMetaInfo, dirEntries []FileMetaInfo
fim, fjm := fii.Meta(), fij.Meta()
// Pull bundle headers to the top.
ficlass, fjclass := fim.Classifier(), fjm.Classifier()
ficlass, fjclass := fim.Classifier, fjm.Classifier
if ficlass != fjclass {
return ficlass < fjclass
}
@@ -222,20 +222,20 @@ func (w *Walkway) walk(path string, info FileMetaInfo, dirEntries []FileMetaInfo
// With multiple content dirs with different languages,
// there can be duplicate files, and a weight will be added
// to the closest one.
fiw, fjw := fim.Weight(), fjm.Weight()
fiw, fjw := fim.Weight, fjm.Weight
if fiw != fjw {
return fiw > fjw
}
// Explicit order set.
fio, fjo := fim.Ordinal(), fjm.Ordinal()
fio, fjo := fim.Ordinal, fjm.Ordinal
if fio != fjo {
return fio < fjo
}
// When we walk into a symlink, we keep the reference to
// the original name.
fin, fjn := fim.Name(), fjm.Name()
fin, fjn := fim.Name, fjm.Name
if fin != "" && fjn != "" {
return fin < fjn
}
@@ -252,7 +252,7 @@ func (w *Walkway) walk(path string, info FileMetaInfo, dirEntries []FileMetaInfo
meta := fim.Meta()
// Note that we use the original Name even if it's a symlink.
name := meta.Name()
name := meta.Name
if name == "" {
name = fim.Name()
}
@@ -267,13 +267,13 @@ func (w *Walkway) walk(path string, info FileMetaInfo, dirEntries []FileMetaInfo
pathMeta = strings.TrimPrefix(pathn, w.basePath)
}
meta[metaKeyPath] = normalizeFilename(pathMeta)
meta[metaKeyPathWalk] = pathn
meta.Path = normalizeFilename(pathMeta)
meta.PathWalk = pathn
if fim.IsDir() && w.isSeen(meta.Filename()) {
if fim.IsDir() && w.isSeen(meta.Filename) {
// Prevent infinite recursion
// Possible cyclic reference
meta[metaKeySkipDir] = true
meta.SkipDir = true
}
}
@@ -291,11 +291,11 @@ func (w *Walkway) walk(path string, info FileMetaInfo, dirEntries []FileMetaInfo
fim := fi.(FileMetaInfo)
meta := fim.Meta()
if meta.SkipDir() {
if meta.SkipDir {
continue
}
err := w.walk(meta.GetString(metaKeyPathWalk), fim, nil, walkFn)
err := w.walk(meta.PathWalk, fim, nil, walkFn)
if err != nil {
if !fi.IsDir() || err != filepath.SkipDir {
return err