about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2007-02-21T22·45+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2007-02-21T22·45+0000
commit9da367b7d5e7c71efd802b87c99c11faff141499 (patch)
tree211ee4b64462765ffe10e587981ce61ca473c616
parent881feb96987dace75f983c16fec1013b70602d4f (diff)
* `nix-store -qR' and friends: print the paths sorted topologically
  under the references relation.  This is useful for commands that
  want to copy paths to another Nix store in the right order.

-rw-r--r--src/libstore/gc.cc4
-rw-r--r--src/libstore/store-api.hh5
-rw-r--r--src/nix-store/nix-store.cc43
3 files changed, 12 insertions, 40 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index fa3b84b7afc9..2c75b16f61e6 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -417,7 +417,7 @@ static void dfsVisit(const PathSet & paths, const Path & path,
 }
 
 
-static Paths topoSort(const PathSet & paths)
+Paths topoSortPaths(const PathSet & paths)
 {
     Paths sorted;
     PathSet visited;
@@ -550,7 +550,7 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete,
        which things can be deleted safely. */
     /* !!! when we have multiple output paths per derivation, this
        will not work anymore because we get cycles. */
-    Paths storePaths = topoSort(storePathSet);
+    Paths storePaths = topoSortPaths(storePathSet);
 
     /* Try to delete store paths in the topologically sorted order. */
     for (Paths::iterator i = storePaths.begin(); i != storePaths.end(); ++i) {
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 1f2d60f11cb6..8531eb040496 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -242,6 +242,11 @@ Path addPermRoot(const Path & storePath, const Path & gcRoot,
     bool indirect, bool allowOutsideRootsDir = false);
 
 
+/* Sort a set of paths topologically under the references relation.
+   If p refers to q, then p follows q in this list. */
+Paths topoSortPaths(const PathSet & paths);
+
+
 /* For now, there is a single global store API object, but we'll
    purify that in the future. */
 extern boost::shared_ptr<StoreAPI> store;
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index 6399c097468a..293becc6869f 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -210,14 +210,6 @@ static Path maybeUseOutput(const Path & storePath, bool useOutput, bool forceRea
 }
 
 
-static void printPathSet(const PathSet & paths)
-{
-    for (PathSet::iterator i = paths.begin(); 
-         i != paths.end(); ++i)
-        cout << format("%s\n") % *i;
-}
-
-
 /* Some code to print a tree representation of a derivation dependency
    graph.  Topological sorting is used to keep the tree relatively
    flat. */
@@ -227,34 +219,6 @@ const string treeLine = "|   ";
 const string treeNull = "    ";
 
 
-static void dfsVisit(const PathSet & paths, const Path & path,
-    PathSet & visited, Paths & sorted)
-{
-    if (visited.find(path) != visited.end()) return;
-    visited.insert(path);
-    
-    PathSet closure;
-    computeFSClosure(path, closure);
-    
-    for (PathSet::iterator i = closure.begin();
-         i != closure.end(); ++i)
-        if (*i != path && paths.find(*i) != paths.end())
-            dfsVisit(paths, *i, visited, sorted);
-
-    sorted.push_front(path);
-}
-
-
-static Paths topoSort(const PathSet & paths)
-{
-    Paths sorted;
-    PathSet visited;
-    for (PathSet::const_iterator i = paths.begin(); i != paths.end(); ++i)
-        dfsVisit(paths, *i, visited, sorted);
-    return sorted;
-}
-
-
 static void printTree(const Path & path,
     const string & firstPad, const string & tailPad, PathSet & done)
 {
@@ -279,7 +243,7 @@ static void printTree(const Path & path,
        closure(B).  That is, if derivation A is an (possibly indirect)
        input of B, then A is printed first.  This has the effect of
        flattening the tree, preventing deeply nested structures.  */
-    Paths sorted = topoSort(references);
+    Paths sorted = topoSortPaths(references);
     reverse(sorted.begin(), sorted.end());
 
     for (Paths::iterator i = sorted.begin(); i != sorted.end(); ++i) {
@@ -355,7 +319,10 @@ static void opQuery(Strings opFlags, Strings opArgs)
                 else if (query == qReferrers) store->queryReferrers(path,  paths);
                 else if (query == qReferrersClosure) computeFSClosure(path, paths, true);
             }
-            printPathSet(paths);
+            Paths sorted = topoSortPaths(paths);
+            for (Paths::reverse_iterator i = sorted.rbegin(); 
+                 i != sorted.rend(); ++i)
+                cout << format("%s\n") % *i;
             break;
         }