Store the output hashes in the initialOutputs of the drv goal

That way we
1. Don't have to recompute them several times
2. Can compute them in a place where we know the type of the parent
  derivation, meaning that we don't need the casting dance we had before
This commit is contained in:
regnat 2021-02-04 14:41:49 +01:00 committed by Théophane Hufschmitt
parent 0bfbd04369
commit 4bc28c44f2
2 changed files with 30 additions and 20 deletions

View file

@ -124,6 +124,17 @@ DerivationGoal::DerivationGoal(const StorePath & drvPath, const BasicDerivation
, buildMode(buildMode) , buildMode(buildMode)
{ {
this->drv = std::make_unique<BasicDerivation>(BasicDerivation(drv)); this->drv = std::make_unique<BasicDerivation>(BasicDerivation(drv));
auto outputHashes = staticOutputHashes(worker.store, drv);
for (auto &[outputName, outputHash] : outputHashes)
initialOutputs.insert({
outputName,
InitialOutput{
.wanted = true, // Will be refined later
.outputHash = outputHash
}
});
state = &DerivationGoal::haveDerivation; state = &DerivationGoal::haveDerivation;
name = fmt( name = fmt(
"building of '%s' from in-memory derivation", "building of '%s' from in-memory derivation",
@ -258,8 +269,20 @@ void DerivationGoal::loadDerivation()
assert(worker.store.isValidPath(drvPath)); assert(worker.store.isValidPath(drvPath));
auto fullDrv = new Derivation(worker.store.derivationFromPath(drvPath));
auto outputHashes = staticOutputHashes(worker.store, *fullDrv);
for (auto &[outputName, outputHash] : outputHashes)
initialOutputs.insert({
outputName,
InitialOutput{
.wanted = true, // Will be refined later
.outputHash = outputHash
}
});
/* Get the derivation. */ /* Get the derivation. */
drv = std::unique_ptr<BasicDerivation>(new Derivation(worker.store.derivationFromPath(drvPath))); drv = std::unique_ptr<BasicDerivation>(fullDrv);
haveDerivation(); haveDerivation();
} }
@ -1022,14 +1045,6 @@ void DerivationGoal::buildDone()
void DerivationGoal::resolvedFinished() { void DerivationGoal::resolvedFinished() {
assert(resolvedDrv); assert(resolvedDrv);
// If the derivation was originally a full `Derivation` (and not just
// a `BasicDerivation`, we must retrieve it because the `staticOutputHashes`
// will be wrong otherwise
Derivation fullDrv = *drv;
if (auto upcasted = dynamic_cast<Derivation *>(drv.get()))
fullDrv = *upcasted;
auto originalHashes = staticOutputHashes(worker.store, fullDrv);
auto resolvedHashes = staticOutputHashes(worker.store, *resolvedDrv); auto resolvedHashes = staticOutputHashes(worker.store, *resolvedDrv);
// `wantedOutputs` might be empty, which means “all the outputs” // `wantedOutputs` might be empty, which means “all the outputs”
@ -1038,7 +1053,7 @@ void DerivationGoal::resolvedFinished() {
realWantedOutputs = resolvedDrv->outputNames(); realWantedOutputs = resolvedDrv->outputNames();
for (auto & wantedOutput : realWantedOutputs) { for (auto & wantedOutput : realWantedOutputs) {
assert(originalHashes.count(wantedOutput) != 0); assert(initialOutputs.count(wantedOutput) != 0);
assert(resolvedHashes.count(wantedOutput) != 0); assert(resolvedHashes.count(wantedOutput) != 0);
auto realisation = worker.store.queryRealisation( auto realisation = worker.store.queryRealisation(
DrvOutput{resolvedHashes.at(wantedOutput), wantedOutput} DrvOutput{resolvedHashes.at(wantedOutput), wantedOutput}
@ -1047,7 +1062,7 @@ void DerivationGoal::resolvedFinished() {
// realisation won't be there // realisation won't be there
if (realisation) { if (realisation) {
auto newRealisation = *realisation; auto newRealisation = *realisation;
newRealisation.id = DrvOutput{originalHashes.at(wantedOutput), wantedOutput}; newRealisation.id = DrvOutput{initialOutputs.at(wantedOutput).outputHash, wantedOutput};
worker.store.registerDrvOutput(newRealisation); worker.store.registerDrvOutput(newRealisation);
} else { } else {
// If we don't have a realisation, then it must mean that something // If we don't have a realisation, then it must mean that something
@ -3829,9 +3844,8 @@ void DerivationGoal::checkPathValidity()
{ {
bool checkHash = buildMode == bmRepair; bool checkHash = buildMode == bmRepair;
for (auto & i : queryPartialDerivationOutputMap()) { for (auto & i : queryPartialDerivationOutputMap()) {
InitialOutput info { InitialOutput & info = initialOutputs.at(i.first);
.wanted = wantOutput(i.first, wantedOutputs), info.wanted = wantOutput(i.first, wantedOutputs);
};
if (i.second) { if (i.second) {
auto outputPath = *i.second; auto outputPath = *i.second;
info.known = { info.known = {
@ -3844,19 +3858,14 @@ void DerivationGoal::checkPathValidity()
}; };
} }
if (settings.isExperimentalFeatureEnabled("ca-derivations")) { if (settings.isExperimentalFeatureEnabled("ca-derivations")) {
Derivation fullDrv = *drv;
if (auto upcasted = dynamic_cast<Derivation *>(drv.get()))
fullDrv = *upcasted;
auto outputHashes = staticOutputHashes(worker.store, fullDrv);
if (auto real = worker.store.queryRealisation( if (auto real = worker.store.queryRealisation(
DrvOutput{outputHashes.at(i.first), i.first})) { DrvOutput{initialOutputs.at(i.first).outputHash, i.first})) {
info.known = { info.known = {
.path = real->outPath, .path = real->outPath,
.status = PathStatus::Valid, .status = PathStatus::Valid,
}; };
} }
} }
initialOutputs.insert_or_assign(i.first, info);
} }
} }

View file

@ -37,6 +37,7 @@ struct InitialOutputStatus {
struct InitialOutput { struct InitialOutput {
bool wanted; bool wanted;
Hash outputHash;
std::optional<InitialOutputStatus> known; std::optional<InitialOutputStatus> known;
}; };