mirror of
https://github.com/NixOS/nix
synced 2025-07-08 11:03:54 +02:00
pathInfoCache: Respect disk cache TTLs #3398
This commit is contained in:
parent
2097983218
commit
d549250069
4 changed files with 50 additions and 10 deletions
|
@ -104,7 +104,7 @@ void BinaryCacheStore::writeNarInfo(ref<NarInfo> narInfo)
|
||||||
|
|
||||||
{
|
{
|
||||||
auto state_(state.lock());
|
auto state_(state.lock());
|
||||||
state_->pathInfoCache.upsert(hashPart, std::shared_ptr<NarInfo>(narInfo));
|
state_->pathInfoCache.upsert(hashPart, PathInfoCacheValue(std::shared_ptr<NarInfo>(narInfo)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (diskCache)
|
if (diskCache)
|
||||||
|
|
|
@ -623,7 +623,7 @@ uint64_t LocalStore::addValidPath(State & state,
|
||||||
|
|
||||||
{
|
{
|
||||||
auto state_(Store::state.lock());
|
auto state_(Store::state.lock());
|
||||||
state_->pathInfoCache.upsert(storePathToHash(info.path), std::make_shared<ValidPathInfo>(info));
|
state_->pathInfoCache.upsert(storePathToHash(info.path), PathInfoCacheValue(info));
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
|
|
|
@ -261,6 +261,15 @@ std::string Store::getUri()
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Store::PathInfoCacheValue::isKnownNow()
|
||||||
|
{
|
||||||
|
std::chrono::duration ttl = didExist()
|
||||||
|
? std::chrono::seconds(settings.ttlPositiveNarInfoCache)
|
||||||
|
: std::chrono::seconds(settings.ttlNegativeNarInfoCache);
|
||||||
|
|
||||||
|
return std::chrono::steady_clock::now() < time_point + ttl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Store::isValidPath(const Path & storePath)
|
bool Store::isValidPath(const Path & storePath)
|
||||||
{
|
{
|
||||||
|
@ -271,9 +280,9 @@ bool Store::isValidPath(const Path & storePath)
|
||||||
{
|
{
|
||||||
auto state_(state.lock());
|
auto state_(state.lock());
|
||||||
auto res = state_->pathInfoCache.get(hashPart);
|
auto res = state_->pathInfoCache.get(hashPart);
|
||||||
if (res) {
|
if (res && res->isKnownNow()) {
|
||||||
stats.narInfoReadAverted++;
|
stats.narInfoReadAverted++;
|
||||||
return *res != 0;
|
return res->didExist();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,7 +292,7 @@ bool Store::isValidPath(const Path & storePath)
|
||||||
stats.narInfoReadAverted++;
|
stats.narInfoReadAverted++;
|
||||||
auto state_(state.lock());
|
auto state_(state.lock());
|
||||||
state_->pathInfoCache.upsert(hashPart,
|
state_->pathInfoCache.upsert(hashPart,
|
||||||
res.first == NarInfoDiskCache::oInvalid ? 0 : res.second);
|
res.first == NarInfoDiskCache::oInvalid ? 0 : PathInfoCacheValue(res.second));
|
||||||
return res.first == NarInfoDiskCache::oValid;
|
return res.first == NarInfoDiskCache::oValid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,11 +349,11 @@ void Store::queryPathInfo(const Path & storePath,
|
||||||
|
|
||||||
{
|
{
|
||||||
auto res = state.lock()->pathInfoCache.get(hashPart);
|
auto res = state.lock()->pathInfoCache.get(hashPart);
|
||||||
if (res) {
|
if (res && res->isKnownNow()) {
|
||||||
stats.narInfoReadAverted++;
|
stats.narInfoReadAverted++;
|
||||||
if (!*res)
|
if (!res->didExist())
|
||||||
throw InvalidPath(format("path '%s' is not valid") % storePath);
|
throw InvalidPath(format("path '%s' is not valid") % storePath);
|
||||||
return callback(ref<ValidPathInfo>(*res));
|
return callback(ref<ValidPathInfo>(res->value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,7 +364,7 @@ void Store::queryPathInfo(const Path & storePath,
|
||||||
{
|
{
|
||||||
auto state_(state.lock());
|
auto state_(state.lock());
|
||||||
state_->pathInfoCache.upsert(hashPart,
|
state_->pathInfoCache.upsert(hashPart,
|
||||||
res.first == NarInfoDiskCache::oInvalid ? 0 : res.second);
|
res.first == NarInfoDiskCache::oInvalid ? 0 : PathInfoCacheValue(res.second));
|
||||||
if (res.first == NarInfoDiskCache::oInvalid ||
|
if (res.first == NarInfoDiskCache::oInvalid ||
|
||||||
(res.second->path != storePath && storePathToName(storePath) != ""))
|
(res.second->path != storePath && storePathToName(storePath) != ""))
|
||||||
throw InvalidPath(format("path '%s' is not valid") % storePath);
|
throw InvalidPath(format("path '%s' is not valid") % storePath);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
@ -256,9 +257,39 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
struct PathInfoCacheValue {
|
||||||
|
|
||||||
|
PathInfoCacheValue(std::shared_ptr<ValidPathInfo> value) :
|
||||||
|
time_point(std::chrono::steady_clock::now()),
|
||||||
|
value(value) {}
|
||||||
|
|
||||||
|
// Convenience constructor copying from reference
|
||||||
|
PathInfoCacheValue(const ValidPathInfo& value) :
|
||||||
|
PathInfoCacheValue(std::make_shared<ValidPathInfo>(value)) {}
|
||||||
|
|
||||||
|
// Record a missing path
|
||||||
|
PathInfoCacheValue(std::nullptr_t nil) :
|
||||||
|
PathInfoCacheValue(std::shared_ptr<ValidPathInfo>()) {}
|
||||||
|
|
||||||
|
// Time of cache entry creation or update(?)
|
||||||
|
std::chrono::time_point<std::chrono::steady_clock> time_point;
|
||||||
|
|
||||||
|
// Null if missing
|
||||||
|
std::shared_ptr<ValidPathInfo> value;
|
||||||
|
|
||||||
|
// Whether the value is valid as a cache entry. The path may not exist.
|
||||||
|
bool isKnownNow();
|
||||||
|
|
||||||
|
// Past tense, because a path can only be assumed to exists when
|
||||||
|
// isKnownNow() && didExist()
|
||||||
|
inline bool didExist() {
|
||||||
|
return value != 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct State
|
struct State
|
||||||
{
|
{
|
||||||
LRUCache<std::string, std::shared_ptr<ValidPathInfo>> pathInfoCache;
|
LRUCache<std::string, PathInfoCacheValue> pathInfoCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
Sync<State> state;
|
Sync<State> state;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue