diff options
author | Patrick Steinhardt <psteinhardt@gitlab.com> | 2022-03-24 16:30:24 +0300 |
---|---|---|
committer | Patrick Steinhardt <psteinhardt@gitlab.com> | 2022-03-24 17:37:33 +0300 |
commit | dc7d06d538128acd19ffe9dcae178fd615143409 (patch) | |
tree | d84584a02b7cc50a095b84a48919e26899b6ddeb | |
parent | eddec48155c974fbc14aed9122a44a7e0e5bdab2 (diff) |
housekeeping: Avoid stat calls when searching for locked refspks-houskeeping-clean-stale-data-walkdir
We use `filepath.Walk()` to search for stale reference locks, which will
stat every single directory entry we're finding. This is needless
busywork though: we would only ever consider files for deletion which
have a `.lock` suffix, so all the other stat calls are wasted.
Convert the function to instead use `filepath.WalkDir()` to reduce the
number of stat calls.
Changelog: performance
-rw-r--r-- | internal/git/housekeeping/clean_stale_data.go | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/internal/git/housekeeping/clean_stale_data.go b/internal/git/housekeeping/clean_stale_data.go index 39135a5cb..504bd6682 100644 --- a/internal/git/housekeeping/clean_stale_data.go +++ b/internal/git/housekeeping/clean_stale_data.go @@ -353,29 +353,40 @@ func findBrokenLooseReferences(ctx context.Context, repoPath string) ([]string, func findStaleReferenceLocks(ctx context.Context, repoPath string) ([]string, error) { var staleReferenceLocks []string - err := filepath.Walk(filepath.Join(repoPath, "refs"), func(path string, info os.FileInfo, err error) error { - if os.IsNotExist(err) { - // Race condition: somebody already deleted the file for us. Ignore this file. - return nil - } - + if err := filepath.WalkDir(filepath.Join(repoPath, "refs"), func(path string, dirEntry fs.DirEntry, err error) error { if err != nil { + if errors.Is(err, fs.ErrNotExist) || errors.Is(err, fs.ErrPermission) { + return nil + } + return err } - if info.IsDir() { + if dirEntry.IsDir() { return nil } - if !strings.HasSuffix(info.Name(), ".lock") || time.Since(info.ModTime()) < referenceLockfileGracePeriod { + if !strings.HasSuffix(dirEntry.Name(), ".lock") { + return nil + } + + fi, err := dirEntry.Info() + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + return nil + } + + return fmt.Errorf("statting reference lock: %w", err) + } + + if time.Since(fi.ModTime()) < referenceLockfileGracePeriod { return nil } staleReferenceLocks = append(staleReferenceLocks, path) return nil - }) - if err != nil { - return nil, err + }); err != nil { + return nil, fmt.Errorf("walking refs: %w", err) } return staleReferenceLocks, nil |