diff options
Diffstat (limited to 'src/libstore/misc.cc')
-rw-r--r-- | src/libstore/misc.cc | 175 |
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; } |