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, EvalState & state,
std::shared_ptr<flake::LockedFlake> lockedFlake) std::shared_ptr<flake::LockedFlake> lockedFlake)
{ {
auto fingerprint = lockedFlake->getFingerprint(); auto fingerprint = lockedFlake->getFingerprint(state.store);
return make_ref<nix::eval_cache::EvalCache>( return make_ref<nix::eval_cache::EvalCache>(
#if 0
evalSettings.useEvalCache && evalSettings.pureEval evalSettings.useEvalCache && evalSettings.pureEval
? std::optional { std::cref(fingerprint) } ? fingerprint
: : std::nullopt,
#endif
std::nullopt,
state, state,
[&state, lockedFlake]() [&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 // FIXME: as an optimization, if the flake contains a lock file
// and we haven't changed it, then it's sufficient to use // and we haven't changed it, then it's sufficient to use
// flake.sourceInfo.storePath for the fingerprint. // flake.sourceInfo.storePath for the fingerprint.
return hashString(htSHA256, return hashString(htSHA256, fmt("%s;%s;%s", *fingerprint, flake.lockedRef.subdir, lockFile));
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));
} }
Flake::~Flake() { } Flake::~Flake() { }

View file

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

View file

@ -289,6 +289,14 @@ std::optional<time_t> Input::getLastModified() const
return {}; 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) ParsedURL InputScheme::toURL(const Input & input)
{ {
throw Error("don't know how to convert input '%s' to a URL", attrsToJSON(input.attrs)); 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<uint64_t> getRevCount() const;
std::optional<time_t> getLastModified() 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: private:
void checkLocked(Store & store, const StorePath & storePath, Input & input) const; void checkLocked(Store & store, const StorePath & storePath, Input & input) const;
@ -156,6 +160,9 @@ struct InputScheme
virtual bool isRelative(const Input & input) const virtual bool isRelative(const Input & input) const
{ return false; } { 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); void registerInputScheme(std::shared_ptr<InputScheme> && fetcher);

View file

@ -86,13 +86,14 @@ struct PathInputScheme : InputScheme
// nothing to do // 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"); auto path = getStrAttr(input.attrs, "path");
if (path[0] == '/') if (path[0] == '/')
return CanonPath(path); return CanonPath(path);
// FIXME: remove this?
if (!input.parent) if (!input.parent)
throw Error("cannot fetch input '%s' because it uses a relative path", input.to_string()); 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()); input2.attrs.emplace("path", (std::string) absPath.abs());
return {makeFSInputAccessor(absPath), std::move(input2)}; 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>()); }); static auto rPathInputScheme = OnStartup([] { registerInputScheme(std::make_unique<PathInputScheme>()); });