Restore the evaluation cache

This commit is contained in:
Eelco Dolstra 2022-07-22 15:19:30 +02:00
parent c73a7584fb
commit 3d27ce36d0
6 changed files with 41 additions and 17 deletions

View file

@ -560,14 +560,11 @@ ref<eval_cache::EvalCache> openEvalCache(
EvalState & state,
std::shared_ptr<flake::LockedFlake> lockedFlake)
{
auto fingerprint = lockedFlake->getFingerprint();
auto fingerprint = lockedFlake->getFingerprint(state.store);
return make_ref<nix::eval_cache::EvalCache>(
#if 0
evalSettings.useEvalCache && evalSettings.pureEval
? std::optional { std::cref(fingerprint) }
:
#endif
std::nullopt,
? fingerprint
: std::nullopt,
state,
[&state, lockedFlake]()
{

View file

@ -772,19 +772,17 @@ static RegisterPrimOp r2({
}
Fingerprint LockedFlake::getFingerprint() const
std::optional<Fingerprint> LockedFlake::getFingerprint(ref<Store> store) const
{
if (lockFile.isUnlocked()) return std::nullopt;
auto fingerprint = flake.lockedRef.input.getFingerprint(store);
if (!fingerprint) return std::nullopt;
// FIXME: as an optimization, if the flake contains a lock file
// and we haven't changed it, then it's sufficient to use
// flake.sourceInfo.storePath for the fingerprint.
return hashString(htSHA256,
fmt("%s;%s;%d;%d;%s",
"FIXME",
//flake.sourceInfo->storePath.to_string(),
flake.lockedRef.subdir,
flake.lockedRef.input.getRevCount().value_or(0),
flake.lockedRef.input.getLastModified().value_or(0),
lockFile));
return hashString(htSHA256, fmt("%s;%s;%s", *fingerprint, flake.lockedRef.subdir, lockFile));
}
Flake::~Flake() { }

View file

@ -79,7 +79,7 @@ struct LockedFlake
Flake flake;
LockFile lockFile;
Fingerprint getFingerprint() const;
std::optional<Fingerprint> getFingerprint(ref<Store> store) const;
};
struct LockFlags

View file

@ -289,6 +289,14 @@ std::optional<time_t> Input::getLastModified() const
return {};
}
std::optional<std::string> Input::getFingerprint(ref<Store> store) const
{
if (auto rev = getRev())
return rev->gitRev();
assert(scheme);
return scheme->getFingerprint(store, *this);
}
ParsedURL InputScheme::toURL(const Input & input)
{
throw Error("don't know how to convert input '%s' to a URL", attrsToJSON(input.attrs));

View file

@ -104,6 +104,10 @@ public:
std::optional<uint64_t> getRevCount() const;
std::optional<time_t> getLastModified() const;
// For locked inputs, returns a string that uniquely specifies the
// content of the input (typically a commit hash or content hash).
std::optional<std::string> getFingerprint(ref<Store> store) const;
private:
void checkLocked(Store & store, const StorePath & storePath, Input & input) const;
@ -156,6 +160,9 @@ struct InputScheme
virtual bool isRelative(const Input & input) const
{ return false; }
virtual std::optional<std::string> getFingerprint(ref<Store> store, const Input & input) const
{ return std::nullopt; }
};
void registerInputScheme(std::shared_ptr<InputScheme> && fetcher);

View file

@ -86,13 +86,14 @@ struct PathInputScheme : InputScheme
// nothing to do
}
CanonPath getAbsPath(ref<Store> store, const Input & input)
CanonPath getAbsPath(ref<Store> store, const Input & input) const
{
auto path = getStrAttr(input.attrs, "path");
if (path[0] == '/')
return CanonPath(path);
// FIXME: remove this?
if (!input.parent)
throw Error("cannot fetch input '%s' because it uses a relative path", input.to_string());
@ -145,6 +146,19 @@ struct PathInputScheme : InputScheme
input2.attrs.emplace("path", (std::string) absPath.abs());
return {makeFSInputAccessor(absPath), std::move(input2)};
}
std::optional<std::string> getFingerprint(ref<Store> store, const Input & input) const override
{
/* If this path is in the Nix store, we can consider it
locked, so just use the path as its fingerprint. Maybe we
should restrict this to CA paths but that's not
super-important. */
auto path = getAbsPath(store, input);
if (store->isInStore(path.abs()))
return path.abs();
return std::nullopt;
}
};
static auto rPathInputScheme = OnStartup([] { registerInputScheme(std::make_unique<PathInputScheme>()); });