mirror of
https://github.com/NixOS/nix.git
synced 2025-11-20 01:09:37 +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 "nixexpr.hh"
|
||||||
#include "symbol-table.hh"
|
#include "symbol-table.hh"
|
||||||
#include "tree-cache.hh"
|
#include "value-cache.hh"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
@ -37,7 +37,7 @@ class Bindings
|
||||||
public:
|
public:
|
||||||
typedef uint32_t size_t;
|
typedef uint32_t size_t;
|
||||||
Pos *pos;
|
Pos *pos;
|
||||||
std::shared_ptr<tree_cache::Cursor> eval_cache;
|
ValueCache eval_cache;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t size_, capacity_;
|
size_t size_, capacity_;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include "filetransfer.hh"
|
#include "filetransfer.hh"
|
||||||
#include "json.hh"
|
#include "json.hh"
|
||||||
#include "function-trace.hh"
|
#include "function-trace.hh"
|
||||||
|
#include "value-cache.hh"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
@ -1109,10 +1110,79 @@ void ExprVar::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
unsigned long nrLookups = 0;
|
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)
|
bool EvalState::getAttrField(Value & attrs, const std::vector<Symbol> & selector, const Pos & pos, Value & dest)
|
||||||
{
|
{
|
||||||
Pos * pos2 = 0;
|
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;
|
Value * vAttrs = &attrs;
|
||||||
try {
|
try {
|
||||||
for (auto & name : selector) {
|
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