1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-12-05 00:21:01 +01:00

perf(libstore/derivation-builder): Futher simplify / maybe optimize

We can precompute the exact information we need for topo sorting and
store it in `PerhapsNeedToRegister`. Depending on how `topoSort` works,
this is easy a performance improvement or just completely harmless.

Co-Authored-By: Bernardo Meurer Costa <beme@anthropic.com>
This commit is contained in:
John Ericson 2025-11-25 17:01:23 -05:00
parent 686ad9b052
commit c33b2c5834

View file

@ -1396,6 +1396,11 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
struct PerhapsNeedToRegister struct PerhapsNeedToRegister
{ {
StorePathSet refs; StorePathSet refs;
/**
* References to other outputs. Built by looking up in
* `scratchOutputsInverse`.
*/
StringSet otherOutputs;
}; };
/* inverse map of scratchOutputs for efficient lookup */ /* inverse map of scratchOutputs for efficient lookup */
@ -1471,12 +1476,24 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
references = scanForReferences(blank, actualPath, referenceablePaths); references = scanForReferences(blank, actualPath, referenceablePaths);
} }
outputReferencesIfUnregistered.insert_or_assign(outputName, PerhapsNeedToRegister{.refs = references}); StringSet referencedOutputs;
for (auto & r : references)
if (auto * o = get(scratchOutputsInverse, r))
referencedOutputs.insert(*o);
outputReferencesIfUnregistered.insert_or_assign(
outputName,
PerhapsNeedToRegister{
.refs = references,
.otherOutputs = referencedOutputs,
});
outputStats.insert_or_assign(outputName, std::move(st)); outputStats.insert_or_assign(outputName, std::move(st));
} }
auto topoSortResult = topoSort(outputsToSort, [&](const std::string & name) { StringSet emptySet;
auto orifu = get(outputReferencesIfUnregistered, name);
auto topoSortResult = topoSort(outputsToSort, [&](const std::string & name) -> const StringSet & {
auto * orifu = get(outputReferencesIfUnregistered, name);
if (!orifu) if (!orifu)
throw BuildError( throw BuildError(
BuildResult::Failure::OutputRejected, BuildResult::Failure::OutputRejected,
@ -1488,14 +1505,8 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
/* Since we'll use the already installed versions of these, we /* Since we'll use the already installed versions of these, we
can treat them as leaves and ignore any references they can treat them as leaves and ignore any references they
have. */ have. */
[&](const AlreadyRegistered &) { return StringSet{}; }, [&](const AlreadyRegistered &) -> const StringSet & { return emptySet; },
[&](const PerhapsNeedToRegister & refs) { [&](const PerhapsNeedToRegister & refs) -> const StringSet & { return refs.otherOutputs; },
StringSet referencedOutputs;
for (auto & r : refs.refs)
if (auto * o = get(scratchOutputsInverse, r))
referencedOutputs.insert(*o);
return referencedOutputs;
},
}, },
*orifu); *orifu);
}); });