about summary refs log tree commit diff
path: root/src/nix-store/main.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2005-01-27T15·21+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2005-01-27T15·21+0000
commitc505702265833a762d681952bcc72562d64a242e (patch)
treeda6f095532755b766d7752d6925ea865ba0cefe2 /src/nix-store/main.cc
parent59682e618805701f9c249736514df6db457895f9 (diff)
* Fix and simplify the garbage collector (it's still not concurrent,
  though).  In particular it's now much easier to register a GC root.
  Just place a symlink to whatever store path it is that you want to
  keep in /nix/var/nix/gcroots.

Diffstat (limited to 'src/nix-store/main.cc')
-rw-r--r--src/nix-store/main.cc55
1 files changed, 13 insertions, 42 deletions
diff --git a/src/nix-store/main.cc b/src/nix-store/main.cc
index ea8d398f1a2d..810fe94b65eb 100644
--- a/src/nix-store/main.cc
+++ b/src/nix-store/main.cc
@@ -274,61 +274,32 @@ static void opIsValid(Strings opFlags, Strings opArgs)
 
 static void opGC(Strings opFlags, Strings opArgs)
 {
-#if 0
+    GCAction action;
+    
     /* Do what? */
-    enum { soPrintLive, soPrintDead, soDelete } subOp;
-    time_t minAge = 0;
     for (Strings::iterator i = opFlags.begin();
          i != opFlags.end(); ++i)
-        if (*i == "--print-live") subOp = soPrintLive;
-        else if (*i == "--print-dead") subOp = soPrintDead;
-        else if (*i == "--delete") subOp = soDelete;
-        else if (*i == "--min-age") {
-            int n;
-            if (opArgs.size() == 0 || !string2Int(opArgs.front(), n))
-                throw UsageError("`--min-age' requires an integer argument");
-            minAge = n;
-        }
+        if (*i == "--print-live") action = gcReturnLive;
+        else if (*i == "--print-dead") action = gcReturnDead;
+        else if (*i == "--delete") action = gcDeleteDead;
         else throw UsageError(format("bad sub-operation `%1%' in GC") % *i);
-        
-    Paths roots;
+
+    /* Read the roots. */
+    PathSet roots;
     while (1) {
         Path root;
         getline(cin, root);
         if (cin.eof()) break;
-        roots.push_back(root);
-    }
-
-    PathSet live = findLivePaths(roots);
-
-    if (subOp == soPrintLive) {
-        for (PathSet::iterator i = live.begin(); i != live.end(); ++i)
-            cout << *i << endl;
-        return;
+        roots.insert(root);
     }
 
-    PathSet dead = findDeadPaths(live, minAge * 3600);
+    PathSet result;
+    collectGarbage(roots, action, result);
 
-    if (subOp == soPrintDead) {
-        for (PathSet::iterator i = dead.begin(); i != dead.end(); ++i)
+    if (action != gcDeleteDead) {
+        for (PathSet::iterator i = result.begin(); i != result.end(); ++i)
             cout << *i << endl;
-        return;
     }
-
-    if (subOp == soDelete) {
-
-        /* !!! What happens if the garbage collector run is aborted
-           halfway through?  In particular, dead paths can always
-           become live again (through re-instantiation), and might
-           then refer to deleted paths. => check instantiation
-           invariants */
-
-        for (PathSet::iterator i = dead.begin(); i != dead.end(); ++i) {
-            printMsg(lvlInfo, format("deleting `%1%'") % *i);
-            deleteFromStore(*i);
-        }
-    }
-#endif
 }