mirror of
https://github.com/NixOS/nix.git
synced 2025-11-20 01:09:37 +01:00
Use the cache in nix search
Not optimal atm, possibly because we don’t cache the evaluation failures
This commit is contained in:
parent
a6aaf81103
commit
9102508f33
5 changed files with 161 additions and 17 deletions
|
|
@ -1284,6 +1284,43 @@ bool EvalState::getAttrField(Value & attrs, const std::vector<Symbol> & selector
|
|||
return true;
|
||||
}
|
||||
|
||||
void EvalState::getAttrFieldThrow(Value & attrs, const std::vector<Symbol> & selector, const Pos & pos, Value & dest)
|
||||
{
|
||||
if (!getAttrField(attrs, selector, pos, dest))
|
||||
throw Error("Missing attribute path '%s'", "ImTooLazyToImplementThisRightNow");
|
||||
}
|
||||
|
||||
std::vector<Attr> EvalState::getFields(Value & attrs, const Pos & pos)
|
||||
{
|
||||
auto eval_cache = attrs.getEvalCache();
|
||||
if (eval_cache.isEmpty()) {
|
||||
forceValue(attrs, pos);
|
||||
eval_cache = attrs.getEvalCache();
|
||||
}
|
||||
if (auto attrNames = eval_cache.listChildren(symbols)) {
|
||||
bool everythingCached = true;
|
||||
std::vector<Attr> res;
|
||||
for (auto & attrName : *attrNames) {
|
||||
auto newValue = allocValue();
|
||||
try {
|
||||
if (lazyGetAttrField(attrs, {attrName}, pos, *newValue)) {
|
||||
res.push_back(Attr(attrName, newValue));
|
||||
} else {
|
||||
everythingCached = false;
|
||||
break;
|
||||
}
|
||||
} catch (Error &) {
|
||||
everythingCached = false;
|
||||
}
|
||||
}
|
||||
if (everythingCached) return res;
|
||||
}
|
||||
|
||||
forceValue(attrs);
|
||||
auto attrsStart = attrs.attrs->attrs;
|
||||
return std::vector<Attr>(attrsStart, attrsStart + attrs.attrs->size());
|
||||
}
|
||||
|
||||
void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
Value vTmp;
|
||||
|
|
@ -1493,6 +1530,20 @@ std::optional<tree_cache::AttrValue> ValueCache::getRawValue()
|
|||
return rawCache->getCachedValue();
|
||||
}
|
||||
|
||||
std::optional<std::vector<Symbol>> ValueCache::listChildren(SymbolTable& symbols)
|
||||
{
|
||||
auto ret = std::vector<Symbol>();
|
||||
if (rawCache) {
|
||||
auto cachedValue = rawCache->getCachedValue();
|
||||
if (std::get_if<tree_cache::attributeSet_t>(&cachedValue)) {
|
||||
for (auto & fieldStr : rawCache->getChildren())
|
||||
ret.push_back(symbols.create(fieldStr));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
|
||||
{
|
||||
if (auto evalCache = fun.getEvalCache(); !evalCache.isEmpty()) {
|
||||
|
|
|
|||
|
|
@ -359,6 +359,12 @@ public:
|
|||
// Similar to `getAttrField`, but if the cache says that the result is an
|
||||
// attribute set, just return a thunk to it rather than forcing it.
|
||||
bool lazyGetAttrField(Value & attrs, const std::vector<Symbol> & selector, const Pos & pos, Value & dest);
|
||||
|
||||
// Similar to `getAttrField`, but throws an `Error` if the field can’t be
|
||||
// found
|
||||
void getAttrFieldThrow(Value & attrs, const std::vector<Symbol> & selector, const Pos & pos, Value & dest);
|
||||
|
||||
std::vector<Attr> getFields(Value & attrs, const Pos & pos);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue