1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-25 19:51:00 +01:00

Add a session independent cache.

This commit is contained in:
Nicolas Pierron 2009-07-08 09:26:15 +00:00
parent 7244b9b861
commit 4941ba3413
3 changed files with 36 additions and 7 deletions

View file

@ -16,9 +16,9 @@ namespace nix {
EvalState::EvalState()
: normalForms(32768), primOps(128)
: sessionNormalForms(32768), normalForms(32768), primOps(128)
{
nrEvaluated = nrCached = 0;
nrEvaluated = nrCached = nrDephtAfterReset = 0;
initNixExprHelpers();
@ -803,10 +803,17 @@ Expr evalExpr(EvalState & state, Expr e)
#endif
state.nrEvaluated++;
state.nrDephtAfterReset++;
/* Consult the memo table to quickly get the normal form of
previously evaluated expressions. */
Expr nf = state.normalForms.get(e);
if (nf) {
state.nrCached++;
return nf;
}
nf = state.sessionNormalForms.get(e);
if (nf) {
if (nf == makeBlackHole())
throwEvalError("infinite recursion encountered");
@ -815,14 +822,22 @@ Expr evalExpr(EvalState & state, Expr e)
}
/* Otherwise, evaluate and memoize. */
state.normalForms.set(e, makeBlackHole());
state.sessionNormalForms.set(e, makeBlackHole());
try {
nf = evalExpr2(state, e);
} catch (Error & err) {
state.normalForms.remove(e);
state.sessionNormalForms.remove(e);
throw;
}
state.normalForms.set(e, nf);
if (state.nrDephtAfterReset) {
state.sessionNormalForms.remove(e);
state.normalForms.set(e, nf);
state.nrDephtAfterReset--;
} else {
state.sessionNormalForms.set(e, nf);
}
return nf;
}
@ -830,6 +845,7 @@ Expr evalExpr(EvalState & state, Expr e)
Expr evalFile(EvalState & state, const Path & path)
{
startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path);
state.nrDephtAfterReset = 0;
Expr e = parseExprFromFile(state, path);
try {
return evalExpr(state, e);
@ -901,11 +917,13 @@ void printEvalStats(EvalState & state)
char x;
bool showStats = getEnv("NIX_SHOW_STATS", "0") != "0";
printMsg(showStats ? lvlInfo : lvlDebug,
format("evaluated %1% expressions, %2% cache hits, %3%%% efficiency, used %4% ATerm bytes, used %5% bytes of stack space")
format("evaluated %1% expressions, %2% cache hits, %3%%% efficiency, used %4% ATerm bytes, used %5% bytes of stack space, %6% normal reduction, %7% session dependent reduction.")
% state.nrEvaluated % state.nrCached
% ((float) state.nrCached / (float) state.nrEvaluated * 100)
% AT_calcAllocatedSize()
% (&x - deepestStack));
% (&x - deepestStack)
% state.normalForms.size()
% state.sessionNormalForms.size());
if (showStats)
printATermMapStats();
}

View file

@ -29,6 +29,7 @@ typedef Expr (* PrimOp) (EvalState &, const ATermVector & args);
struct EvalState
{
ATermMap sessionNormalForms;
ATermMap normalForms;
ATermMap primOps;
DrvRoots drvRoots;
@ -37,6 +38,7 @@ struct EvalState
unsigned int nrEvaluated;
unsigned int nrCached;
unsigned int nrDephtAfterReset;
bool allowUnsafeEquality;

View file

@ -74,12 +74,14 @@ static Expr prim_null(EvalState & state, const ATermVector & args)
platforms. */
static Expr prim_currentSystem(EvalState & state, const ATermVector & args)
{
state.nrDephtAfterReset = 0;
return makeStr(thisSystem);
}
static Expr prim_currentTime(EvalState & state, const ATermVector & args)
{
state.nrDephtAfterReset = 0;
return ATmake("Int(<int>)", time(0));
}
@ -228,6 +230,7 @@ static Expr prim_addErrorContext(EvalState & state, const ATermVector & args)
static Expr prim_getEnv(EvalState & state, const ATermVector & args)
{
string name = evalStringNoCtx(state, args[0]);
state.nrDephtAfterReset = 0;
return makeStr(getEnv(name));
}
@ -316,6 +319,7 @@ static Hash hashDerivationModulo(EvalState & state, Derivation drv)
static Expr prim_derivationStrict(EvalState & state, const ATermVector & args)
{
startNest(nest, lvlVomit, "evaluating derivation");
state.nrDephtAfterReset = 0;
ATermMap attrs;
queryAllAttrs(evalExpr(state, args[0]), attrs, true);
@ -549,6 +553,7 @@ static Expr prim_storePath(EvalState & state, const ATermVector & args)
{
PathSet context;
Path path = canonPath(coerceToPath(state, args[0], context));
state.nrDephtAfterReset = 0;
if (!isInStore(path))
throw EvalError(format("path `%1%' is not in the Nix store") % path);
Path path2 = toStorePath(path);
@ -565,6 +570,7 @@ static Expr prim_pathExists(EvalState & state, const ATermVector & args)
Path path = coerceToPath(state, args[0], context);
if (!context.empty())
throw EvalError(format("string `%1%' cannot refer to other paths") % path);
state.nrDephtAfterReset = 0;
return makeBool(pathExists(path));
}
@ -598,6 +604,7 @@ static Expr prim_readFile(EvalState & state, const ATermVector & args)
Path path = coerceToPath(state, args[0], context);
if (!context.empty())
throw EvalError(format("string `%1%' cannot refer to other paths") % path);
state.nrDephtAfterReset = 0;
return makeStr(readFile(path));
}
@ -637,6 +644,7 @@ static Expr prim_toFile(EvalState & state, const ATermVector & args)
refs.insert(path);
}
state.nrDephtAfterReset = 0;
Path storePath = readOnlyMode
? computeStorePathForText(name, contents, refs)
: store->addTextToStore(name, contents, refs);
@ -689,6 +697,7 @@ static Expr prim_filterSource(EvalState & state, const ATermVector & args)
FilterFromExpr filter(state, args[0]);
state.nrDephtAfterReset = 0;
Path dstPath = readOnlyMode
? computeStorePathForPath(path, true, htSHA256, filter).first
: store->addToStore(path, true, htSHA256, filter);