about summary refs log tree commit diff
path: root/src/libstore
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/local-store.hh4
-rw-r--r--src/libstore/misc.cc54
-rw-r--r--src/libstore/misc.hh4
-rw-r--r--src/libstore/remote-store.cc10
-rw-r--r--src/libstore/remote-store.hh2
-rw-r--r--src/libstore/store-api.hh6
-rw-r--r--src/libstore/worker-protocol.hh3
7 files changed, 59 insertions, 24 deletions
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index bb5a9143ceef..82ca791a3fb2 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -111,10 +111,6 @@ public:
 
     Path queryDeriver(const Path & path);
 
-    /* Return all currently valid derivations that have `path' as an
-       output.  (Note that the result of `queryDeriver()' is the
-       derivation that was actually used to produce `path', which may
-       not exist anymore.) */
     PathSet queryValidDerivers(const Path & path);
 
     PathSet queryDerivationOutputs(const Path & path);
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index 899e4764c1d6..74ff26b9cc5c 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -15,27 +15,47 @@ Derivation derivationFromPath(StoreAPI & store, const Path & drvPath)
 }
 
 
-void computeFSClosure(StoreAPI & store, const Path & storePath,
-    PathSet & paths, bool flipDirection, bool includeOutputs)
+void computeFSClosure(StoreAPI & store, const Path & path,
+    PathSet & paths, bool flipDirection, bool includeOutputs, bool includeDerivers)
 {
-    if (paths.find(storePath) != paths.end()) return;
-    paths.insert(storePath);
+    if (paths.find(path) != paths.end()) return;
+    paths.insert(path);
 
-    PathSet references;
-    if (flipDirection)
-        store.queryReferrers(storePath, references);
-    else
-        store.queryReferences(storePath, references);
-
-    if (includeOutputs && isDerivation(storePath)) {
-        PathSet outputs = store.queryDerivationOutputs(storePath);
-        foreach (PathSet::iterator, i, outputs)
-            if (store.isValidPath(*i))
-                computeFSClosure(store, *i, paths, flipDirection, true);
+    PathSet edges;
+
+    if (flipDirection) {
+        store.queryReferrers(path, edges);
+
+        if (includeOutputs) {
+            PathSet derivers = store.queryValidDerivers(path);
+            foreach (PathSet::iterator, i, derivers)
+                edges.insert(*i);
+        }
+
+        if (includeDerivers && isDerivation(path)) {
+            PathSet outputs = store.queryDerivationOutputs(path);
+            foreach (PathSet::iterator, i, outputs)
+                if (store.isValidPath(*i) && store.queryDeriver(*i) == path)
+                    edges.insert(*i);
+        }
+
+    } else {
+        store.queryReferences(path, edges);
+
+        if (includeOutputs && isDerivation(path)) {
+            PathSet outputs = store.queryDerivationOutputs(path);
+            foreach (PathSet::iterator, i, outputs)
+                if (store.isValidPath(*i)) edges.insert(*i);
+        }
+
+        if (includeDerivers) {
+            Path deriver = store.queryDeriver(path);
+            if (store.isValidPath(deriver)) edges.insert(deriver);
+        }
     }
 
-    foreach (PathSet::iterator, i, references)
-        computeFSClosure(store, *i, paths, flipDirection, includeOutputs);
+    foreach (PathSet::iterator, i, edges)
+        computeFSClosure(store, *i, paths, flipDirection, includeOutputs, includeDerivers);
 }
 
 
diff --git a/src/libstore/misc.hh b/src/libstore/misc.hh
index fe0bbdd799d7..b4bd9ed8a49f 100644
--- a/src/libstore/misc.hh
+++ b/src/libstore/misc.hh
@@ -17,9 +17,9 @@ Derivation derivationFromPath(StoreAPI & store, const Path & drvPath);
    `storePath' is returned; that is, the closures under the
    `referrers' relation instead of the `references' relation is
    returned. */
-void computeFSClosure(StoreAPI & store, const Path & storePath,
+void computeFSClosure(StoreAPI & store, const Path & path,
     PathSet & paths, bool flipDirection = false,
-    bool includeOutputs = false);
+    bool includeOutputs = false, bool includeDerivers = false);
 
 /* Return the path corresponding to the output identifier `id' in the
    given derivation. */
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index c97c5fbf044e..8f33b7e5cd46 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -334,6 +334,16 @@ Path RemoteStore::queryDeriver(const Path & path)
 }
 
 
+PathSet RemoteStore::queryValidDerivers(const Path & path)
+{
+    openConnection();
+    writeInt(wopQueryValidDerivers, to);
+    writeString(path, to);
+    processStderr();
+    return readStorePaths<PathSet>(from);
+}
+
+
 PathSet RemoteStore::queryDerivationOutputs(const Path & path)
 {
     openConnection();
diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh
index 47c822969f50..14253b92cd0e 100644
--- a/src/libstore/remote-store.hh
+++ b/src/libstore/remote-store.hh
@@ -40,6 +40,8 @@ public:
 
     Path queryDeriver(const Path & path);
     
+    PathSet queryValidDerivers(const Path & path);
+
     PathSet queryDerivationOutputs(const Path & path);
     
     StringSet queryDerivationOutputNames(const Path & path);
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index cbbacc12c92a..053bece7a3a3 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -133,6 +133,12 @@ public:
        no deriver has been set. */
     virtual Path queryDeriver(const Path & path) = 0;
 
+    /* Return all currently valid derivations that have `path' as an
+       output.  (Note that the result of `queryDeriver()' is the
+       derivation that was actually used to produce `path', which may
+       not exist anymore.) */
+    virtual PathSet queryValidDerivers(const Path & path) = 0;
+
     /* Query the outputs of the derivation denoted by `path'. */
     virtual PathSet queryDerivationOutputs(const Path & path) = 0;
 
diff --git a/src/libstore/worker-protocol.hh b/src/libstore/worker-protocol.hh
index 7e4c3ec5fbde..46035f4577e3 100644
--- a/src/libstore/worker-protocol.hh
+++ b/src/libstore/worker-protocol.hh
@@ -6,7 +6,7 @@ namespace nix {
 #define WORKER_MAGIC_1 0x6e697863
 #define WORKER_MAGIC_2 0x6478696f
 
-#define PROTOCOL_VERSION 0x10c
+#define PROTOCOL_VERSION 0x10d
 #define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
 #define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
 
@@ -42,6 +42,7 @@ typedef enum {
     wopQuerySubstitutablePathInfos = 30,
     wopQueryValidPaths = 31,
     wopQuerySubstitutablePaths = 32,
+    wopQueryValidDerivers = 33,
 } WorkerOp;