Clarify outputReferences variable with self-describing type

Thanks for the idea, @Regnat!
This commit is contained in:
John Ericson 2020-08-11 22:34:09 +00:00
parent 8a068bd025
commit 6d57139050

View file

@ -3800,7 +3800,9 @@ void DerivationGoal::registerOutputs()
that are most definitely already installed, we just store their final that are most definitely already installed, we just store their final
name so we can also use it in rewrites. */ name so we can also use it in rewrites. */
StringSet outputsToSort; StringSet outputsToSort;
std::map<std::string, std::variant<StorePath, StorePathSet>> outputReferences; struct AlreadyRegistered { StorePath path; };
struct PerhapsNeedToRegister { StorePathSet refs; };
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) {
auto actualPath = toRealPathChroot(worker.store.printStorePath(scratchOutputs.at(outputName))); auto actualPath = toRealPathChroot(worker.store.printStorePath(scratchOutputs.at(outputName)));
@ -3814,7 +3816,9 @@ void DerivationGoal::registerOutputs()
initialInfo.wanted = buildMode == bmCheck initialInfo.wanted = buildMode == bmCheck
|| !(initialInfo.known && initialInfo.known->isValid()); || !(initialInfo.known && initialInfo.known->isValid());
if (!initialInfo.wanted) { if (!initialInfo.wanted) {
outputReferences.insert_or_assign(outputName, initialInfo.known->path); outputReferencesIfUnregistered.insert_or_assign(
outputName,
AlreadyRegistered { .path = initialInfo.known->path });
continue; continue;
} }
@ -3851,28 +3855,29 @@ void DerivationGoal::registerOutputs()
auto references = worker.store.parseStorePathSet( auto references = worker.store.parseStorePathSet(
scanForReferences(blank, actualPath, worker.store.printStorePathSet(referenceablePaths))); scanForReferences(blank, actualPath, worker.store.printStorePathSet(referenceablePaths)));
outputReferences.insert_or_assign(outputName, references); outputReferencesIfUnregistered.insert_or_assign(
outputName,
PerhapsNeedToRegister { .refs = references });
outputStats.insert_or_assign(outputName, std::move(st)); outputStats.insert_or_assign(outputName, std::move(st));
} }
auto sortedOutputNames = topoSort(outputsToSort, auto sortedOutputNames = topoSort(outputsToSort,
{[&](const std::string & name) { {[&](const std::string & name) {
auto x = outputReferences.at(name);
return std::visit(overloaded { return std::visit(overloaded {
/* 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. */
[&](StorePath _) { return StringSet {}; }, [&](AlreadyRegistered _) { return StringSet {}; },
[&](StorePathSet refs) { [&](PerhapsNeedToRegister refs) {
StringSet referencedOutputs; StringSet referencedOutputs;
/* FIXME build inverted map up front so no quadratic waste here */ /* FIXME build inverted map up front so no quadratic waste here */
for (auto & r : refs) for (auto & r : refs.refs)
for (auto & [o, p] : scratchOutputs) for (auto & [o, p] : scratchOutputs)
if (r == p) if (r == p)
referencedOutputs.insert(o); referencedOutputs.insert(o);
return referencedOutputs; return referencedOutputs;
}, },
}, x); }, outputReferencesIfUnregistered.at(name));
}}, }},
{[&](const std::string & path, const std::string & parent) { {[&](const std::string & path, const std::string & parent) {
// TODO with more -vvvv also show the temporary paths for manual inspection. // TODO with more -vvvv also show the temporary paths for manual inspection.
@ -3900,14 +3905,14 @@ void DerivationGoal::registerOutputs()
bool rewritten = false; bool rewritten = false;
std::optional<StorePathSet> referencesOpt = std::visit(overloaded { std::optional<StorePathSet> referencesOpt = std::visit(overloaded {
[&](StorePath skippedFinalPath) -> std::optional<StorePathSet> { [&](AlreadyRegistered skippedFinalPath) -> std::optional<StorePathSet> {
finish(skippedFinalPath); finish(skippedFinalPath.path);
return std::nullopt; return std::nullopt;
}, },
[&](StorePathSet references) -> std::optional<StorePathSet> { [&](PerhapsNeedToRegister r) -> std::optional<StorePathSet> {
return references; return r.refs;
}, },
}, outputReferences.at(outputName)); }, outputReferencesIfUnregistered.at(outputName));
if (!referencesOpt) if (!referencesOpt)
continue; continue;