aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/gc.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2021-10-14 14:13:57 +0200
committerEelco Dolstra <edolstra@gmail.com>2021-10-14 14:13:57 +0200
commit17e6ebcc90b6c7d5db8588f1d2b914c98543560b (patch)
tree9e0b05cdcd3e718086c3e1ac3bff67c60ebd6618 /src/libstore/gc.cc
parent0154fa30cf2a6da63e69f7488cec9e289f57cc15 (diff)
Speed up GC by marking entire closures as live
Diffstat (limited to 'src/libstore/gc.cc')
-rw-r--r--src/libstore/gc.cc20
1 files changed, 14 insertions, 6 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 800a3fd19..03d44ebf8 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -654,12 +654,22 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
handle it again. */
if (dead.count(*path)) continue;
+ auto markAlive = [&]()
+ {
+ alive.insert(*path);
+ alive.insert(start);
+ try {
+ StorePathSet closure;
+ computeFSClosure(*path, closure);
+ for (auto & p : closure)
+ alive.insert(p);
+ } catch (InvalidPath &) { }
+ };
+
/* If this is a root, bail out. */
if (roots.count(*path)) {
debug("cannot delete '%s' because it's a root", printStorePath(*path));
- alive.insert(*path);
- alive.insert(start);
- return;
+ return markAlive();
}
if (options.action == GCOptions::gcDeleteSpecific
@@ -671,9 +681,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
auto shared(_shared.lock());
if (shared->tempRoots.count(hashPart)) {
debug("cannot delete '%s' because it's a temporary root", printStorePath(*path));
- alive.insert(*path);
- alive.insert(start);
- return;
+ return markAlive();
}
shared->pending = hashPart;
}