From a728780fbd494ad8bc9299a90bc6cf15287b9e46 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 21 Jul 2016 14:13:35 +0200 Subject: [PATCH] Store::computeFSClosure(): Use thread pool This speeds up queries against the binary cache. --- src/libstore/misc.cc | 75 ++++++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc index 4bb043aaf..2e0774f7e 100644 --- a/src/libstore/misc.cc +++ b/src/libstore/misc.cc @@ -2,6 +2,7 @@ #include "globals.hh" #include "local-store.hh" #include "store-api.hh" +#include "thread-pool.hh" namespace nix { @@ -10,43 +11,63 @@ namespace nix { void Store::computeFSClosure(const Path & path, PathSet & paths, bool flipDirection, bool includeOutputs, bool includeDerivers) { - if (paths.find(path) != paths.end()) return; - paths.insert(path); + ThreadPool pool; - PathSet edges; + Sync state_; - if (flipDirection) { - queryReferrers(path, edges); + std::function doPath; - if (includeOutputs) { - PathSet derivers = queryValidDerivers(path); - for (auto & i : derivers) - edges.insert(i); + doPath = [&](const Path & path) { + { + auto state(state_.lock()); + 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); - edges = info->references; - if (includeOutputs && isDerivation(path)) { - PathSet outputs = queryDerivationOutputs(path); - for (auto & i : outputs) - if (isValidPath(i)) edges.insert(i); + if (flipDirection) { + + PathSet referrers; + 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)) - edges.insert(info->deriver); - } + pool.enqueue(std::bind(doPath, path)); - for (auto & i : edges) - computeFSClosure(i, paths, flipDirection, includeOutputs, includeDerivers); + pool.process(); }