Aso track the output path of the realisation dependencies
This commit is contained in:
parent
cb46d70794
commit
1f3ff0d193
|
@ -927,7 +927,7 @@ void DerivationGoal::resolvedFinished() {
|
||||||
auto newRealisation = *realisation;
|
auto newRealisation = *realisation;
|
||||||
newRealisation.id = DrvOutput{initialOutputs.at(wantedOutput).outputHash, wantedOutput};
|
newRealisation.id = DrvOutput{initialOutputs.at(wantedOutput).outputHash, wantedOutput};
|
||||||
newRealisation.signatures.clear();
|
newRealisation.signatures.clear();
|
||||||
newRealisation.drvOutputDeps = drvOutputReferences(worker.store, *drv, realisation->outPath);
|
newRealisation.dependentRealisations = drvOutputReferences(worker.store, *drv, realisation->outPath);
|
||||||
signRealisation(newRealisation);
|
signRealisation(newRealisation);
|
||||||
worker.store.registerDrvOutput(newRealisation);
|
worker.store.registerDrvOutput(newRealisation);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -711,19 +711,19 @@ void LocalStore::registerDrvOutput(const Realisation & info, CheckSigsFlag check
|
||||||
void LocalStore::registerDrvOutput(const Realisation & info)
|
void LocalStore::registerDrvOutput(const Realisation & info)
|
||||||
{
|
{
|
||||||
settings.requireExperimentalFeature("ca-derivations");
|
settings.requireExperimentalFeature("ca-derivations");
|
||||||
auto state(_state.lock());
|
|
||||||
retrySQLite<void>([&]() {
|
retrySQLite<void>([&]() {
|
||||||
|
auto state(_state.lock());
|
||||||
state->stmts->RegisterRealisedOutput
|
state->stmts->RegisterRealisedOutput
|
||||||
.use()(info.id.strHash())(info.id.outputName)(printStorePath(
|
.use()(info.id.strHash())(info.id.outputName)(printStorePath(
|
||||||
info.outPath))(concatStringsSep(" ", info.signatures))
|
info.outPath))(concatStringsSep(" ", info.signatures))
|
||||||
.exec();
|
.exec();
|
||||||
|
uint64_t myId = state->db.getLastInsertedRowId();
|
||||||
|
for (auto & [outputId, _] : info.dependentRealisations) {
|
||||||
|
state->stmts->AddRealisationRealisationReference
|
||||||
|
.use()(myId)(outputId.strHash())(outputId.outputName)
|
||||||
|
.exec();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
uint64_t myId = state->db.getLastInsertedRowId();
|
|
||||||
for (auto& outputId : info.drvOutputDeps) {
|
|
||||||
state->stmts->AddRealisationRealisationReference
|
|
||||||
.use()(myId)(outputId.strHash())(outputId.outputName)
|
|
||||||
.exec();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalStore::cacheDrvOutputMapping(State & state, const uint64_t deriver, const string & outputName, const StorePath & output)
|
void LocalStore::cacheDrvOutputMapping(State & state, const uint64_t deriver, const string & outputName, const StorePath & output)
|
||||||
|
@ -1730,22 +1730,26 @@ std::optional<const Realisation> LocalStore::queryRealisation(
|
||||||
auto signatures =
|
auto signatures =
|
||||||
tokenizeString<StringSet>(useQueryRealisedOutput.getStr(2));
|
tokenizeString<StringSet>(useQueryRealisedOutput.getStr(2));
|
||||||
|
|
||||||
std::set<DrvOutput> drvOutputDeps;
|
std::map<DrvOutput, StorePath> dependentRealisations;
|
||||||
auto useRealisationRefs(
|
auto useRealisationRefs(
|
||||||
state->stmts->QueryRealisationRealisationReferences.use()(
|
state->stmts->QueryRealisationRealisationReferences.use()(
|
||||||
realisationDbId));
|
realisationDbId));
|
||||||
while (useRealisationRefs.next())
|
while (useRealisationRefs.next()) {
|
||||||
drvOutputDeps.insert(DrvOutput{
|
auto depHash = useRealisationRefs.getStr(0);
|
||||||
Hash::parseAnyPrefixed(useRealisationRefs.getStr(0)),
|
auto depOutputName = useRealisationRefs.getStr(1);
|
||||||
useRealisationRefs.getStr(1),
|
auto useQueryRealisedOutput(
|
||||||
}
|
state->stmts->QueryRealisedOutput.use()(depHash)(depOutputName));
|
||||||
);
|
assert(useQueryRealisedOutput.next());
|
||||||
|
auto outputPath = parseStorePath(useQueryRealisedOutput.getStr(1));
|
||||||
|
auto depId = DrvOutput { Hash::parseAnyPrefixed(depHash), depOutputName };
|
||||||
|
dependentRealisations.insert({depId, outputPath});
|
||||||
|
}
|
||||||
|
|
||||||
return Ret{Realisation{
|
return Ret{Realisation{
|
||||||
.id = id,
|
.id = id,
|
||||||
.outPath = outputPath,
|
.outPath = outputPath,
|
||||||
.signatures = signatures,
|
.signatures = signatures,
|
||||||
.drvOutputDeps = drvOutputDeps,
|
.dependentRealisations = dependentRealisations,
|
||||||
}};
|
}};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -254,25 +254,22 @@ StorePaths Store::topoSortPaths(const StorePathSet & paths)
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<DrvOutput> drvOutputReferences(
|
std::map<DrvOutput, StorePath> drvOutputReferences(
|
||||||
const std::set<Realisation> inputRealisations,
|
const std::set<Realisation> inputRealisations,
|
||||||
const StorePathSet pathReferences)
|
const StorePathSet pathReferences)
|
||||||
{
|
{
|
||||||
std::set<DrvOutput> res;
|
std::map<DrvOutput, StorePath> res;
|
||||||
|
|
||||||
std::map<StorePath, std::set<DrvOutput>> inputsByOutputPath;
|
for (const auto & input : inputRealisations) {
|
||||||
for (const auto & input : inputRealisations)
|
if (pathReferences.count(input.outPath)) {
|
||||||
inputsByOutputPath[input.outPath].insert(input.id);
|
res.insert({input.id, input.outPath});
|
||||||
|
}
|
||||||
for (const auto & path : pathReferences) {
|
|
||||||
auto theseInputs = inputsByOutputPath[path];
|
|
||||||
res.insert(theseInputs.begin(), theseInputs.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<DrvOutput> drvOutputReferences(
|
std::map<DrvOutput, StorePath> drvOutputReferences(
|
||||||
Store & store,
|
Store & store,
|
||||||
const Derivation & drv,
|
const Derivation & drv,
|
||||||
const StorePath & outputPath)
|
const StorePath & outputPath)
|
||||||
|
|
|
@ -33,7 +33,7 @@ void Realisation::closure(Store & store, std::set<Realisation> startOutputs, std
|
||||||
{
|
{
|
||||||
auto getDeps = [&](const Realisation& current) -> std::set<Realisation> {
|
auto getDeps = [&](const Realisation& current) -> std::set<Realisation> {
|
||||||
std::set<Realisation> res;
|
std::set<Realisation> res;
|
||||||
for (auto& currentDep : current.drvOutputDeps) {
|
for (auto& [currentDep, _] : current.dependentRealisations) {
|
||||||
if (auto currentRealisation = store.queryRealisation(currentDep))
|
if (auto currentRealisation = store.queryRealisation(currentDep))
|
||||||
res.insert(*currentRealisation);
|
res.insert(*currentRealisation);
|
||||||
else
|
else
|
||||||
|
@ -60,14 +60,14 @@ void Realisation::closure(Store & store, std::set<Realisation> startOutputs, std
|
||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json Realisation::toJSON() const {
|
nlohmann::json Realisation::toJSON() const {
|
||||||
nlohmann::json jsonDrvOutputDeps;
|
auto jsonDependentRealisations = nlohmann::json::object();
|
||||||
for (auto & dep : drvOutputDeps)
|
for (auto & [depId, depOutPath] : dependentRealisations)
|
||||||
jsonDrvOutputDeps.push_back(dep.to_string());
|
jsonDependentRealisations.emplace(depId.to_string(), depOutPath.to_string());
|
||||||
return nlohmann::json{
|
return nlohmann::json{
|
||||||
{"id", id.to_string()},
|
{"id", id.to_string()},
|
||||||
{"outPath", outPath.to_string()},
|
{"outPath", outPath.to_string()},
|
||||||
{"signatures", signatures},
|
{"signatures", signatures},
|
||||||
{"drvOutputDeps", jsonDrvOutputDeps},
|
{"dependentRealisations", jsonDependentRealisations},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,16 +93,16 @@ Realisation Realisation::fromJSON(
|
||||||
if (auto signaturesIterator = json.find("signatures"); signaturesIterator != json.end())
|
if (auto signaturesIterator = json.find("signatures"); signaturesIterator != json.end())
|
||||||
signatures.insert(signaturesIterator->begin(), signaturesIterator->end());
|
signatures.insert(signaturesIterator->begin(), signaturesIterator->end());
|
||||||
|
|
||||||
std::set <DrvOutput> drvOutputDeps;
|
std::map <DrvOutput, StorePath> dependentRealisations;
|
||||||
if (auto jsonDependencies = json.find("drvOutputDeps"); jsonDependencies != json.end())
|
if (auto jsonDependencies = json.find("dependentRealisations"); jsonDependencies != json.end())
|
||||||
for (auto & jsonDep : *jsonDependencies)
|
for (auto & [jsonDepId, jsonDepOutPath] : jsonDependencies->get<std::map<std::string, std::string>>())
|
||||||
drvOutputDeps.insert(DrvOutput::parse(jsonDep.get<std::string>()));
|
dependentRealisations.insert({DrvOutput::parse(jsonDepId), StorePath(jsonDepOutPath)});
|
||||||
|
|
||||||
return Realisation{
|
return Realisation{
|
||||||
.id = DrvOutput::parse(getField("id")),
|
.id = DrvOutput::parse(getField("id")),
|
||||||
.outPath = StorePath(getField("outPath")),
|
.outPath = StorePath(getField("outPath")),
|
||||||
.signatures = signatures,
|
.signatures = signatures,
|
||||||
.drvOutputDeps = drvOutputDeps,
|
.dependentRealisations = dependentRealisations,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,13 @@ struct Realisation {
|
||||||
|
|
||||||
StringSet signatures;
|
StringSet signatures;
|
||||||
|
|
||||||
std::set<DrvOutput> drvOutputDeps;
|
/**
|
||||||
|
* The realisations that are required for the current one to be valid.
|
||||||
|
*
|
||||||
|
* When importing this realisation, the store will first check that all its
|
||||||
|
* dependencies exist, and map to the correct output path
|
||||||
|
*/
|
||||||
|
std::map<DrvOutput, StorePath> dependentRealisations;
|
||||||
|
|
||||||
nlohmann::json toJSON() const;
|
nlohmann::json toJSON() const;
|
||||||
static Realisation fromJSON(const nlohmann::json& json, const std::string& whence);
|
static Realisation fromJSON(const nlohmann::json& json, const std::string& whence);
|
||||||
|
|
|
@ -798,7 +798,7 @@ std::map<StorePath, StorePath> copyPaths(ref<Store> srcStore, ref<Store> dstStor
|
||||||
pool, Realisation::closure(*srcStore, toplevelRealisations),
|
pool, Realisation::closure(*srcStore, toplevelRealisations),
|
||||||
[&](const Realisation& current) -> std::set<Realisation> {
|
[&](const Realisation& current) -> std::set<Realisation> {
|
||||||
std::set<Realisation> children;
|
std::set<Realisation> children;
|
||||||
for (const auto& drvOutput : current.drvOutputDeps) {
|
for (const auto& [drvOutput, _] : current.dependentRealisations) {
|
||||||
auto currentChild = srcStore->queryRealisation(drvOutput);
|
auto currentChild = srcStore->queryRealisation(drvOutput);
|
||||||
if (!currentChild)
|
if (!currentChild)
|
||||||
throw Error(
|
throw Error(
|
||||||
|
|
|
@ -864,7 +864,7 @@ std::pair<std::string, Store::Params> splitUriAndParams(const std::string & uri)
|
||||||
|
|
||||||
std::optional<ContentAddress> getDerivationCA(const BasicDerivation & drv);
|
std::optional<ContentAddress> getDerivationCA(const BasicDerivation & drv);
|
||||||
|
|
||||||
std::set<DrvOutput> drvOutputReferences(
|
std::map<DrvOutput, StorePath> drvOutputReferences(
|
||||||
Store & store,
|
Store & store,
|
||||||
const Derivation & drv,
|
const Derivation & drv,
|
||||||
const StorePath & outputPath);
|
const StorePath & outputPath);
|
||||||
|
|
Loading…
Reference in a new issue