diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index df4e52e5d..69d7ba380 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1090,7 +1090,9 @@ void EvalState::evalFile(const SourcePath & path, Value & v, bool mustBeTrivial) void EvalState::resetFileCache() { fileEvalCache.clear(); + fileEvalCache.rehash(0); fileParseCache.clear(); + fileParseCache.rehash(0); inputCache->clear(); } @@ -2375,10 +2377,9 @@ StorePath EvalState::copyPathToStore(NixStringContext & context, const SourcePat if (nix::isDerivation(path.path.abs())) error("file names are not allowed to end in '%1%'", drvExtension).debugThrow(); - auto dstPathCached = get(*srcToStore.lock(), path); - - auto dstPath = dstPathCached ? *dstPathCached : [&]() { - auto dstPath = fetchToStore( + std::optional dstPath; + if (!srcToStore.cvisit(path, [&dstPath](const auto & kv) { dstPath.emplace(kv.second); })) { + dstPath.emplace(fetchToStore( fetchSettings, *store, path.resolveSymlinks(SymlinkResolution::Ancestors), @@ -2386,15 +2387,14 @@ StorePath EvalState::copyPathToStore(NixStringContext & context, const SourcePat path.baseName(), ContentAddressMethod::Raw::NixArchive, nullptr, - repair); - allowPath(dstPath); - srcToStore.lock()->try_emplace(path, dstPath); - printMsg(lvlChatty, "copied source '%1%' -> '%2%'", path, store->printStorePath(dstPath)); - return dstPath; - }(); + repair)); + allowPath(*dstPath); + srcToStore.try_emplace(path, *dstPath); + printMsg(lvlChatty, "copied source '%1%' -> '%2%'", path, store->printStorePath(*dstPath)); + } - context.insert(NixStringContextElem::Opaque{.path = dstPath}); - return dstPath; + context.insert(NixStringContextElem::Opaque{.path = *dstPath}); + return *dstPath; } SourcePath EvalState::coerceToPath(const PosIdx pos, Value & v, NixStringContext & context, std::string_view errorCtx) diff --git a/src/libexpr/include/nix/expr/eval.hh b/src/libexpr/include/nix/expr/eval.hh index 5015a009b..75ed12664 100644 --- a/src/libexpr/include/nix/expr/eval.hh +++ b/src/libexpr/include/nix/expr/eval.hh @@ -20,6 +20,8 @@ // For `NIX_USE_BOEHMGC`, and if that's set, `GC_THREADS` #include "nix/expr/config.hh" +#include +#include #include #include #include @@ -162,7 +164,7 @@ typedef std:: map, traceable_allocator>> ValMap; -typedef std::unordered_map DocCommentMap; +typedef boost::unordered_flat_map> DocCommentMap; struct Env { @@ -395,7 +397,7 @@ public: bool inDebugger = false; int trylevel; std::list debugTraces; - std::map> exprEnvs; + boost::unordered_flat_map> exprEnvs; const std::shared_ptr getStaticEnv(const Expr & expr) const { @@ -438,12 +440,12 @@ private: /* Cache for calls to addToStore(); maps source paths to the store paths. */ - Sync> srcToStore; + boost::concurrent_flat_map> srcToStore; /** * A cache from path names to parse trees. */ - typedef std::unordered_map< + typedef boost::unordered_flat_map< SourcePath, Expr *, std::hash, @@ -455,7 +457,7 @@ private: /** * A cache from path names to values. */ - typedef std::unordered_map< + typedef boost::unordered_flat_map< SourcePath, Value, std::hash, @@ -468,11 +470,11 @@ private: * Associate source positions of certain AST nodes with their preceding doc comment, if they have one. * Grouped by file. */ - std::unordered_map positionToDocComment; + boost::unordered_flat_map> positionToDocComment; LookupPath lookupPath; - std::map> lookupPathResolved; + boost::unordered_flat_map> lookupPathResolved; /** * Cache used by prim_match(). @@ -746,7 +748,7 @@ public: /** * Internal primops not exposed to the user. */ - std::unordered_map< + boost::unordered_flat_map< std::string, Value *, std::hash, @@ -1017,10 +1019,10 @@ private: bool countCalls; - typedef std::map PrimOpCalls; + typedef boost::unordered_flat_map PrimOpCalls; PrimOpCalls primOpCalls; - typedef std::map FunctionCalls; + typedef boost::unordered_flat_map FunctionCalls; FunctionCalls functionCalls; /** Evaluation/call profiler. */ @@ -1028,7 +1030,7 @@ private: void incrFunctionCall(ExprLambda * fun); - typedef std::map AttrSelects; + typedef boost::unordered_flat_map> AttrSelects; AttrSelects attrSelects; friend struct ExprOpUpdate; diff --git a/src/libexpr/include/nix/expr/parser-state.hh b/src/libexpr/include/nix/expr/parser-state.hh index 836cc9861..e689678de 100644 --- a/src/libexpr/include/nix/expr/parser-state.hh +++ b/src/libexpr/include/nix/expr/parser-state.hh @@ -71,7 +71,7 @@ struct LexerState /** * @brief Maps some positions to a DocComment, where the comment is relevant to the location. */ - std::unordered_map & positionToDocComment; + DocCommentMap & positionToDocComment; PosTable & positions; PosTable::Origin origin; diff --git a/src/libexpr/include/nix/expr/value.hh b/src/libexpr/include/nix/expr/value.hh index 82db1a775..d3aeac157 100644 --- a/src/libexpr/include/nix/expr/value.hh +++ b/src/libexpr/include/nix/expr/value.hh @@ -12,6 +12,7 @@ #include "nix/expr/print-options.hh" #include "nix/util/checked-arithmetic.hh" +#include #include namespace nix { @@ -1166,7 +1167,7 @@ void Value::mkBlackhole() } typedef std::vector> ValueVector; -typedef std::unordered_map< +typedef boost::unordered_flat_map< Symbol, Value *, std::hash, diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 35fe929d9..89da001ef 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -57,7 +57,7 @@ namespace nix { -typedef std::unordered_map DocCommentMap; +typedef boost::unordered_flat_map> DocCommentMap; Expr * parseExprFromBuf( char * text, diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 9ba417c32..c107c6bc2 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -18,6 +18,8 @@ #include "nix/util/sort.hh" #include +#include +#include #include #include @@ -1750,7 +1752,7 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName read them later. */ { auto h = hashDerivationModulo(*state.store, drv, false); - drvHashes.lock()->insert_or_assign(drvPath, h); + drvHashes.insert_or_assign(drvPath, std::move(h)); } auto result = state.buildBindings(1 + drv.outputs.size()); @@ -4027,7 +4029,7 @@ static void prim_groupBy(EvalState & state, const PosIdx pos, Value ** args, Val auto name = state.forceStringNoCtx( res, pos, "while evaluating the return value of the grouping function passed to builtins.groupBy"); auto sym = state.symbols.create(name); - auto vector = attrs.try_emplace(sym, ValueVector()).first; + auto vector = attrs.try_emplace(sym, {}).first; vector->second.push_back(vElem); } @@ -4562,27 +4564,19 @@ static RegisterPrimOp primop_convertHash({ struct RegexCache { - struct State - { - std::unordered_map> cache; - }; - - Sync state_; + boost::concurrent_flat_map> cache; std::regex get(std::string_view re) { - auto state(state_.lock()); - auto it = state->cache.find(re); - if (it != state->cache.end()) - return it->second; + std::regex regex; /* No std::regex constructor overload from std::string_view, but can be constructed from a pointer + size or an iterator range. */ - return state->cache - .emplace( - std::piecewise_construct, - std::forward_as_tuple(re), - std::forward_as_tuple(/*s=*/re.data(), /*count=*/re.size(), std::regex::extended)) - .first->second; + cache.try_emplace_and_cvisit(re, + /*s=*/re.data(), /*count=*/re.size(), std::regex::extended, + [®ex](const auto & kv) { regex = kv.second; }, + [®ex](const auto & kv) { regex = kv.second; } + ); + return regex; } }; @@ -4826,7 +4820,7 @@ static void prim_replaceStrings(EvalState & state, const PosIdx pos, Value ** ar from.emplace_back(state.forceString( *elem, pos, "while evaluating one of the strings to replace passed to builtins.replaceStrings")); - std::unordered_map cache; + boost::unordered_flat_map cache; auto to = args[1]->listView(); NixStringContext context;