mirror of
https://github.com/NixOS/nix.git
synced 2025-11-19 16:59:35 +01:00
Query the eval cache
(It’s still always empty)
This commit is contained in:
parent
44f390ed48
commit
6396416dfa
3 changed files with 123 additions and 2 deletions
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "nixexpr.hh"
|
||||
#include "symbol-table.hh"
|
||||
#include "tree-cache.hh"
|
||||
#include "value-cache.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <optional>
|
||||
|
|
@ -37,7 +37,7 @@ class Bindings
|
|||
public:
|
||||
typedef uint32_t size_t;
|
||||
Pos *pos;
|
||||
std::shared_ptr<tree_cache::Cursor> eval_cache;
|
||||
ValueCache eval_cache;
|
||||
|
||||
private:
|
||||
size_t size_, capacity_;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "filetransfer.hh"
|
||||
#include "json.hh"
|
||||
#include "function-trace.hh"
|
||||
#include "value-cache.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
|
|
@ -1109,10 +1110,79 @@ void ExprVar::eval(EvalState & state, Env & env, Value & v)
|
|||
|
||||
unsigned long nrLookups = 0;
|
||||
|
||||
std::pair<ValueCache::CacheResult, ValueCache> ValueCache::getValue(EvalState & state, const std::vector<Symbol> & selector, Value & dest)
|
||||
{
|
||||
if (!rawCache)
|
||||
return { {NoCacheKey}, ValueCache(nullptr) };
|
||||
auto resultingCursor = rawCache->findAlongAttrPath(selector);
|
||||
if (!resultingCursor)
|
||||
return { {CacheMiss}, ValueCache(nullptr) };
|
||||
|
||||
auto cachedValue = resultingCursor->getCachedValue();
|
||||
auto cacheResult = std::visit(
|
||||
overloaded{
|
||||
[&](tree_cache::attributeSet_t) { return ValueCache::CacheResult{ Forward }; },
|
||||
[&](tree_cache::unknown_t) { return ValueCache::CacheResult{ UnCacheable }; },
|
||||
[&](tree_cache::thunk_t) { return ValueCache::CacheResult{ CacheMiss }; },
|
||||
[&](tree_cache::failed_t x) -> ValueCache::CacheResult {throw EvalError(x.error); },
|
||||
[&](tree_cache::missing_t x) {
|
||||
return ValueCache::CacheResult{
|
||||
.returnCode = CacheHit,
|
||||
.lastQueriedSymbolIfMissing = x.attrName
|
||||
};
|
||||
},
|
||||
[&](tree_cache::string_t s) {
|
||||
PathSet context;
|
||||
for (auto& [pathName, outputName] : s.second) {
|
||||
// If the cached value depends on some non-existent
|
||||
// path, we need to discard it and force the evaluation
|
||||
// to bring back the context in the store
|
||||
if (!state.store->isValidPath(
|
||||
state.store->parseStorePath(pathName)))
|
||||
return ValueCache::CacheResult{UnCacheable};
|
||||
context.insert("!" + outputName + "!" + pathName);
|
||||
}
|
||||
mkString(dest, s.first, context);
|
||||
return ValueCache::CacheResult{CacheHit};
|
||||
},
|
||||
[&](tree_cache::wrapped_basetype<bool> b) {
|
||||
dest.mkBool(b.value);
|
||||
return ValueCache::CacheResult{CacheHit};
|
||||
},
|
||||
[&](tree_cache::wrapped_basetype<int64_t> i) {
|
||||
dest.mkInt(i.value);
|
||||
return ValueCache::CacheResult{CacheHit};
|
||||
},
|
||||
[&](tree_cache::wrapped_basetype<double> d) {
|
||||
dest.mkFloat(d.value);
|
||||
return ValueCache::CacheResult{CacheHit};
|
||||
},
|
||||
},
|
||||
cachedValue);
|
||||
|
||||
return { cacheResult, ValueCache(resultingCursor) };
|
||||
}
|
||||
|
||||
bool EvalState::getAttrField(Value & attrs, const std::vector<Symbol> & selector, const Pos & pos, Value & dest)
|
||||
{
|
||||
Pos * pos2 = 0;
|
||||
|
||||
forceValue(attrs, pos);
|
||||
if (attrs.type() == nAttrs) {
|
||||
auto eval_cache = attrs.attrs->eval_cache;
|
||||
auto [ cacheResult, resultingCursor ] = eval_cache.getValue(*this, selector, dest);
|
||||
switch (cacheResult.returnCode) {
|
||||
case ValueCache::CacheHit:
|
||||
return true;
|
||||
case ValueCache::CacheMiss:
|
||||
return false;
|
||||
case ValueCache::Forward: // Fixme: Handle properly
|
||||
case ValueCache::NoCacheKey:
|
||||
case ValueCache::UnCacheable:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
Value * vAttrs = &attrs;
|
||||
try {
|
||||
for (auto & name : selector) {
|
||||
|
|
|
|||
51
src/libexpr/value-cache.hh
Normal file
51
src/libexpr/value-cache.hh
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#pragma once
|
||||
#include "tree-cache.hh"
|
||||
|
||||
namespace nix {
|
||||
struct Value;
|
||||
class EvalState;
|
||||
class Bindings;
|
||||
|
||||
class ValueCache {
|
||||
tree_cache::Cursor::Ref rawCache;
|
||||
|
||||
public:
|
||||
|
||||
ValueCache(tree_cache::Cursor::Ref rawCache) : rawCache(rawCache) {}
|
||||
|
||||
const static ValueCache empty;
|
||||
|
||||
bool isEmpty () { return rawCache == nullptr; }
|
||||
|
||||
enum ReturnCode {
|
||||
// The cache result was an attribute set, so we forward it later in the
|
||||
// chain
|
||||
Forward,
|
||||
CacheMiss,
|
||||
CacheHit,
|
||||
UnCacheable,
|
||||
NoCacheKey,
|
||||
};
|
||||
|
||||
struct CacheResult {
|
||||
ReturnCode returnCode;
|
||||
|
||||
// In case the query returns a `missing_t`, the symbol that's missing
|
||||
std::optional<Symbol> lastQueriedSymbolIfMissing;
|
||||
};
|
||||
std::pair<CacheResult, ValueCache> getValue(EvalState & state, const std::vector<Symbol> & selector, Value & dest);
|
||||
|
||||
ValueCache addChild(const Symbol & attrName, const Value & value);
|
||||
ValueCache addFailedChild(const Symbol & attrName, const Error & error);
|
||||
ValueCache addNumChild(SymbolTable & symbols, int idx, const Value & value);
|
||||
void addAttrSetChilds(Bindings & children);
|
||||
void addListChilds(SymbolTable & symbols, Value** elems, int listSize);
|
||||
|
||||
std::optional<std::vector<Symbol>> listChildren(SymbolTable&);
|
||||
std::optional<std::vector<Symbol>> listChildrenAtPath(SymbolTable&, const std::vector<Symbol> & attrPath);
|
||||
|
||||
std::optional<tree_cache::AttrValue> getRawValue();
|
||||
|
||||
ValueCache() : rawCache(nullptr) {}
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue