mirror of
https://github.com/NixOS/nix.git
synced 2025-11-09 12:06:01 +01:00
libexpr: replace std::unordered_* types by faster boost hash maps
This commit is contained in:
parent
c0fd9146d6
commit
4f8c50fb77
6 changed files with 42 additions and 45 deletions
|
|
@ -1090,7 +1090,9 @@ void EvalState::evalFile(const SourcePath & path, Value & v, bool mustBeTrivial)
|
||||||
void EvalState::resetFileCache()
|
void EvalState::resetFileCache()
|
||||||
{
|
{
|
||||||
fileEvalCache.clear();
|
fileEvalCache.clear();
|
||||||
|
fileEvalCache.rehash(0);
|
||||||
fileParseCache.clear();
|
fileParseCache.clear();
|
||||||
|
fileParseCache.rehash(0);
|
||||||
inputCache->clear();
|
inputCache->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2375,10 +2377,9 @@ StorePath EvalState::copyPathToStore(NixStringContext & context, const SourcePat
|
||||||
if (nix::isDerivation(path.path.abs()))
|
if (nix::isDerivation(path.path.abs()))
|
||||||
error<EvalError>("file names are not allowed to end in '%1%'", drvExtension).debugThrow();
|
error<EvalError>("file names are not allowed to end in '%1%'", drvExtension).debugThrow();
|
||||||
|
|
||||||
auto dstPathCached = get(*srcToStore.lock(), path);
|
std::optional<StorePath> dstPath;
|
||||||
|
if (!srcToStore.cvisit(path, [&dstPath](const auto & kv) { dstPath.emplace(kv.second); })) {
|
||||||
auto dstPath = dstPathCached ? *dstPathCached : [&]() {
|
dstPath.emplace(fetchToStore(
|
||||||
auto dstPath = fetchToStore(
|
|
||||||
fetchSettings,
|
fetchSettings,
|
||||||
*store,
|
*store,
|
||||||
path.resolveSymlinks(SymlinkResolution::Ancestors),
|
path.resolveSymlinks(SymlinkResolution::Ancestors),
|
||||||
|
|
@ -2386,15 +2387,14 @@ StorePath EvalState::copyPathToStore(NixStringContext & context, const SourcePat
|
||||||
path.baseName(),
|
path.baseName(),
|
||||||
ContentAddressMethod::Raw::NixArchive,
|
ContentAddressMethod::Raw::NixArchive,
|
||||||
nullptr,
|
nullptr,
|
||||||
repair);
|
repair));
|
||||||
allowPath(dstPath);
|
allowPath(*dstPath);
|
||||||
srcToStore.lock()->try_emplace(path, dstPath);
|
srcToStore.try_emplace(path, *dstPath);
|
||||||
printMsg(lvlChatty, "copied source '%1%' -> '%2%'", path, store->printStorePath(dstPath));
|
printMsg(lvlChatty, "copied source '%1%' -> '%2%'", path, store->printStorePath(*dstPath));
|
||||||
return dstPath;
|
}
|
||||||
}();
|
|
||||||
|
|
||||||
context.insert(NixStringContextElem::Opaque{.path = dstPath});
|
context.insert(NixStringContextElem::Opaque{.path = *dstPath});
|
||||||
return dstPath;
|
return *dstPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
SourcePath EvalState::coerceToPath(const PosIdx pos, Value & v, NixStringContext & context, std::string_view errorCtx)
|
SourcePath EvalState::coerceToPath(const PosIdx pos, Value & v, NixStringContext & context, std::string_view errorCtx)
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
// For `NIX_USE_BOEHMGC`, and if that's set, `GC_THREADS`
|
// For `NIX_USE_BOEHMGC`, and if that's set, `GC_THREADS`
|
||||||
#include "nix/expr/config.hh"
|
#include "nix/expr/config.hh"
|
||||||
|
|
||||||
|
#include <boost/unordered/concurrent_flat_map.hpp>
|
||||||
|
#include <boost/unordered/unordered_flat_map.hpp>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
@ -162,7 +164,7 @@ typedef std::
|
||||||
map<std::string, Value *, std::less<std::string>, traceable_allocator<std::pair<const std::string, Value *>>>
|
map<std::string, Value *, std::less<std::string>, traceable_allocator<std::pair<const std::string, Value *>>>
|
||||||
ValMap;
|
ValMap;
|
||||||
|
|
||||||
typedef std::unordered_map<PosIdx, DocComment> DocCommentMap;
|
typedef boost::unordered_flat_map<PosIdx, DocComment, std::hash<PosIdx>> DocCommentMap;
|
||||||
|
|
||||||
struct Env
|
struct Env
|
||||||
{
|
{
|
||||||
|
|
@ -395,7 +397,7 @@ public:
|
||||||
bool inDebugger = false;
|
bool inDebugger = false;
|
||||||
int trylevel;
|
int trylevel;
|
||||||
std::list<DebugTrace> debugTraces;
|
std::list<DebugTrace> debugTraces;
|
||||||
std::map<const Expr *, const std::shared_ptr<const StaticEnv>> exprEnvs;
|
boost::unordered_flat_map<const Expr *, const std::shared_ptr<const StaticEnv>> exprEnvs;
|
||||||
|
|
||||||
const std::shared_ptr<const StaticEnv> getStaticEnv(const Expr & expr) const
|
const std::shared_ptr<const StaticEnv> getStaticEnv(const Expr & expr) const
|
||||||
{
|
{
|
||||||
|
|
@ -438,12 +440,12 @@ private:
|
||||||
|
|
||||||
/* Cache for calls to addToStore(); maps source paths to the store
|
/* Cache for calls to addToStore(); maps source paths to the store
|
||||||
paths. */
|
paths. */
|
||||||
Sync<std::unordered_map<SourcePath, StorePath>> srcToStore;
|
boost::concurrent_flat_map<SourcePath, StorePath, std::hash<SourcePath>> srcToStore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A cache from path names to parse trees.
|
* A cache from path names to parse trees.
|
||||||
*/
|
*/
|
||||||
typedef std::unordered_map<
|
typedef boost::unordered_flat_map<
|
||||||
SourcePath,
|
SourcePath,
|
||||||
Expr *,
|
Expr *,
|
||||||
std::hash<SourcePath>,
|
std::hash<SourcePath>,
|
||||||
|
|
@ -455,7 +457,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* A cache from path names to values.
|
* A cache from path names to values.
|
||||||
*/
|
*/
|
||||||
typedef std::unordered_map<
|
typedef boost::unordered_flat_map<
|
||||||
SourcePath,
|
SourcePath,
|
||||||
Value,
|
Value,
|
||||||
std::hash<SourcePath>,
|
std::hash<SourcePath>,
|
||||||
|
|
@ -468,11 +470,11 @@ private:
|
||||||
* Associate source positions of certain AST nodes with their preceding doc comment, if they have one.
|
* Associate source positions of certain AST nodes with their preceding doc comment, if they have one.
|
||||||
* Grouped by file.
|
* Grouped by file.
|
||||||
*/
|
*/
|
||||||
std::unordered_map<SourcePath, DocCommentMap> positionToDocComment;
|
boost::unordered_flat_map<SourcePath, DocCommentMap, std::hash<SourcePath>> positionToDocComment;
|
||||||
|
|
||||||
LookupPath lookupPath;
|
LookupPath lookupPath;
|
||||||
|
|
||||||
std::map<std::string, std::optional<SourcePath>> lookupPathResolved;
|
boost::unordered_flat_map<std::string, std::optional<SourcePath>> lookupPathResolved;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache used by prim_match().
|
* Cache used by prim_match().
|
||||||
|
|
@ -746,7 +748,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Internal primops not exposed to the user.
|
* Internal primops not exposed to the user.
|
||||||
*/
|
*/
|
||||||
std::unordered_map<
|
boost::unordered_flat_map<
|
||||||
std::string,
|
std::string,
|
||||||
Value *,
|
Value *,
|
||||||
std::hash<std::string>,
|
std::hash<std::string>,
|
||||||
|
|
@ -1017,10 +1019,10 @@ private:
|
||||||
|
|
||||||
bool countCalls;
|
bool countCalls;
|
||||||
|
|
||||||
typedef std::map<std::string, size_t> PrimOpCalls;
|
typedef boost::unordered_flat_map<std::string, size_t> PrimOpCalls;
|
||||||
PrimOpCalls primOpCalls;
|
PrimOpCalls primOpCalls;
|
||||||
|
|
||||||
typedef std::map<ExprLambda *, size_t> FunctionCalls;
|
typedef boost::unordered_flat_map<ExprLambda *, size_t> FunctionCalls;
|
||||||
FunctionCalls functionCalls;
|
FunctionCalls functionCalls;
|
||||||
|
|
||||||
/** Evaluation/call profiler. */
|
/** Evaluation/call profiler. */
|
||||||
|
|
@ -1028,7 +1030,7 @@ private:
|
||||||
|
|
||||||
void incrFunctionCall(ExprLambda * fun);
|
void incrFunctionCall(ExprLambda * fun);
|
||||||
|
|
||||||
typedef std::map<PosIdx, size_t> AttrSelects;
|
typedef boost::unordered_flat_map<PosIdx, size_t, std::hash<PosIdx>> AttrSelects;
|
||||||
AttrSelects attrSelects;
|
AttrSelects attrSelects;
|
||||||
|
|
||||||
friend struct ExprOpUpdate;
|
friend struct ExprOpUpdate;
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ struct LexerState
|
||||||
/**
|
/**
|
||||||
* @brief Maps some positions to a DocComment, where the comment is relevant to the location.
|
* @brief Maps some positions to a DocComment, where the comment is relevant to the location.
|
||||||
*/
|
*/
|
||||||
std::unordered_map<PosIdx, DocComment> & positionToDocComment;
|
DocCommentMap & positionToDocComment;
|
||||||
|
|
||||||
PosTable & positions;
|
PosTable & positions;
|
||||||
PosTable::Origin origin;
|
PosTable::Origin origin;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#include "nix/expr/print-options.hh"
|
#include "nix/expr/print-options.hh"
|
||||||
#include "nix/util/checked-arithmetic.hh"
|
#include "nix/util/checked-arithmetic.hh"
|
||||||
|
|
||||||
|
#include <boost/unordered/unordered_flat_map_fwd.hpp>
|
||||||
#include <nlohmann/json_fwd.hpp>
|
#include <nlohmann/json_fwd.hpp>
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
@ -1166,7 +1167,7 @@ void Value::mkBlackhole()
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::vector<Value *, traceable_allocator<Value *>> ValueVector;
|
typedef std::vector<Value *, traceable_allocator<Value *>> ValueVector;
|
||||||
typedef std::unordered_map<
|
typedef boost::unordered_flat_map<
|
||||||
Symbol,
|
Symbol,
|
||||||
Value *,
|
Value *,
|
||||||
std::hash<Symbol>,
|
std::hash<Symbol>,
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
typedef std::unordered_map<PosIdx, DocComment> DocCommentMap;
|
typedef boost::unordered_flat_map<PosIdx, DocComment, std::hash<PosIdx>> DocCommentMap;
|
||||||
|
|
||||||
Expr * parseExprFromBuf(
|
Expr * parseExprFromBuf(
|
||||||
char * text,
|
char * text,
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
#include "nix/util/sort.hh"
|
#include "nix/util/sort.hh"
|
||||||
|
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
|
#include <boost/unordered/concurrent_flat_map.hpp>
|
||||||
|
#include <boost/unordered/unordered_flat_map.hpp>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
@ -1750,7 +1752,7 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName
|
||||||
read them later. */
|
read them later. */
|
||||||
{
|
{
|
||||||
auto h = hashDerivationModulo(*state.store, drv, false);
|
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());
|
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(
|
auto name = state.forceStringNoCtx(
|
||||||
res, pos, "while evaluating the return value of the grouping function passed to builtins.groupBy");
|
res, pos, "while evaluating the return value of the grouping function passed to builtins.groupBy");
|
||||||
auto sym = state.symbols.create(name);
|
auto sym = state.symbols.create(name);
|
||||||
auto vector = attrs.try_emplace(sym, ValueVector()).first;
|
auto vector = attrs.try_emplace<ValueVector>(sym, {}).first;
|
||||||
vector->second.push_back(vElem);
|
vector->second.push_back(vElem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4562,27 +4564,19 @@ static RegisterPrimOp primop_convertHash({
|
||||||
|
|
||||||
struct RegexCache
|
struct RegexCache
|
||||||
{
|
{
|
||||||
struct State
|
boost::concurrent_flat_map<std::string, std::regex, StringViewHash, std::equal_to<>> cache;
|
||||||
{
|
|
||||||
std::unordered_map<std::string, std::regex, StringViewHash, std::equal_to<>> cache;
|
|
||||||
};
|
|
||||||
|
|
||||||
Sync<State> state_;
|
|
||||||
|
|
||||||
std::regex get(std::string_view re)
|
std::regex get(std::string_view re)
|
||||||
{
|
{
|
||||||
auto state(state_.lock());
|
std::regex regex;
|
||||||
auto it = state->cache.find(re);
|
|
||||||
if (it != state->cache.end())
|
|
||||||
return it->second;
|
|
||||||
/* No std::regex constructor overload from std::string_view, but can be constructed
|
/* No std::regex constructor overload from std::string_view, but can be constructed
|
||||||
from a pointer + size or an iterator range. */
|
from a pointer + size or an iterator range. */
|
||||||
return state->cache
|
cache.try_emplace_and_cvisit(re,
|
||||||
.emplace(
|
/*s=*/re.data(), /*count=*/re.size(), std::regex::extended,
|
||||||
std::piecewise_construct,
|
[®ex](const auto & kv) { regex = kv.second; },
|
||||||
std::forward_as_tuple(re),
|
[®ex](const auto & kv) { regex = kv.second; }
|
||||||
std::forward_as_tuple(/*s=*/re.data(), /*count=*/re.size(), std::regex::extended))
|
);
|
||||||
.first->second;
|
return regex;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -4826,7 +4820,7 @@ static void prim_replaceStrings(EvalState & state, const PosIdx pos, Value ** ar
|
||||||
from.emplace_back(state.forceString(
|
from.emplace_back(state.forceString(
|
||||||
*elem, pos, "while evaluating one of the strings to replace passed to builtins.replaceStrings"));
|
*elem, pos, "while evaluating one of the strings to replace passed to builtins.replaceStrings"));
|
||||||
|
|
||||||
std::unordered_map<size_t, std::string_view> cache;
|
boost::unordered_flat_map<size_t, std::string_view> cache;
|
||||||
auto to = args[1]->listView();
|
auto to = args[1]->listView();
|
||||||
|
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue