diff options
author | Sergei Trofimovich <slyich@gmail.com> | 2022-03-17 18:36:45 +0000 |
---|---|---|
committer | Sergei Trofimovich <slyich@gmail.com> | 2022-03-17 18:47:29 +0000 |
commit | d58453f72ea584cac2e3362fd6a73fcf0e3b615e (patch) | |
tree | 3f3694ddf4e90fa27979bad22fb848ca28e06fbe /src/libstore | |
parent | a53c1dc96d059aea6d67726f44c37c39c95404e3 (diff) |
gc: don't visit implicit referrers on garbage collection
Before the change garbage collector was not considering
`.drv` and outputs as alive even if configuration says otherwise.
As a result `nix store gc --dry-run` could visit (and parse)
`.drv` files multiple times (worst case it's quadratic).
It happens because `alive` set was populating only runtime closure
without regard for actual configuration. The change fixes it.
Benchmark: my system has about 139MB, 40K `.drv` files.
Performance before the change:
$ time nix store gc --dry-run
real 4m22,148s
Performance after the change:
$ time nix store gc --dry-run
real 0m14,178s
Diffstat (limited to 'src/libstore')
-rw-r--r-- | src/libstore/gc.cc | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 69755bd19..f65fb1b2e 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -678,7 +678,8 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) alive.insert(start); try { StorePathSet closure; - computeFSClosure(*path, closure); + computeFSClosure(*path, closure, + /* flipDirection */ false, gcKeepOutputs, gcKeepDerivations); for (auto & p : closure) alive.insert(p); } catch (InvalidPath &) { } |