aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2024-04-26 15:48:46 +0200
committerQyriad <qyriad@qyriad.me>2024-06-19 18:39:11 +0000
commitfb7d3154115cb5cf211c5ddbc124e17ee519bb64 (patch)
treef073784147a22c95ec6e45ed39c04594034c5cee /src
parentc55dcc6c13b864dc613a0a6ba51e0b897868f4b4 (diff)
Merge pull request #10570 from layus/shared_caches
Share evaluation caches across installables Before: $ rm -rf ~/.cache/nix && time -f '%E' nix build --dry-run \ 'nixpkgs#hello' \ 'nixpkgs#clang' \ 'nixpkgs#cargo' \ 'nixpkgs#rustup' \ 'nixpkgs#bear' \ 'nixpkgs#firefox' \ 'nixpkgs#git-revise' \ 'nixpkgs#hyperfine' \ 'nixpkgs#curlie' \ 'nixpkgs#xz' \ 'nixpkgs#ripgrep' 0:03.61 After: $ rm -rf ~/.cache/nix && time -f '%E' nix build --dry-run \ 'nixpkgs#hello' \ 'nixpkgs#clang' \ 'nixpkgs#cargo' \ 'nixpkgs#rustup' \ 'nixpkgs#bear' \ 'nixpkgs#firefox' \ 'nixpkgs#git-revise' \ 'nixpkgs#hyperfine' \ 'nixpkgs#curlie' \ 'nixpkgs#xz' \ 'nixpkgs#ripgrep' 0:01.46 This could probably use a more proper benchmark... Fixes #313 (cherry picked from commit de51e5c335865e3e0a8cccd283fec1a52cce243f) Change-Id: I9350bebd462b6af12c51db5bf432321abfe84a16
Diffstat (limited to 'src')
-rw-r--r--src/libcmd/installables.cc23
-rw-r--r--src/libexpr/eval.hh9
2 files changed, 24 insertions, 8 deletions
diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc
index a10214561..711cf1b07 100644
--- a/src/libcmd/installables.cc
+++ b/src/libcmd/installables.cc
@@ -393,13 +393,10 @@ ref<eval_cache::EvalCache> openEvalCache(
EvalState & state,
std::shared_ptr<flake::LockedFlake> lockedFlake)
{
- auto fingerprint = lockedFlake->getFingerprint();
- return make_ref<nix::eval_cache::EvalCache>(
- evalSettings.useEvalCache && evalSettings.pureEval
- ? std::optional { std::cref(fingerprint) }
- : std::nullopt,
- state,
- [&state, lockedFlake]()
+ auto fingerprint = evalSettings.useEvalCache && evalSettings.pureEval
+ ? std::make_optional(lockedFlake->getFingerprint())
+ : std::nullopt;
+ auto rootLoader = [&state, lockedFlake]()
{
/* For testing whether the evaluation cache is
complete. */
@@ -415,7 +412,17 @@ ref<eval_cache::EvalCache> openEvalCache(
assert(aOutputs);
return aOutputs->value;
- });
+ };
+
+ if (fingerprint) {
+ auto search = state.evalCaches.find(fingerprint.value());
+ if (search == state.evalCaches.end()) {
+ search = state.evalCaches.emplace(fingerprint.value(), make_ref<nix::eval_cache::EvalCache>(fingerprint, state, rootLoader)).first;
+ }
+ return search->second;
+ } else {
+ return make_ref<nix::eval_cache::EvalCache>(std::nullopt, state, rootLoader);
+ }
}
Installables SourceExprCommand::parseInstallables(
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index ec6e2bb5e..8e390e46d 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -33,6 +33,10 @@ class EvalState;
class StorePath;
struct SingleDerivedPath;
enum RepairFlag : bool;
+struct MemoryInputAccessor;
+namespace eval_cache {
+ class EvalCache;
+}
/**
@@ -234,6 +238,11 @@ public:
return *new EvalErrorBuilder<T>(*this, args...);
}
+ /**
+ * A cache for evaluation caches, so as to reuse the same root value if possible
+ */
+ std::map<const Hash, ref<eval_cache::EvalCache>> evalCaches;
+
private:
/* Cache for calls to addToStore(); maps source paths to the store