about summary refs log tree commit diff
path: root/src/libstore/misc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/misc.cc')
-rw-r--r--src/libstore/misc.cc175
1 files changed, 84 insertions, 91 deletions
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index 736434ca4895..5c284d1b9ab2 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -1,21 +1,21 @@
-#include "misc.hh"
-#include "store-api.hh"
-#include "local-store.hh"
+#include "derivations.hh"
 #include "globals.hh"
+#include "local-store.hh"
+#include "store-api.hh"
 
 
 namespace nix {
 
 
-Derivation derivationFromPath(StoreAPI & store, const Path & drvPath)
+Derivation Store::derivationFromPath(const Path & drvPath)
 {
     assertStorePath(drvPath);
-    store.ensurePath(drvPath);
+    ensurePath(drvPath);
     return readDerivation(drvPath);
 }
 
 
-void computeFSClosure(StoreAPI & store, const Path & path,
+void Store::computeFSClosure(const Path & path,
     PathSet & paths, bool flipDirection, bool includeOutputs, bool includeDerivers)
 {
     if (paths.find(path) != paths.end()) return;
@@ -24,50 +24,41 @@ void computeFSClosure(StoreAPI & store, const Path & path,
     PathSet edges;
 
     if (flipDirection) {
-        store.queryReferrers(path, edges);
+        queryReferrers(path, edges);
 
         if (includeOutputs) {
-            PathSet derivers = store.queryValidDerivers(path);
-            foreach (PathSet::iterator, i, derivers)
-                edges.insert(*i);
+            PathSet derivers = queryValidDerivers(path);
+            for (auto & 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);
+            PathSet outputs = queryDerivationOutputs(path);
+            for (auto & i : outputs)
+                if (isValidPath(i) && queryPathInfo(i)->deriver == path)
+                    edges.insert(i);
         }
 
     } else {
-        store.queryReferences(path, edges);
+        auto info = queryPathInfo(path);
+        edges = info->references;
 
         if (includeOutputs && isDerivation(path)) {
-            PathSet outputs = store.queryDerivationOutputs(path);
-            foreach (PathSet::iterator, i, outputs)
-                if (store.isValidPath(*i)) edges.insert(*i);
+            PathSet outputs = queryDerivationOutputs(path);
+            for (auto & i : outputs)
+                if (isValidPath(i)) edges.insert(i);
         }
 
-        if (includeDerivers) {
-            Path deriver = store.queryDeriver(path);
-            if (store.isValidPath(deriver)) edges.insert(deriver);
-        }
+        if (includeDerivers && isValidPath(info->deriver))
+            edges.insert(info->deriver);
     }
 
-    foreach (PathSet::iterator, i, edges)
-        computeFSClosure(store, *i, paths, flipDirection, includeOutputs, includeDerivers);
-}
-
-
-Path findOutput(const Derivation & drv, string id)
-{
-    foreach (DerivationOutputs::const_iterator, i, drv.outputs)
-        if (i->first == id) return i->second.path;
-    throw Error(format("derivation has no output ‘%1%’") % id);
+    for (auto & i : edges)
+        computeFSClosure(i, paths, flipDirection, includeOutputs, includeDerivers);
 }
 
 
-void queryMissing(StoreAPI & store, const PathSet & targets,
+void Store::queryMissing(const PathSet & targets,
     PathSet & willBuild, PathSet & willSubstitute, PathSet & unknown,
     unsigned long long & downloadSize, unsigned long long & narSize)
 {
@@ -98,60 +89,60 @@ void queryMissing(StoreAPI & store, const PathSet & targets,
 
         PathSet query, todoDrv, todoNonDrv;
 
-        foreach (PathSet::iterator, i, todo) {
-            if (done.find(*i) != done.end()) continue;
-            done.insert(*i);
+        for (auto & i : todo) {
+            if (done.find(i) != done.end()) continue;
+            done.insert(i);
 
-            DrvPathWithOutputs i2 = parseDrvPathWithOutputs(*i);
+            DrvPathWithOutputs i2 = parseDrvPathWithOutputs(i);
 
             if (isDerivation(i2.first)) {
-                if (!store.isValidPath(i2.first)) {
+                if (!isValidPath(i2.first)) {
                     // FIXME: we could try to substitute p.
-                    unknown.insert(*i);
+                    unknown.insert(i);
                     continue;
                 }
-                Derivation drv = derivationFromPath(store, i2.first);
+                Derivation drv = derivationFromPath(i2.first);
 
                 PathSet invalid;
-                foreach (DerivationOutputs::iterator, j, drv.outputs)
-                    if (wantOutput(j->first, i2.second)
-                        && !store.isValidPath(j->second.path))
-                        invalid.insert(j->second.path);
+                for (auto & j : drv.outputs)
+                    if (wantOutput(j.first, i2.second)
+                        && !isValidPath(j.second.path))
+                        invalid.insert(j.second.path);
                 if (invalid.empty()) continue;
 
-                todoDrv.insert(*i);
-                if (settings.useSubstitutes && substitutesAllowed(drv))
+                todoDrv.insert(i);
+                if (settings.useSubstitutes && drv.substitutesAllowed())
                     query.insert(invalid.begin(), invalid.end());
             }
 
             else {
-                if (store.isValidPath(*i)) continue;
-                query.insert(*i);
-                todoNonDrv.insert(*i);
+                if (isValidPath(i)) continue;
+                query.insert(i);
+                todoNonDrv.insert(i);
             }
         }
 
         todo.clear();
 
         SubstitutablePathInfos infos;
-        store.querySubstitutablePathInfos(query, infos);
+        querySubstitutablePathInfos(query, infos);
 
-        foreach (PathSet::iterator, i, todoDrv) {
-            DrvPathWithOutputs i2 = parseDrvPathWithOutputs(*i);
+        for (auto & i : todoDrv) {
+            DrvPathWithOutputs i2 = parseDrvPathWithOutputs(i);
 
             // FIXME: cache this
-            Derivation drv = derivationFromPath(store, i2.first);
+            Derivation drv = derivationFromPath(i2.first);
 
             PathSet outputs;
             bool mustBuild = false;
-            if (settings.useSubstitutes && substitutesAllowed(drv)) {
-                foreach (DerivationOutputs::iterator, j, drv.outputs) {
-                    if (!wantOutput(j->first, i2.second)) continue;
-                    if (!store.isValidPath(j->second.path)) {
-                        if (infos.find(j->second.path) == infos.end())
+            if (settings.useSubstitutes && drv.substitutesAllowed()) {
+                for (auto & j : drv.outputs) {
+                    if (!wantOutput(j.first, i2.second)) continue;
+                    if (!isValidPath(j.second.path)) {
+                        if (infos.find(j.second.path) == infos.end())
                             mustBuild = true;
                         else
-                            outputs.insert(j->second.path);
+                            outputs.insert(j.second.path);
                     }
                 }
             } else
@@ -160,59 +151,61 @@ void queryMissing(StoreAPI & store, const PathSet & targets,
             if (mustBuild) {
                 willBuild.insert(i2.first);
                 todo.insert(drv.inputSrcs.begin(), drv.inputSrcs.end());
-                foreach (DerivationInputs::iterator, j, drv.inputDrvs)
-                    todo.insert(makeDrvPathWithOutputs(j->first, j->second));
+                for (auto & j : drv.inputDrvs)
+                    todo.insert(makeDrvPathWithOutputs(j.first, j.second));
             } else
                 todoNonDrv.insert(outputs.begin(), outputs.end());
         }
 
-        foreach (PathSet::iterator, i, todoNonDrv) {
-            done.insert(*i);
-            SubstitutablePathInfos::iterator info = infos.find(*i);
+        for (auto & i : todoNonDrv) {
+            done.insert(i);
+            SubstitutablePathInfos::iterator info = infos.find(i);
             if (info != infos.end()) {
-                willSubstitute.insert(*i);
+                willSubstitute.insert(i);
                 downloadSize += info->second.downloadSize;
                 narSize += info->second.narSize;
                 todo.insert(info->second.references.begin(), info->second.references.end());
             } else
-                unknown.insert(*i);
+                unknown.insert(i);
         }
     }
 }
 
 
-static void dfsVisit(StoreAPI & store, const PathSet & paths,
-    const Path & path, PathSet & visited, Paths & sorted,
-    PathSet & parents)
+Paths Store::topoSortPaths(const PathSet & paths)
 {
-    if (parents.find(path) != parents.end())
-        throw BuildError(format("cycle detected in the references of ‘%1%’") % path);
+    Paths sorted;
+    PathSet visited, parents;
 
-    if (visited.find(path) != visited.end()) return;
-    visited.insert(path);
-    parents.insert(path);
+    std::function<void(const Path & path)> dfsVisit;
 
-    PathSet references;
-    if (store.isValidPath(path))
-        store.queryReferences(path, references);
+    dfsVisit = [&](const Path & path) {
+        if (parents.find(path) != parents.end())
+            throw BuildError(format("cycle detected in the references of ‘%1%’") % path);
 
-    foreach (PathSet::iterator, i, references)
-        /* Don't traverse into paths that don't exist.  That can
-           happen due to substitutes for non-existent paths. */
-        if (*i != path && paths.find(*i) != paths.end())
-            dfsVisit(store, paths, *i, visited, sorted, parents);
+        if (visited.find(path) != visited.end()) return;
+        visited.insert(path);
+        parents.insert(path);
 
-    sorted.push_front(path);
-    parents.erase(path);
-}
+        PathSet references;
+        try {
+            references = queryPathInfo(path)->references;
+        } catch (InvalidPath &) {
+        }
 
+        for (auto & i : references)
+            /* Don't traverse into paths that don't exist.  That can
+               happen due to substitutes for non-existent paths. */
+            if (i != path && paths.find(i) != paths.end())
+                dfsVisit(i);
+
+        sorted.push_front(path);
+        parents.erase(path);
+    };
+
+    for (auto & i : paths)
+        dfsVisit(i);
 
-Paths topoSortPaths(StoreAPI & store, const PathSet & paths)
-{
-    Paths sorted;
-    PathSet visited, parents;
-    foreach (PathSet::const_iterator, i, paths)
-        dfsVisit(store, paths, *i, visited, sorted, parents);
     return sorted;
 }