mirror of
https://github.com/NixOS/nix.git
synced 2025-12-04 16:10:59 +01:00
perf(libstore/derivation-builder): pre-compute outputGraph for linear complexity
Build the inverse of `scratchOuputs` before running topoSort, avoiding quadratic complexity when determining which outputs reference each other. This fixes the FIXME comment about building the inverted map up front. Inspired by Lix commit 10c04ce84 / Change Id Ibdd46e7b2e895bfeeebc173046d1297b41998181, but ended up being completely different code. Co-Authored-By: Maximilian Bosch <maximilian@mbosch.me> Co-Authored-By: Bernardo Meurer Costa <beme@anthropic.com>
This commit is contained in:
parent
13b4512cbe
commit
686ad9b052
1 changed files with 7 additions and 4 deletions
|
|
@ -1398,6 +1398,11 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
|
||||||
StorePathSet refs;
|
StorePathSet refs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* inverse map of scratchOutputs for efficient lookup */
|
||||||
|
std::map<StorePath, std::string> scratchOutputsInverse;
|
||||||
|
for (auto & [outputName, path] : scratchOutputs)
|
||||||
|
scratchOutputsInverse.insert_or_assign(path, outputName);
|
||||||
|
|
||||||
std::map<std::string, std::variant<AlreadyRegistered, PerhapsNeedToRegister>> outputReferencesIfUnregistered;
|
std::map<std::string, std::variant<AlreadyRegistered, PerhapsNeedToRegister>> outputReferencesIfUnregistered;
|
||||||
std::map<std::string, struct stat> outputStats;
|
std::map<std::string, struct stat> outputStats;
|
||||||
for (auto & [outputName, _] : drv.outputs) {
|
for (auto & [outputName, _] : drv.outputs) {
|
||||||
|
|
@ -1486,11 +1491,9 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
|
||||||
[&](const AlreadyRegistered &) { return StringSet{}; },
|
[&](const AlreadyRegistered &) { return StringSet{}; },
|
||||||
[&](const PerhapsNeedToRegister & refs) {
|
[&](const PerhapsNeedToRegister & refs) {
|
||||||
StringSet referencedOutputs;
|
StringSet referencedOutputs;
|
||||||
/* FIXME build inverted map up front so no quadratic waste here */
|
|
||||||
for (auto & r : refs.refs)
|
for (auto & r : refs.refs)
|
||||||
for (auto & [o, p] : scratchOutputs)
|
if (auto * o = get(scratchOutputsInverse, r))
|
||||||
if (r == p)
|
referencedOutputs.insert(*o);
|
||||||
referencedOutputs.insert(o);
|
|
||||||
return referencedOutputs;
|
return referencedOutputs;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue