Store::computeFSClosure(): Use thread pool

This speeds up queries against the binary cache.
This commit is contained in:
Eelco Dolstra 2016-07-21 14:13:35 +02:00
parent 77c2739c25
commit a728780fbd

View file

@ -2,6 +2,7 @@
#include "globals.hh" #include "globals.hh"
#include "local-store.hh" #include "local-store.hh"
#include "store-api.hh" #include "store-api.hh"
#include "thread-pool.hh"
namespace nix { namespace nix {
@ -10,43 +11,63 @@ namespace nix {
void Store::computeFSClosure(const Path & path, void Store::computeFSClosure(const Path & path,
PathSet & paths, bool flipDirection, bool includeOutputs, bool includeDerivers) PathSet & paths, bool flipDirection, bool includeOutputs, bool includeDerivers)
{ {
if (paths.find(path) != paths.end()) return; ThreadPool pool;
paths.insert(path);
PathSet edges; Sync<bool> state_;
if (flipDirection) { std::function<void(Path)> doPath;
queryReferrers(path, edges);
if (includeOutputs) { doPath = [&](const Path & path) {
PathSet derivers = queryValidDerivers(path); {
for (auto & i : derivers) auto state(state_.lock());
edges.insert(i); if (paths.count(path)) return;
paths.insert(path);
} }
if (includeDerivers && isDerivation(path)) {
PathSet outputs = queryDerivationOutputs(path);
for (auto & i : outputs)
if (isValidPath(i) && queryPathInfo(i)->deriver == path)
edges.insert(i);
}
} else {
auto info = queryPathInfo(path); auto info = queryPathInfo(path);
edges = info->references;
if (includeOutputs && isDerivation(path)) { if (flipDirection) {
PathSet outputs = queryDerivationOutputs(path);
for (auto & i : outputs) PathSet referrers;
if (isValidPath(i)) edges.insert(i); queryReferrers(path, referrers);
for (auto & ref : referrers)
if (ref != path)
pool.enqueue(std::bind(doPath, ref));
if (includeOutputs) {
PathSet derivers = queryValidDerivers(path);
for (auto & i : derivers)
pool.enqueue(std::bind(doPath, i));
}
if (includeDerivers && isDerivation(path)) {
PathSet outputs = queryDerivationOutputs(path);
for (auto & i : outputs)
if (isValidPath(i) && queryPathInfo(i)->deriver == path)
pool.enqueue(std::bind(doPath, i));
}
} else {
for (auto & ref : info->references)
if (ref != path)
pool.enqueue(std::bind(doPath, ref));
if (includeOutputs && isDerivation(path)) {
PathSet outputs = queryDerivationOutputs(path);
for (auto & i : outputs)
if (isValidPath(i)) pool.enqueue(std::bind(doPath, i));
}
if (includeDerivers && isValidPath(info->deriver))
pool.enqueue(std::bind(doPath, info->deriver));
} }
};
if (includeDerivers && isValidPath(info->deriver)) pool.enqueue(std::bind(doPath, path));
edges.insert(info->deriver);
}
for (auto & i : edges) pool.process();
computeFSClosure(i, paths, flipDirection, includeOutputs, includeDerivers);
} }