From 9da367b7d5e7c71efd802b87c99c11faff141499 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 21 Feb 2007 22:45:10 +0000 Subject: [PATCH] * `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. --- src/libstore/gc.cc | 4 ++-- src/libstore/store-api.hh | 5 +++++ src/nix-store/nix-store.cc | 43 +++++--------------------------------- 3 files changed, 12 insertions(+), 40 deletions(-) diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index fa3b84b7a..2c75b16f6 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 1f2d60f11..8531eb040 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 store; diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 6399c0974..293becc68 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; }