#pragma once ///@file #include "lix/libutil/sync.hh" #include "lix/libutil/hash.hh" #include "lix/libexpr/eval.hh" #include #include namespace nix::eval_cache { struct AttrDb; class AttrCursor; typedef std::function 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 CachingEvaluator : public Evaluator { /** * A cache for evaluation caches, so as to reuse the same root value if possible */ std::map> caches; public: using Evaluator::Evaluator; ref getCacheFor(Hash hash, RootLoader rootLoader); }; class EvalCache : public std::enable_shared_from_this { friend class AttrCursor; std::shared_ptr db; RootLoader rootLoader; RootValue value; Value * getRootValue(EvalState & state); public: EvalCache( std::optional> useCache, RootLoader rootLoader); ref getRoot(); }; enum AttrType { Placeholder = 0, FullAttrs = 1, String = 2, Missing = 3, Misc = 4, Failed = 5, Bool = 6, ListOfStrings = 7, Int = 8, }; struct placeholder_t {}; struct fullattr_t { std::vector p; }; struct missing_t {}; struct misc_t {}; struct failed_t {}; struct int_t { NixInt x; }; typedef uint64_t AttrId; typedef std::pair AttrKey; typedef std::pair string_t; typedef std::variant< fullattr_t, string_t, placeholder_t, missing_t, misc_t, failed_t, bool, int_t, std::vector > AttrValue; class AttrCursor : public std::enable_shared_from_this { friend class EvalCache; ref root; typedef std::optional, std::string>> Parent; Parent parent; RootValue _value; std::optional> cachedValue; AttrKey getKey(); Value & getValue(EvalState & state); public: AttrCursor( ref root, Parent parent, Value * value = nullptr, std::optional> && cachedValue = {}); std::vector getAttrPath(EvalState & state) const; std::vector getAttrPath(EvalState & state, std::string_view name) const; std::string getAttrPathStr(EvalState & state) const; std::string getAttrPathStr(EvalState & state, std::string_view name) const; Suggestions getSuggestionsForAttr(EvalState & state, const std::string & name); std::shared_ptr maybeGetAttr(EvalState & state, const std::string & name); ref getAttr(EvalState & state, const std::string & name); /** * Get an attribute along a chain of attrsets. Note that this does * not auto-call functors or functions. */ OrSuggestions> findAlongAttrPath(EvalState & state, const std::vector & attrPath); std::string getString(EvalState & state); string_t getStringWithContext(EvalState & state); bool getBool(EvalState & state); NixInt getInt(EvalState & state); std::vector getListOfStrings(EvalState & state); std::vector getAttrs(EvalState & state); bool isDerivation(EvalState & state); Value & forceValue(EvalState & state); /** * Force creation of the .drv file in the Nix store. */ StorePath forceDerivation(EvalState & state); }; }