From a60a1f09b2f667d10ff0873b9fd5a70bad3febfd Mon Sep 17 00:00:00 2001 From: Guillaume Maudoux Date: Fri, 19 Apr 2024 16:21:51 +0200 Subject: [PATCH 1/3] Reuse eval caches and related values when possible --- src/libcmd/installables.cc | 22 +++++++++++++++------- src/libexpr/eval.hh | 8 ++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index ed6772377..5683e1afa 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -444,12 +444,10 @@ ref openEvalCache( std::shared_ptr lockedFlake) { auto fingerprint = lockedFlake->getFingerprint(state.store); - return make_ref( - evalSettings.useEvalCache && evalSettings.pureEval - ? fingerprint - : std::nullopt, - state, - [&state, lockedFlake]() + auto hash = evalSettings.useEvalCache && evalSettings.pureEval + ? fingerprint + : std::nullopt; + auto rootLoader = [&state, lockedFlake]() { /* For testing whether the evaluation cache is complete. */ @@ -465,7 +463,17 @@ ref openEvalCache( assert(aOutputs); return aOutputs->value; - }); + }; + + if (hash) { + auto search = state.evalCaches.find(hash.value()); + if (search == state.evalCaches.end()) { + search = state.evalCaches.emplace(hash.value(), make_ref(hash, state, rootLoader)).first; + } + return search->second; + } else { + return make_ref(hash, state, rootLoader); + } } Installables SourceExprCommand::parseInstallables( diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 3477f6c46..508361301 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -34,6 +34,9 @@ class StorePath; struct SingleDerivedPath; enum RepairFlag : bool; struct MemoryInputAccessor; +namespace eval_cache { + class EvalCache; +} /** @@ -282,6 +285,11 @@ public: return *new EvalErrorBuilder(*this, args...); } + /** + * A cache for evaluation caches, so as to reuse the same root value if possible + */ + std::map> evalCaches; + private: /* Cache for calls to addToStore(); maps source paths to the store From 1c4e392c64939ca961458cfb15a9da1e4d883b22 Mon Sep 17 00:00:00 2001 From: Guillaume Maudoux Date: Thu, 25 Apr 2024 00:44:47 +0200 Subject: [PATCH 2/3] Compute fingerprint only if needed As per Eelco's review comments Co-authored-by: Eelco Dolstra --- src/libcmd/installables.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 5683e1afa..e5c981629 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -443,9 +443,8 @@ ref openEvalCache( EvalState & state, std::shared_ptr lockedFlake) { - auto fingerprint = lockedFlake->getFingerprint(state.store); - auto hash = evalSettings.useEvalCache && evalSettings.pureEval - ? fingerprint + auto fingerprint = evalSettings.useEvalCache && evalSettings.pureEval + ? lockedFlake->getFingerprint(state.store) : std::nullopt; auto rootLoader = [&state, lockedFlake]() { @@ -472,7 +471,7 @@ ref openEvalCache( } return search->second; } else { - return make_ref(hash, state, rootLoader); + return make_ref(std::nullopt, state, rootLoader); } } From 19cc50dcbf58dd52a82308ab1733d2d7764db9d1 Mon Sep 17 00:00:00 2001 From: Guillaume Maudoux Date: Thu, 25 Apr 2024 00:47:46 +0200 Subject: [PATCH 3/3] fixup: Compute fingerprint only if needed --- src/libcmd/installables.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index e5c981629..b93c7f7e8 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -464,10 +464,10 @@ ref openEvalCache( return aOutputs->value; }; - if (hash) { - auto search = state.evalCaches.find(hash.value()); + if (fingerprint) { + auto search = state.evalCaches.find(fingerprint.value()); if (search == state.evalCaches.end()) { - search = state.evalCaches.emplace(hash.value(), make_ref(hash, state, rootLoader)).first; + search = state.evalCaches.emplace(fingerprint.value(), make_ref(fingerprint, state, rootLoader)).first; } return search->second; } else {