From 84c1df46ea0b4cfa97a57a3a3dfa049c766843d7 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Sun, 11 May 2025 22:50:32 +0200 Subject: [PATCH] libstore: remove DerivedPathMap single-level maps suffice now that dynamic derivations are gone. Change-Id: If29998b104b31255292ab0c789622d7d27040f69 --- lix/legacy/build-remote.cc | 2 +- lix/legacy/nix-build.cc | 20 ++-- lix/libexpr/primops.cc | 4 +- lix/libstore/build/derivation-goal.cc | 28 +++--- lix/libstore/derivations.cc | 80 +++++----------- lix/libstore/derivations.hh | 7 +- lix/libstore/derived-path-map.cc | 69 ------------- lix/libstore/derived-path-map.hh | 96 ------------------- lix/libstore/meson.build | 2 - lix/libstore/misc.cc | 35 ++----- perl/lib/Nix/Store.xs | 2 +- subprojects/nix-eval-jobs/src/constituents.cc | 3 +- subprojects/nix-eval-jobs/src/drv.cc | 5 +- tests/unit/libstore/derivation.cc | 12 +-- 14 files changed, 67 insertions(+), 298 deletions(-) delete mode 100644 lix/libstore/derived-path-map.cc delete mode 100644 lix/libstore/derived-path-map.hh diff --git a/lix/legacy/build-remote.cc b/lix/legacy/build-remote.cc index 6b62660ae..d58bd249a 100644 --- a/lix/legacy/build-remote.cc +++ b/lix/legacy/build-remote.cc @@ -324,7 +324,7 @@ connected: // // 2. Changing the `inputSrcs` set changes the associated // output ids, which break CA derivations - if (!drv.inputDrvs.map.empty()) + if (!drv.inputDrvs.empty()) drv.inputSrcs = store->parseStorePathSet(inputs); optResult = aio.blockOn(sshStore->buildDerivation(*drvPath, (const BasicDerivation &) drv)); auto & result = *optResult; diff --git a/lix/legacy/nix-build.cc b/lix/legacy/nix-build.cc index 0f5fdde6a..2a9813513 100644 --- a/lix/legacy/nix-build.cc +++ b/lix/legacy/nix-build.cc @@ -368,18 +368,16 @@ static void main_nix_build(AsyncIoRoot & aio, std::string programName, Strings a } } - auto accumDerivedPath = [&](ref inputDrv, const DerivedPathMap::ChildNode & inputNode) { - if (!inputNode.value.empty()) + auto accumDerivedPath = [&](ref inputDrv, const StringSet & inputNode) { + if (!inputNode.empty()) pathsToBuild.push_back(DerivedPath::Built { .drvPath = inputDrv, - .outputs = OutputsSpec::Names { inputNode.value }, + .outputs = OutputsSpec::Names { inputNode }, }); - // only dynamic derivations have a non-empty childMap - assert(inputNode.childMap.empty()); }; // Build or fetch all dependencies of the derivation. - for (const auto & [inputDrv0, inputNode] : drv.inputDrvs.map) { + for (const auto & [inputDrv0, inputNode] : drv.inputDrvs) { // To get around lambda capturing restrictions in the // standard. const auto & inputDrv = inputDrv0; @@ -451,20 +449,16 @@ static void main_nix_build(AsyncIoRoot & aio, std::string programName, Strings a if (env.count("__json")) { StorePathSet inputs; - std::function::ChildNode &)> accumInputClosure; - - accumInputClosure = [&](const StorePath & inputDrv, const DerivedPathMap::ChildNode & inputNode) { + auto accumInputClosure = [&](const StorePath & inputDrv, const StringSet & inputNode) { auto outputs = aio.blockOn(store->queryPartialDerivationOutputMap(inputDrv, &*evalStore)); - for (auto & i : inputNode.value) { + for (auto & i : inputNode) { auto o = outputs.at(i); aio.blockOn(store->computeFSClosure(*o, inputs)); } - for (const auto & [outputName, childNode] : inputNode.childMap) - accumInputClosure(*outputs.at(outputName), childNode); }; - for (const auto & [inputDrv, inputNode] : drv.inputDrvs.map) + for (const auto & [inputDrv, inputNode] : drv.inputDrvs) accumInputClosure(inputDrv, inputNode); ParsedDerivation parsedDrv(drvInfo.requireDrvPath(*state), drv); diff --git a/lix/libexpr/primops.cc b/lix/libexpr/primops.cc index 60fc339a3..66651640d 100644 --- a/lix/libexpr/primops.cc +++ b/lix/libexpr/primops.cc @@ -971,13 +971,13 @@ drvName, Bindings * attrs, Value & v) for (auto & j : refs) { drv.inputSrcs.insert(j); if (j.isDerivation()) { - drv.inputDrvs.map[j].value = + drv.inputDrvs[j] = state.aio.blockOn(state.ctx.store->readDerivation(j)).outputNames(); } } }, [&](const NixStringContextElem::Built & b) { - drv.inputDrvs.ensureSlot(*b.drvPath).value.insert(b.output); + drv.inputDrvs[b.drvPath->path].insert(b.output); }, [&](const NixStringContextElem::Opaque & o) { drv.inputSrcs.insert(o.path); diff --git a/lix/libstore/build/derivation-goal.cc b/lix/libstore/build/derivation-goal.cc index 3f54556fa..186b6e99d 100644 --- a/lix/libstore/build/derivation-goal.cc +++ b/lix/libstore/build/derivation-goal.cc @@ -373,19 +373,17 @@ try { /* The inputs must be built before we can build this goal. */ inputDrvOutputs.clear(); if (useDerivation) { - auto addWaiteeDerivedPath = [&](ref inputDrv, const DerivedPathMap::ChildNode & inputNode) { - if (!inputNode.value.empty()) + auto addWaiteeDerivedPath = [&](ref inputDrv, const StringSet & inputNode) { + if (!inputNode.empty()) dependencies.add(worker.goalFactory().makeGoal( DerivedPath::Built { .drvPath = inputDrv, - .outputs = inputNode.value, + .outputs = inputNode, }, buildMode == bmRepair ? bmRepair : bmNormal)); - // only dynamic derivations have a non-empty childMap - assert(inputNode.childMap.empty()); }; - for (const auto & [inputDrvPath, inputNode] : dynamic_cast(drv.get())->inputDrvs.map) { + for (const auto & [inputDrvPath, inputNode] : dynamic_cast(drv.get())->inputDrvs) { addWaiteeDerivedPath(makeConstantStorePathRef(inputDrvPath), inputNode); } } @@ -539,7 +537,7 @@ try { return ia.deferred; }, [&](const DerivationType::ContentAddressed & ca) { - return !fullDrv.inputDrvs.map.empty() && ( + return !fullDrv.inputDrvs.empty() && ( ca.fixed /* Can optionally resolve if fixed, which is good for avoiding unnecessary rebuilds. */ @@ -550,7 +548,7 @@ try { }, }, drvType.raw); - if (resolveDrv && !fullDrv.inputDrvs.map.empty()) { + if (resolveDrv && !fullDrv.inputDrvs.empty()) { experimentalFeatureSettings.require(Xp::CaDerivations); /* We are be able to resolve this derivation based on the @@ -587,10 +585,8 @@ try { co_return co_await resolvedFinished(); } - std::function>(const StorePath &, const DerivedPathMap::ChildNode &)> accumInputPaths; - // NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines) - accumInputPaths = [&](const StorePath & depDrvPath, const DerivedPathMap::ChildNode & inputNode) -> kj::Promise> { + auto accumInputPaths = [&](const StorePath & depDrvPath, const StringSet & inputNode) -> kj::Promise> { try { /* Add the relevant output closures of the input derivation `i' as input paths. Only add the closures of output paths @@ -633,21 +629,19 @@ try { } }; - for (auto & outputName : inputNode.value) { + for (auto & outputName : inputNode) { TRY_AWAIT( worker.store.computeFSClosure(TRY_AWAIT(getOutput(outputName)), inputPaths) ); } - for (auto & [outputName, childNode] : inputNode.childMap) - TRY_AWAIT(accumInputPaths(TRY_AWAIT(getOutput(outputName)), childNode)); co_return result::success(); } catch (...) { co_return result::current_exception(); } }; - for (auto & [depDrvPath, depNode] : fullDrv.inputDrvs.map) + for (auto & [depDrvPath, depNode] : fullDrv.inputDrvs) TRY_AWAIT(accumInputPaths(depDrvPath, depNode)); } @@ -1762,9 +1756,9 @@ void DerivationGoal::waiteeDone(GoalPtr waitee) auto & fullDrv = *dynamic_cast(drv.get()); - auto * nodeP = fullDrv.inputDrvs.findSlot(DerivedPath::Opaque { .path = dg->drvPath }); + auto * nodeP = get(fullDrv.inputDrvs, dg->drvPath); if (!nodeP) return; - auto & outputs = nodeP->value; + auto & outputs = *nodeP; for (auto & outputName : outputs) { auto buildResult = dg->buildResult.restrictTo(DerivedPath::Built { diff --git a/lix/libstore/derivations.cc b/lix/libstore/derivations.cc index 86a9de9b3..9f02eba30 100644 --- a/lix/libstore/derivations.cc +++ b/lix/libstore/derivations.cc @@ -107,7 +107,7 @@ kj::Promise> writeDerivation(Store & store, const Derivation & drv, RepairFlag repair, bool readOnly) try { auto references = drv.inputSrcs; - for (auto & i : drv.inputDrvs.map) + for (auto & i : drv.inputDrvs) references.insert(i.first); /* Note that the outputs of a derivation are *not* references (that can be missing (of course) and should not necessarily be @@ -287,13 +287,11 @@ static DerivationOutput parseDerivationOutput( return parseDerivationOutput(store, *pathS, *hashAlgo, *hash, xpSettings); } -static DerivedPathMap::ChildNode parseDerivedPathMapNode( +static StringSet parseDerivedPathMapNode( const Store & store, StringViewStream & str) { - DerivedPathMap::ChildNode node; - node.value = parseStrings(str, false); - return node; + return parseStrings(str, false); } @@ -333,7 +331,7 @@ Derivation parseDerivation( expect(str, "("); auto drvPath = parsePath(str); expect(str, ","); - drv.inputDrvs.map.insert_or_assign(store.parseStorePath(*drvPath), parseDerivedPathMapNode(store, str)); + drv.inputDrvs.insert_or_assign(store.parseStorePath(*drvPath), parseDerivedPathMapNode(store, str)); expect(str, ")"); } @@ -421,29 +419,15 @@ static void printUnquotedStrings(std::string & res, ForwardIterator i, ForwardIt } -static void unparseDerivedPathMapNode(const Store & store, std::string & s, const DerivedPathMap::ChildNode & node) +static void unparseDerivedPathMapNode(const Store & store, std::string & s, const StringSet & node) { s += ','; - if (node.childMap.empty()) { - printUnquotedStrings(s, node.value.begin(), node.value.end()); - } else { - s += "("; - printUnquotedStrings(s, node.value.begin(), node.value.end()); - s += ",["; - bool first = true; - for (auto & [outputName, childNode] : node.childMap) { - if (first) first = false; else s += ','; - s += '('; printUnquotedString(s, outputName); - unparseDerivedPathMapNode(store, s, childNode); - s += ')'; - } - s += "])"; - } + printUnquotedStrings(s, node.begin(), node.end()); } std::string Derivation::unparse(const Store & store, bool maskOutputs, - DerivedPathMap::ChildNode::Map * actualInputs) const + std::map * actualInputs) const { std::string s; s.reserve(65536); @@ -490,7 +474,7 @@ std::string Derivation::unparse(const Store & store, bool maskOutputs, s += ')'; } } else { - for (auto & [drvPath, childMap] : inputDrvs.map) { + for (auto & [drvPath, childMap] : inputDrvs) { if (first) first = false; else s += ','; s += '('; printUnquotedString(s, store.printStorePath(drvPath)); unparseDerivedPathMapNode(store, s, childMap); @@ -701,16 +685,16 @@ try { }, }, drv.type().raw); - DerivedPathMap::ChildNode::Map inputs2; - for (auto & [drvPath, node] : drv.inputDrvs.map) { + std::map inputs2; + for (auto & [drvPath, node] : drv.inputDrvs) { const auto & res = TRY_AWAIT(pathDerivationModulo(store, drvPath)); if (res.kind == DrvHash::Kind::Deferred) kind = DrvHash::Kind::Deferred; - for (auto & outputName : node.value) { + for (auto & outputName : node) { const auto h = get(res.hashes, outputName); if (!h) throw Error("no hash for output '%s' of derivation '%s'", outputName, drv.name); - inputs2[h->to_string(Base::Base16, false)].value.insert(outputName); + inputs2[h->to_string(Base::Base16, false)].insert(outputName); } } @@ -900,19 +884,14 @@ Derivation::tryResolve(Store & store, Store * evalStore) const try { std::map, StorePath> inputDrvOutputs; - std::function< - kj::Promise>(const StorePath &, const DerivedPathMap::ChildNode &)> - accum; // NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines) - accum = [&](auto & inputDrv, auto & node) -> kj::Promise> { + auto accum = [&](auto & inputDrv, auto & node) -> kj::Promise> { try { for (auto & [outputName, outputPath] : TRY_AWAIT(store.queryPartialDerivationOutputMap(inputDrv, evalStore))) { if (outputPath) { inputDrvOutputs.insert_or_assign({inputDrv, outputName}, *outputPath); - if (auto p = get(node.childMap, outputName)) - TRY_AWAIT(accum(*outputPath, *p)); } } co_return result::success(); @@ -921,7 +900,7 @@ try { } }; - for (auto & [inputDrv, node] : inputDrvs.map) + for (auto & [inputDrv, node] : inputDrvs) TRY_AWAIT(accum(inputDrv, node)); co_return TRY_AWAIT(tryResolve(store, inputDrvOutputs)); @@ -931,7 +910,7 @@ try { static bool tryResolveInput( Store & store, StorePathSet & inputSrcs, StringMap & inputRewrites, - const StorePath & inputDrv, const DerivedPathMap::ChildNode & inputNode, + const StorePath & inputDrv, const StringSet & inputNode, const std::map, StorePath> & inputDrvOutputs) { auto getOutput = [&](const std::string & outputName) { @@ -948,7 +927,7 @@ static bool tryResolveInput( return DownstreamPlaceholder::unknownCaOutput(inputDrv, outputName); }; - for (auto & outputName : inputNode.value) { + for (auto & outputName : inputNode) { auto actualPathOpt = getOutput(outputName); if (!actualPathOpt) return false; auto actualPath = *actualPathOpt; @@ -960,8 +939,6 @@ static bool tryResolveInput( inputSrcs.insert(std::move(actualPath)); } - // only dynamic drvs can have non-empty childMaps - assert(inputNode.childMap.empty()); return true; } @@ -974,7 +951,7 @@ try { // Input paths that we'll want to rewrite in the derivation StringMap inputRewrites; - for (auto & [inputDrv, inputNode] : inputDrvs.map) + for (auto & [inputDrv, inputNode] : inputDrvs) if (!tryResolveInput(store, resolved.inputSrcs, inputRewrites, inputDrv, inputNode, inputDrvOutputs)) co_return std::nullopt; @@ -1171,22 +1148,16 @@ JSON Derivation::toJSON(const Store & store) const } { - std::function::ChildNode &)> doInput; - doInput = [&](const auto & inputNode) { + auto doInput = [&](const auto & inputNode) { auto value = JSON::object(); - value["outputs"] = inputNode.value; - { - auto next = JSON::object(); - for (auto & [outputId, childNode] : inputNode.childMap) - next[outputId] = doInput(childNode); - value["dynamicOutputs"] = std::move(next); - } + value["outputs"] = inputNode; + value["dynamicOutputs"] = JSON::object(); // for compatibility with cppnix return value; }; { auto& inputDrvsObj = res["inputDrvs"]; inputDrvsObj = JSON::object(); - for (auto & [inputDrv, inputNode] : inputDrvs.map) { + for (auto & [inputDrv, inputNode] : inputDrvs) { inputDrvsObj[store.printStorePath(inputDrv)] = doInput(inputNode); } } @@ -1236,10 +1207,9 @@ Derivation Derivation::fromJSON( } try { - std::function::ChildNode(const JSON &)> doInput; - doInput = [&](const auto & json) { - DerivedPathMap::ChildNode node; - node.value = static_cast( + auto doInput = [&](const auto & json) { + StringSet node; + node = static_cast( ensureType(valueAt(json, "outputs"), value_t::array)); if (!ensureType(valueAt(json, "dynamicOutputs"), value_t::object).empty()) { throw UnimplementedError("dynamic derivations are not supported"); @@ -1248,7 +1218,7 @@ Derivation Derivation::fromJSON( }; auto & inputDrvsObj = ensureType(valueAt(json, "inputDrvs"), value_t::object); for (auto & [inputDrvPath, inputOutputs] : inputDrvsObj.items()) - res.inputDrvs.map[store.parseStorePath(inputDrvPath)] = + res.inputDrvs[store.parseStorePath(inputDrvPath)] = doInput(inputOutputs); } catch (Error & e) { e.addTrace({}, "while reading key 'inputDrvs'"); diff --git a/lix/libstore/derivations.hh b/lix/libstore/derivations.hh index 9ab213e67..fa271c23e 100644 --- a/lix/libstore/derivations.hh +++ b/lix/libstore/derivations.hh @@ -2,15 +2,16 @@ ///@file #include "lix/libstore/path.hh" +#include "lix/libutil/config.hh" #include "lix/libutil/result.hh" #include "lix/libutil/types.hh" #include "lix/libutil/hash.hh" #include "lix/libstore/content-address.hh" #include "lix/libutil/repair-flag.hh" -#include "lix/libstore/derived-path-map.hh" #include "lix/libutil/sync.hh" #include "lix/libutil/comparator.hh" #include "lix/libutil/variant-wrapper.hh" +#include "outputs-spec.hh" #include #include @@ -286,13 +287,13 @@ struct Derivation : BasicDerivation /** * inputs that are sub-derivations */ - DerivedPathMap> inputDrvs; + std::map> inputDrvs; /** * Print a derivation. */ std::string unparse(const Store & store, bool maskOutputs, - DerivedPathMap::ChildNode::Map * actualInputs = nullptr) const; + std::map * actualInputs = nullptr) const; /** * Return the underlying basic derivation but with these changes: diff --git a/lix/libstore/derived-path-map.cc b/lix/libstore/derived-path-map.cc deleted file mode 100644 index d8c833b28..000000000 --- a/lix/libstore/derived-path-map.cc +++ /dev/null @@ -1,69 +0,0 @@ -#include "lix/libstore/derived-path-map.hh" - -namespace nix { - -template -typename DerivedPathMap::ChildNode & DerivedPathMap::ensureSlot(const SingleDerivedPath & k) -{ - std::function initIter; - initIter = [&](const auto & k) -> auto & { - return std::visit(overloaded { - [&](const SingleDerivedPath::Opaque & bo) -> auto & { - // will not overwrite if already there - return map[bo.path]; - }, - [&](const SingleDerivedPath::Built & bfd) -> auto & { - auto & n = initIter(*bfd.drvPath); - return n.childMap[bfd.output]; - }, - }, k.raw()); - }; - return initIter(k); -} - -template -typename DerivedPathMap::ChildNode * DerivedPathMap::findSlot(const SingleDerivedPath & k) -{ - std::function initIter; - initIter = [&](const auto & k) { - return std::visit(overloaded { - [&](const SingleDerivedPath::Opaque & bo) { - auto it = map.find(bo.path); - return it != map.end() - ? &it->second - : nullptr; - }, - [&](const SingleDerivedPath::Built & bfd) { - auto * n = initIter(*bfd.drvPath); - if (!n) return (ChildNode *)nullptr; - - auto it = n->childMap.find(bfd.output); - return it != n->childMap.end() - ? &it->second - : nullptr; - }, - }, k.raw()); - }; - return initIter(k); -} - -} - -// instantiations - -namespace nix { - -GENERATE_CMP_EXT( - template<>, - DerivedPathMap>::ChildNode, - me->value, - me->childMap); - -GENERATE_CMP_EXT( - template<>, - DerivedPathMap>, - me->map); - -template struct DerivedPathMap>; - -}; diff --git a/lix/libstore/derived-path-map.hh b/lix/libstore/derived-path-map.hh deleted file mode 100644 index 1efe7a267..000000000 --- a/lix/libstore/derived-path-map.hh +++ /dev/null @@ -1,96 +0,0 @@ -#pragma once -///@file - -#include "lix/libutil/types.hh" -#include "lix/libstore/derived-path.hh" - -namespace nix { - -/** - * A simple Trie, of sorts. Conceptually a map of `SingleDerivedPath` to - * values. - * - * Concretely, an n-ary tree, as described below. A - * `SingleDerivedPath::Opaque` maps to the value of an immediate child - * of the root node. A `SingleDerivedPath::Built` maps to a deeper child - * node: the `SingleDerivedPath::Built::drvPath` is first mapped to a a - * child node (inductively), and then the - * `SingleDerivedPath::Built::output` is used to look up that child's - * child via its map. In this manner, every `SingleDerivedPath` is - * mapped to a child node. - * - * @param V A type to instantiate for each output. It should probably - * should be an "optional" type so not every interior node has to have a - * value. `* const Something` or `std::optional` would be - * good choices for "optional" types. - */ -template -struct DerivedPathMap { - /** - * A child node (non-root node). - */ - struct ChildNode { - /** - * Value of this child node. - * - * @see DerivedPathMap for what `V` should be. - */ - V value; - - /** - * The map type for the root node. - */ - using Map = std::map; - - /** - * The map of the root node. - */ - Map childMap; - - DECLARE_CMP(ChildNode); - }; - - /** - * The map type for the root node. - */ - using Map = std::map; - - /** - * The map of root node. - */ - Map map; - - DECLARE_CMP(DerivedPathMap); - - /** - * Find the node for `k`, creating it if needed. - * - * The node is referred to as a "slot" on the assumption that `V` is - * some sort of optional type, so the given key can be set or unset - * by changing this node. - */ - ChildNode & ensureSlot(const SingleDerivedPath & k); - - /** - * Like `ensureSlot` but does not create the slot if it doesn't exist. - * - * Read the entire description of `ensureSlot` to understand an - * important caveat here that "have slot" does *not* imply "key is - * set in map". To ensure a key is set one would need to get the - * child node (with `findSlot` or `ensureSlot`) *and* check the - * `ChildNode::value`. - */ - ChildNode * findSlot(const SingleDerivedPath & k); -}; - - -DECLARE_CMP_EXT( - template<>, - DerivedPathMap>::, - DerivedPathMap>); -DECLARE_CMP_EXT( - template<>, - DerivedPathMap>::ChildNode::, - DerivedPathMap>::ChildNode); - -} diff --git a/lix/libstore/meson.build b/lix/libstore/meson.build index 27145df8d..aaa39e266 100644 --- a/lix/libstore/meson.build +++ b/lix/libstore/meson.build @@ -156,7 +156,6 @@ libstore_sources = files( 'crypto.cc', 'daemon.cc', 'derivations.cc', - 'derived-path-map.cc', 'derived-path.cc', 'downstream-placeholder.cc', 'dummy-store.cc', @@ -225,7 +224,6 @@ libstore_headers = files( 'crypto.hh', 'daemon.hh', 'derivations.hh', - 'derived-path-map.hh', 'derived-path.hh', 'downstream-placeholder.hh', 'dummy-store.hh', diff --git a/lix/libstore/misc.cc b/lix/libstore/misc.cc index 134e56669..ef11a6ac7 100644 --- a/lix/libstore/misc.cc +++ b/lix/libstore/misc.cc @@ -150,15 +150,13 @@ struct QueryMissingContext kj::Promise> queryMissing(const std::vector & targets); - void enqueueDerivedPaths(ref inputDrv, const DerivedPathMap::ChildNode & inputNode) + void enqueueDerivedPaths(ref inputDrv, const StringSet & inputNode) { - if (!inputNode.value.empty()) { - pool.enqueueWithAio([this, path{DerivedPath::Built{inputDrv, inputNode.value}}]( + if (!inputNode.empty()) { + pool.enqueueWithAio([this, path{DerivedPath::Built{inputDrv, inputNode}}]( AsyncIoRoot & aio ) { doPath(aio, path); }); } - // only dynamic derivations have a non-empty childMap - assert(inputNode.childMap.empty()); } void mustBuildDrv(const StorePath & drvPath, const Derivation & drv) @@ -168,7 +166,7 @@ struct QueryMissingContext state->willBuild.insert(drvPath); } - for (const auto & [inputDrv, inputNode] : drv.inputDrvs.map) { + for (const auto & [inputDrv, inputNode] : drv.inputDrvs) { enqueueDerivedPaths(makeConstantStorePathRef(inputDrv), inputNode); } } @@ -415,20 +413,15 @@ try { std::set inputRealisations; - std::function< - kj::Promise>(const StorePath &, const DerivedPathMap::ChildNode &)> - accumRealisations; - // NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines) - accumRealisations = [&](const StorePath & inputDrv, - const DerivedPathMap::ChildNode & inputNode - ) -> kj::Promise> { + auto accumRealisations = [&](const StorePath & inputDrv, + const StringSet & inputNode) -> kj::Promise> { try { - if (!inputNode.value.empty()) { + if (!inputNode.empty()) { auto outputHashes = TRY_AWAIT( staticOutputHashes(evalStore, TRY_AWAIT(evalStore.readDerivation(inputDrv))) ); - for (const auto & outputName : inputNode.value) { + for (const auto & outputName : inputNode) { auto outputHash = get(outputHashes, outputName); if (!outputHash) throw Error( @@ -443,23 +436,13 @@ try { inputRealisations.insert(*thisRealisation); } } - if (!inputNode.value.empty()) { - auto d = makeConstantStorePathRef(inputDrv); - for (const auto & [outputName, childNode] : inputNode.childMap) { - SingleDerivedPath next = SingleDerivedPath::Built { d, outputName }; - TRY_AWAIT(accumRealisations( - // TODO deep resolutions for dynamic derivations, issue #8947, would go here. - TRY_AWAIT(resolveDerivedPath(store, next, evalStore_)), - childNode)); - } - } co_return result::success(); } catch (...) { co_return result::current_exception(); } }; - for (const auto & [inputDrv, inputNode] : drv.inputDrvs.map) + for (const auto & [inputDrv, inputNode] : drv.inputDrvs) TRY_AWAIT(accumRealisations(inputDrv, inputNode)); auto info = TRY_AWAIT(store.queryPathInfo(outputPath)); diff --git a/perl/lib/Nix/Store.xs b/perl/lib/Nix/Store.xs index 356c44674..8fba66ae6 100644 --- a/perl/lib/Nix/Store.xs +++ b/perl/lib/Nix/Store.xs @@ -339,7 +339,7 @@ SV * derivationFromPath(char * drvPath) hv_stores(hash, "outputs", newRV((SV *) outputs)); AV * inputDrvs = newAV(); - for (auto & i : drv.inputDrvs.map) + for (auto & i : drv.inputDrvs) av_push(inputDrvs, newSVpv(store()->printStorePath(i.first).c_str(), 0)); // !!! ignores i->second hv_stores(hash, "inputDrvs", newRV((SV *) inputDrvs)); diff --git a/subprojects/nix-eval-jobs/src/constituents.cc b/subprojects/nix-eval-jobs/src/constituents.cc index cdd4e490b..38313f9f1 100644 --- a/subprojects/nix-eval-jobs/src/constituents.cc +++ b/subprojects/nix-eval-jobs/src/constituents.cc @@ -134,8 +134,7 @@ void rewriteAggregates(std::map &jobs, auto childDrv = aio.blockOn(store->readDerivation(childDrvPath)); job["constituents"].push_back( store->printStorePath(childDrvPath)); - drv.inputDrvs.map[childDrvPath].value = { - childDrv.outputs.begin()->first}; + drv.inputDrvs[childDrvPath] = {childDrv.outputs.begin()->first}; } std::string drvName(drvPath.name()); diff --git a/subprojects/nix-eval-jobs/src/drv.cc b/subprojects/nix-eval-jobs/src/drv.cc index 2b4c83adc..2d39c14a7 100644 --- a/subprojects/nix-eval-jobs/src/drv.cc +++ b/subprojects/nix-eval-jobs/src/drv.cc @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -103,9 +102,9 @@ Drv::Drv(std::string &attrPath, nix::EvalState &state, nix::DrvInfo &drvInfo, drvPath = localStore->printStorePath(drvInfo.requireDrvPath(state)); auto drv = state.aio.blockOn(localStore->readDerivation(drvInfo.requireDrvPath(state))); - for (const auto &[inputDrvPath, inputNode] : drv.inputDrvs.map) { + for (const auto &[inputDrvPath, inputNode] : drv.inputDrvs) { std::set inputDrvOutputs; - for (auto &outputName : inputNode.value) { + for (auto &outputName : inputNode) { inputDrvOutputs.insert(outputName); } inputDrvs[localStore->printStorePath(inputDrvPath)] = inputDrvOutputs; diff --git a/tests/unit/libstore/derivation.cc b/tests/unit/libstore/derivation.cc index 2d7af3cd5..fca6b06c8 100644 --- a/tests/unit/libstore/derivation.cc +++ b/tests/unit/libstore/derivation.cc @@ -204,15 +204,11 @@ Derivation makeSimpleDrv(const Store & store) { store.parseStorePath("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"), }; drv.inputDrvs = { - .map = { + { + store.parseStorePath("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv"), { - store.parseStorePath("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv"), - { - .value = { - "cat", - "dog", - }, - }, + "cat", + "dog", }, }, };