libexpr: remove eval caches from EvalState
eval caches are not used by actual eval at all, only by the flake-shaped
wrappers around evaluation. moving caches into a subclass both clarifies
that eval caches and eval states are coupled and separates concerns that
should not have been intermixed as they were here. in the future we will
want to split up and decouple things even further. that'll have to wait.
Change-Id: I7b69510c0f8b212f05fae62e7b992d9475b4841f
This commit is contained in:
parent
564f464772
commit
7c650ea241
|
@ -102,15 +102,15 @@ ref<Store> EvalCommand::getEvalStore()
|
||||||
return ref<Store>(evalStore);
|
return ref<Store>(evalStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<EvalState> EvalCommand::getEvalState()
|
ref<eval_cache::CachingEvalState> EvalCommand::getEvalState()
|
||||||
{
|
{
|
||||||
if (!evalState) {
|
if (!evalState) {
|
||||||
evalState =
|
evalState =
|
||||||
#if HAVE_BOEHMGC
|
#if HAVE_BOEHMGC
|
||||||
std::allocate_shared<EvalState>(traceable_allocator<EvalState>(),
|
std::allocate_shared<eval_cache::CachingEvalState>(traceable_allocator<EvalState>(),
|
||||||
searchPath, getEvalStore(), getStore())
|
searchPath, getEvalStore(), getStore())
|
||||||
#else
|
#else
|
||||||
std::make_shared<EvalState>(
|
std::make_shared<eval_cache::CachingEvalState>(
|
||||||
searchPath, getEvalStore(), getStore())
|
searchPath, getEvalStore(), getStore())
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
@ -121,7 +121,7 @@ ref<EvalState> EvalCommand::getEvalState()
|
||||||
evalState->debug = std::make_unique<DebugState>(&AbstractNixRepl::runSimple);
|
evalState->debug = std::make_unique<DebugState>(&AbstractNixRepl::runSimple);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return ref<EvalState>(evalState);
|
return ref<eval_cache::CachingEvalState>(evalState);
|
||||||
}
|
}
|
||||||
|
|
||||||
MixOperateOnOptions::MixOperateOnOptions()
|
MixOperateOnOptions::MixOperateOnOptions()
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
///@file
|
///@file
|
||||||
|
|
||||||
#include "lix/libcmd/installable-value.hh"
|
#include "lix/libcmd/installable-value.hh"
|
||||||
|
#include "lix/libexpr/eval-cache.hh"
|
||||||
#include "lix/libutil/args.hh"
|
#include "lix/libutil/args.hh"
|
||||||
#include "lix/libcmd/common-eval-args.hh"
|
#include "lix/libcmd/common-eval-args.hh"
|
||||||
#include "lix/libstore/path.hh"
|
#include "lix/libstore/path.hh"
|
||||||
|
@ -76,12 +77,12 @@ struct EvalCommand : virtual StoreCommand, MixEvalArgs
|
||||||
|
|
||||||
ref<Store> getEvalStore();
|
ref<Store> getEvalStore();
|
||||||
|
|
||||||
ref<EvalState> getEvalState();
|
ref<eval_cache::CachingEvalState> getEvalState();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Store> evalStore;
|
std::shared_ptr<Store> evalStore;
|
||||||
|
|
||||||
std::shared_ptr<EvalState> evalState;
|
std::shared_ptr<eval_cache::CachingEvalState> evalState;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -331,7 +332,7 @@ void completeFlakeRef(AddCompletions & completions, ref<Store> store, std::strin
|
||||||
|
|
||||||
void completeFlakeRefWithFragment(
|
void completeFlakeRefWithFragment(
|
||||||
AddCompletions & completions,
|
AddCompletions & completions,
|
||||||
ref<EvalState> evalState,
|
ref<eval_cache::CachingEvalState> evalState,
|
||||||
flake::LockFlags lockFlags,
|
flake::LockFlags lockFlags,
|
||||||
Strings attrPathPrefixes,
|
Strings attrPathPrefixes,
|
||||||
const Strings & defaultFlakeAttrPaths,
|
const Strings & defaultFlakeAttrPaths,
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
InstallableAttrPath::InstallableAttrPath(
|
InstallableAttrPath::InstallableAttrPath(
|
||||||
ref<EvalState> state,
|
ref<eval_cache::CachingEvalState> state,
|
||||||
SourceExprCommand & cmd,
|
SourceExprCommand & cmd,
|
||||||
Value * v,
|
Value * v,
|
||||||
const std::string & attrPath,
|
const std::string & attrPath,
|
||||||
|
@ -93,7 +93,7 @@ DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths()
|
||||||
}
|
}
|
||||||
|
|
||||||
InstallableAttrPath InstallableAttrPath::parse(
|
InstallableAttrPath InstallableAttrPath::parse(
|
||||||
ref<EvalState> state,
|
ref<eval_cache::CachingEvalState> state,
|
||||||
SourceExprCommand & cmd,
|
SourceExprCommand & cmd,
|
||||||
Value * v,
|
Value * v,
|
||||||
std::string_view prefix,
|
std::string_view prefix,
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
///@file
|
///@file
|
||||||
|
|
||||||
#include "lix/libcmd/installable-value.hh"
|
#include "lix/libcmd/installable-value.hh"
|
||||||
|
#include "lix/libexpr/eval-cache.hh"
|
||||||
#include "lix/libstore/outputs-spec.hh"
|
#include "lix/libstore/outputs-spec.hh"
|
||||||
#include "lix/libcmd/command.hh"
|
#include "lix/libcmd/command.hh"
|
||||||
#include "lix/libcmd/common-eval-args.hh"
|
#include "lix/libcmd/common-eval-args.hh"
|
||||||
|
@ -19,7 +20,7 @@ class InstallableAttrPath : public InstallableValue
|
||||||
ExtendedOutputsSpec extendedOutputsSpec;
|
ExtendedOutputsSpec extendedOutputsSpec;
|
||||||
|
|
||||||
InstallableAttrPath(
|
InstallableAttrPath(
|
||||||
ref<EvalState> state,
|
ref<eval_cache::CachingEvalState> state,
|
||||||
SourceExprCommand & cmd,
|
SourceExprCommand & cmd,
|
||||||
Value * v,
|
Value * v,
|
||||||
const std::string & attrPath,
|
const std::string & attrPath,
|
||||||
|
@ -34,7 +35,7 @@ class InstallableAttrPath : public InstallableValue
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static InstallableAttrPath parse(
|
static InstallableAttrPath parse(
|
||||||
ref<EvalState> state,
|
ref<eval_cache::CachingEvalState> state,
|
||||||
SourceExprCommand & cmd,
|
SourceExprCommand & cmd,
|
||||||
Value * v,
|
Value * v,
|
||||||
std::string_view prefix,
|
std::string_view prefix,
|
||||||
|
|
|
@ -67,7 +67,7 @@ static std::string showAttrPaths(const std::vector<std::string> & paths)
|
||||||
|
|
||||||
InstallableFlake::InstallableFlake(
|
InstallableFlake::InstallableFlake(
|
||||||
SourceExprCommand * cmd,
|
SourceExprCommand * cmd,
|
||||||
ref<EvalState> state,
|
ref<eval_cache::CachingEvalState> state,
|
||||||
FlakeRef && flakeRef,
|
FlakeRef && flakeRef,
|
||||||
std::string_view fragment,
|
std::string_view fragment,
|
||||||
ExtendedOutputsSpec extendedOutputsSpec,
|
ExtendedOutputsSpec extendedOutputsSpec,
|
||||||
|
|
|
@ -40,7 +40,7 @@ struct InstallableFlake : InstallableValue
|
||||||
|
|
||||||
InstallableFlake(
|
InstallableFlake(
|
||||||
SourceExprCommand * cmd,
|
SourceExprCommand * cmd,
|
||||||
ref<EvalState> state,
|
ref<eval_cache::CachingEvalState> state,
|
||||||
FlakeRef && flakeRef,
|
FlakeRef && flakeRef,
|
||||||
std::string_view fragment,
|
std::string_view fragment,
|
||||||
ExtendedOutputsSpec extendedOutputsSpec,
|
ExtendedOutputsSpec extendedOutputsSpec,
|
||||||
|
@ -83,7 +83,7 @@ static inline FlakeRef defaultNixpkgsFlakeRef()
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<eval_cache::EvalCache> openEvalCache(
|
ref<eval_cache::EvalCache> openEvalCache(
|
||||||
EvalState & state,
|
eval_cache::CachingEvalState & state,
|
||||||
std::shared_ptr<flake::LockedFlake> lockedFlake);
|
std::shared_ptr<flake::LockedFlake> lockedFlake);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
///@file
|
///@file
|
||||||
|
|
||||||
#include "lix/libcmd/installables.hh"
|
#include "lix/libcmd/installables.hh"
|
||||||
|
#include "lix/libexpr/eval-cache.hh"
|
||||||
#include "lix/libexpr/flake/flake.hh"
|
#include "lix/libexpr/flake/flake.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
@ -9,8 +10,6 @@ namespace nix {
|
||||||
struct DrvInfo;
|
struct DrvInfo;
|
||||||
struct SourceExprCommand;
|
struct SourceExprCommand;
|
||||||
|
|
||||||
namespace eval_cache { class EvalCache; class AttrCursor; }
|
|
||||||
|
|
||||||
struct App
|
struct App
|
||||||
{
|
{
|
||||||
std::vector<DerivedPath> context;
|
std::vector<DerivedPath> context;
|
||||||
|
@ -71,9 +70,9 @@ struct ExtraPathInfoValue : ExtraPathInfo
|
||||||
*/
|
*/
|
||||||
struct InstallableValue : Installable
|
struct InstallableValue : Installable
|
||||||
{
|
{
|
||||||
ref<EvalState> state;
|
ref<eval_cache::CachingEvalState> state;
|
||||||
|
|
||||||
InstallableValue(ref<EvalState> state) : state(state) {}
|
InstallableValue(ref<eval_cache::CachingEvalState> state) : state(state) {}
|
||||||
|
|
||||||
virtual ~InstallableValue() { }
|
virtual ~InstallableValue() { }
|
||||||
|
|
||||||
|
|
|
@ -267,7 +267,7 @@ void SourceExprCommand::completeInstallable(AddCompletions & completions, std::s
|
||||||
|
|
||||||
void completeFlakeRefWithFragment(
|
void completeFlakeRefWithFragment(
|
||||||
AddCompletions & completions,
|
AddCompletions & completions,
|
||||||
ref<EvalState> evalState,
|
ref<eval_cache::CachingEvalState> evalState,
|
||||||
flake::LockFlags lockFlags,
|
flake::LockFlags lockFlags,
|
||||||
Strings attrPathPrefixes,
|
Strings attrPathPrefixes,
|
||||||
const Strings & defaultFlakeAttrPaths,
|
const Strings & defaultFlakeAttrPaths,
|
||||||
|
@ -390,7 +390,7 @@ static StorePath getDeriver(
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<eval_cache::EvalCache> openEvalCache(
|
ref<eval_cache::EvalCache> openEvalCache(
|
||||||
EvalState & state,
|
eval_cache::CachingEvalState & state,
|
||||||
std::shared_ptr<flake::LockedFlake> lockedFlake)
|
std::shared_ptr<flake::LockedFlake> lockedFlake)
|
||||||
{
|
{
|
||||||
auto fingerprint = evalSettings.useEvalCache && evalSettings.pureEval
|
auto fingerprint = evalSettings.useEvalCache && evalSettings.pureEval
|
||||||
|
@ -415,11 +415,7 @@ ref<eval_cache::EvalCache> openEvalCache(
|
||||||
};
|
};
|
||||||
|
|
||||||
if (fingerprint) {
|
if (fingerprint) {
|
||||||
auto search = state.evalCaches.find(fingerprint.value());
|
return state.getCacheFor(fingerprint.value(), rootLoader);
|
||||||
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 {
|
} else {
|
||||||
return make_ref<nix::eval_cache::EvalCache>(std::nullopt, state, rootLoader);
|
return make_ref<nix::eval_cache::EvalCache>(std::nullopt, state, rootLoader);
|
||||||
}
|
}
|
||||||
|
|
|
@ -334,6 +334,16 @@ static std::shared_ptr<AttrDb> makeAttrDb(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ref<EvalCache> CachingEvalState::getCacheFor(Hash hash, RootLoader rootLoader)
|
||||||
|
{
|
||||||
|
if (auto it = caches.find(hash); it != caches.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
auto cache = make_ref<EvalCache>(hash, *this, rootLoader);
|
||||||
|
caches.emplace(hash, cache);
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
EvalCache::EvalCache(
|
EvalCache::EvalCache(
|
||||||
std::optional<std::reference_wrapper<const Hash>> useCache,
|
std::optional<std::reference_wrapper<const Hash>> useCache,
|
||||||
EvalState & state,
|
EvalState & state,
|
||||||
|
|
|
@ -13,13 +13,34 @@ namespace nix::eval_cache {
|
||||||
struct AttrDb;
|
struct AttrDb;
|
||||||
class AttrCursor;
|
class AttrCursor;
|
||||||
|
|
||||||
|
typedef std::function<Value *()> RootLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EvalState with caching support. Historically this was part of EvalState,
|
||||||
|
* but it was split out to make maintenance easier. This could've been just
|
||||||
|
* a pair of EvalState and the cache map, but doing so would currently hide
|
||||||
|
* the rather strong connection between EvalState and these caches. At some
|
||||||
|
* future time the cache interface should be changed to hide its EvalState.
|
||||||
|
*/
|
||||||
|
class CachingEvalState : public EvalState
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A cache for evaluation caches, so as to reuse the same root value if possible
|
||||||
|
*/
|
||||||
|
std::map<Hash, ref<EvalCache>> caches;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using EvalState::EvalState;
|
||||||
|
|
||||||
|
ref<EvalCache> getCacheFor(Hash hash, RootLoader rootLoader);
|
||||||
|
};
|
||||||
|
|
||||||
class EvalCache : public std::enable_shared_from_this<EvalCache>
|
class EvalCache : public std::enable_shared_from_this<EvalCache>
|
||||||
{
|
{
|
||||||
friend class AttrCursor;
|
friend class AttrCursor;
|
||||||
|
|
||||||
std::shared_ptr<AttrDb> db;
|
std::shared_ptr<AttrDb> db;
|
||||||
EvalState & state;
|
EvalState & state;
|
||||||
typedef std::function<Value *()> RootLoader;
|
|
||||||
RootLoader rootLoader;
|
RootLoader rootLoader;
|
||||||
RootValue value;
|
RootValue value;
|
||||||
|
|
||||||
|
|
|
@ -321,11 +321,6 @@ public:
|
||||||
return *new EvalErrorBuilder<T>(*this, args...);
|
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:
|
private:
|
||||||
|
|
||||||
/* Cache for calls to addToStore(); maps source paths to the store
|
/* Cache for calls to addToStore(); maps source paths to the store
|
||||||
|
|
Loading…
Reference in a new issue