Optimize walkdir for pages

This commit is contained in:
2026-04-21 20:04:13 +02:00
parent e0d2fb0b41
commit e8992235d4
+41 -10
View File
@@ -1,8 +1,8 @@
package main
import (
"bytes"
"fmt"
"io/fs"
"log"
"net/http"
"os"
@@ -44,20 +44,21 @@ func (h *handler) handleMove(w http.ResponseWriter, r *http.Request, srcURL, src
return
}
// Phase 1: walk the tree and rewrite every index.md whose content changes.
// Keep the pre-rewrite bytes in memory so we can revert on failure.
// Phase 1: walk the tree and rewrite every index.md that references the
// moved path. Keep the pre-rewrite bytes in memory so we can revert on
// failure. The walker only reads directory listings and files literally
// named index.md; hidden directories are pruned. A cheap substring check
// skips parsing files that cannot contain a relevant link.
rewritten := map[string][]byte{}
walkErr := filepath.WalkDir(h.root, func(fsPath string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() || d.Name() != "index.md" {
return nil
}
needle := []byte("[[" + oldPath)
walkErr := walkIndexFiles(h.root, func(fsPath string) error {
orig, err := os.ReadFile(fsPath)
if err != nil {
return err
}
if !bytes.Contains(orig, needle) {
return nil
}
updated, changed := rewriteWikiLinks(orig, oldPath, newPath)
if !changed {
return nil
@@ -186,6 +187,36 @@ func rollbackRewrites(rewritten map[string][]byte) {
}
}
// walkIndexFiles visits every `index.md` under root, skipping hidden
// directories (names beginning with `.`). Unlike filepath.WalkDir this does
// not stat each regular file — on spinning disks that saves the bulk of the
// traversal cost when folders contain many non-page files (photos, archives).
func walkIndexFiles(root string, visit func(fsPath string) error) error {
entries, err := os.ReadDir(root)
if err != nil {
return err
}
for _, e := range entries {
name := e.Name()
if strings.HasPrefix(name, ".") {
continue
}
full := filepath.Join(root, name)
if e.IsDir() {
if err := walkIndexFiles(full, visit); err != nil {
return err
}
continue
}
if name == "index.md" {
if err := visit(full); err != nil {
return err
}
}
}
return nil
}
// writeFileAtomic writes data to a temp file in the same directory as path
// and renames it into place so readers never observe a partial file.
func writeFileAtomic(path string, data []byte, perm os.FileMode) error {