* Made `nix-store -qR --include-outputs' much faster if there are
multiple paths specified on the command line (from O(n * m) to O(n + m), where n is the number of arguments and m is the size of the closure).
This commit is contained in:
parent
50e34891f0
commit
fdcaf37361
3 changed files with 13 additions and 41 deletions
|
@ -19,7 +19,7 @@ Derivation derivationFromPath(const Path & drvPath)
|
||||||
|
|
||||||
|
|
||||||
void computeFSClosure(const Path & storePath,
|
void computeFSClosure(const Path & storePath,
|
||||||
PathSet & paths, bool flipDirection)
|
PathSet & paths, bool flipDirection, bool includeOutputs)
|
||||||
{
|
{
|
||||||
if (paths.find(storePath) != paths.end()) return;
|
if (paths.find(storePath) != paths.end()) return;
|
||||||
paths.insert(storePath);
|
paths.insert(storePath);
|
||||||
|
@ -30,8 +30,15 @@ void computeFSClosure(const Path & storePath,
|
||||||
else
|
else
|
||||||
store->queryReferences(storePath, references);
|
store->queryReferences(storePath, references);
|
||||||
|
|
||||||
|
if (includeOutputs && isDerivation(storePath)) {
|
||||||
|
Derivation drv = derivationFromPath(storePath);
|
||||||
|
foreach (DerivationOutputs::iterator, i, drv.outputs)
|
||||||
|
if (store->isValidPath(i->second.path))
|
||||||
|
computeFSClosure(i->second.path, paths, flipDirection, true);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (PathSet::iterator, i, references)
|
foreach (PathSet::iterator, i, references)
|
||||||
computeFSClosure(*i, paths, flipDirection);
|
computeFSClosure(*i, paths, flipDirection, includeOutputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,8 @@ Derivation derivationFromPath(const Path & drvPath);
|
||||||
`referrers' relation instead of the `references' relation is
|
`referrers' relation instead of the `references' relation is
|
||||||
returned. */
|
returned. */
|
||||||
void computeFSClosure(const Path & storePath,
|
void computeFSClosure(const Path & storePath,
|
||||||
PathSet & paths, bool flipDirection = false);
|
PathSet & paths, bool flipDirection = false,
|
||||||
|
bool includeOutputs = false);
|
||||||
|
|
||||||
/* Return the path corresponding to the output identifier `id' in the
|
/* Return the path corresponding to the output identifier `id' in the
|
||||||
given derivation. */
|
given derivation. */
|
||||||
|
|
|
@ -165,41 +165,6 @@ static void opPrintFixedPath(Strings opFlags, Strings opArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Place in `paths' the set of paths that are required to `realise'
|
|
||||||
the given store path, i.e., all paths necessary for valid
|
|
||||||
deployment of the path. For a derivation, this is the union of
|
|
||||||
requisites of the inputs, plus the derivation; for other store
|
|
||||||
paths, it is the set of paths in the FS closure of the path. If
|
|
||||||
`includeOutputs' is true, include the requisites of the output
|
|
||||||
paths of derivations as well.
|
|
||||||
|
|
||||||
Note that this function can be used to implement three different
|
|
||||||
deployment policies:
|
|
||||||
|
|
||||||
- Source deployment (when called on a derivation).
|
|
||||||
- Binary deployment (when called on an output path).
|
|
||||||
- Source/binary deployment (when called on a derivation with
|
|
||||||
`includeOutputs' set to true).
|
|
||||||
*/
|
|
||||||
static void storePathRequisites(const Path & storePath,
|
|
||||||
bool includeOutputs, PathSet & paths)
|
|
||||||
{
|
|
||||||
computeFSClosure(storePath, paths);
|
|
||||||
|
|
||||||
if (includeOutputs) {
|
|
||||||
for (PathSet::iterator i = paths.begin();
|
|
||||||
i != paths.end(); ++i)
|
|
||||||
if (isDerivation(*i)) {
|
|
||||||
Derivation drv = derivationFromPath(*i);
|
|
||||||
for (DerivationOutputs::iterator j = drv.outputs.begin();
|
|
||||||
j != drv.outputs.end(); ++j)
|
|
||||||
if (store->isValidPath(j->second.path))
|
|
||||||
computeFSClosure(j->second.path, paths);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static Path maybeUseOutput(const Path & storePath, bool useOutput, bool forceRealise)
|
static Path maybeUseOutput(const Path & storePath, bool useOutput, bool forceRealise)
|
||||||
{
|
{
|
||||||
if (forceRealise) realisePath(storePath);
|
if (forceRealise) realisePath(storePath);
|
||||||
|
@ -310,8 +275,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
PathSet paths;
|
PathSet paths;
|
||||||
foreach (Strings::iterator, i, opArgs) {
|
foreach (Strings::iterator, i, opArgs) {
|
||||||
Path path = maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise);
|
Path path = maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise);
|
||||||
if (query == qRequisites)
|
if (query == qRequisites) computeFSClosure(path, paths, false, includeOutputs);
|
||||||
storePathRequisites(path, includeOutputs, paths);
|
|
||||||
else if (query == qReferences) store->queryReferences(path, paths);
|
else if (query == qReferences) store->queryReferences(path, paths);
|
||||||
else if (query == qReferrers) store->queryReferrers(path, paths);
|
else if (query == qReferrers) store->queryReferrers(path, paths);
|
||||||
else if (query == qReferrersClosure) computeFSClosure(path, paths, true);
|
else if (query == qReferrersClosure) computeFSClosure(path, paths, true);
|
||||||
|
|
Loading…
Reference in a new issue