From ea792bcdc850c18e6785ff0d2c96d3ef1396bb80 Mon Sep 17 00:00:00 2001 From: regnat Date: Thu, 10 Jun 2021 09:11:47 +0200 Subject: [PATCH] Make nix search lazier Only 4 evals left \o/ --- src/libexpr/eval.cc | 25 ++++++++++++++++--------- src/libexpr/eval.hh | 3 ++- src/nix/search.cc | 5 +++-- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 2b7955bcb..e8130f93e 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1198,12 +1198,8 @@ EvalState::LazyValueType EvalState::lazyGetAttrField(Value & attrs, const std::v } auto [ cacheResult, resultingCursor ] = eval_cache.getValue(*this, selector, dest); updateCacheStats(cacheResult); - switch (cacheResult.returnCode) { - case ValueCache::CacheHit: - if (cacheResult.lastQueriedSymbolIfMissing) - return LazyValueType::Missing; - return LazyValueType::PlainValue; - case ValueCache::Forward: { + + auto delayValue = [&](ValueCache & cursor) { auto recordAsVar = new ExprCastedVar(&attrs); auto accessExpr = new ExprSelect(pos, recordAsVar, selector); auto thunk = (Thunk*)allocBytes(sizeof(Thunk)); @@ -1212,10 +1208,21 @@ EvalState::LazyValueType EvalState::lazyGetAttrField(Value & attrs, const std::v dest.mkCachedThunk( thunk, - new ValueCache(resultingCursor) + new ValueCache(cursor) ); - return LazyValueType::DelayedAttrSet; - } + }; + + switch (cacheResult.returnCode) { + case ValueCache::CacheHit: + if (cacheResult.lastQueriedSymbolIfMissing) + return LazyValueType::Missing; + return LazyValueType::PlainValue; + case ValueCache::UnCacheable: + delayValue(resultingCursor); + return LazyValueType::DelayedUncacheable; + case ValueCache::Forward: + delayValue(resultingCursor); + return LazyValueType::DelayedAttr; default: if(getAttrField(attrs, selector, pos, dest)) return LazyValueType::PlainValue; diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 9d2ee2941..a19518913 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -359,7 +359,8 @@ public: enum struct LazyValueType { PlainValue, - DelayedAttrSet, + DelayedUncacheable, + DelayedAttr, Missing, }; diff --git a/src/nix/search.cc b/src/nix/search.cc index f99faecdf..61bdba967 100644 --- a/src/nix/search.cc +++ b/src/nix/search.cc @@ -98,9 +98,10 @@ struct CmdSearch : InstallableCommand, MixJSON attrPath2.push_back(attrName); auto attrValue = state->allocValue(); auto value_ = allocRootValue(attrValue); - state->lazyGetAttrField(current, {attrName}, noPos, + auto childField = state->lazyGetAttrField(current, {attrName}, noPos, *attrValue); - visit(*attrValue, attrPath2, false); + if (childField != EvalState::LazyValueType::DelayedUncacheable) + visit(*attrValue, attrPath2, false); } catch (EvalError &e) { if (!(attrPath.size() > 0 && attrPath[0] == "legacyPackages"))