1
1
Fork 0
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:
regnat 2021-06-03 06:40:54 +02:00
parent 44f390ed48
commit 6396416dfa
3 changed files with 123 additions and 2 deletions

View file

@ -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_;

View file

@ -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) {

View 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) {}
};
}