pathInfoCache: Respect disk cache TTLs #3398

This commit is contained in:
Robert Hensing 2020-03-11 20:04:47 +01:00
parent 9080d5d924
commit 3f55f8a8fb
4 changed files with 39 additions and 11 deletions

View file

@ -106,7 +106,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 { .value = std::shared_ptr<NarInfo>(narInfo) });
} }
if (diskCache) if (diskCache)

View file

@ -622,7 +622,8 @@ uint64_t LocalStore::addValidPath(State & state,
{ {
auto state_(Store::state.lock()); auto state_(Store::state.lock());
state_->pathInfoCache.upsert(storePathToHash(printStorePath(info.path)), std::make_shared<ValidPathInfo>(info)); state_->pathInfoCache.upsert(storePathToHash(printStorePath(info.path)),
PathInfoCacheValue{ .value = std::make_shared<const ValidPathInfo>(info) });
} }
return id; return id;

View file

@ -226,6 +226,14 @@ 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 StorePath & storePath) bool Store::isValidPath(const StorePath & storePath)
{ {
@ -234,9 +242,9 @@ bool Store::isValidPath(const StorePath & 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();
} }
} }
@ -246,7 +254,7 @@ bool Store::isValidPath(const StorePath & 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 ? PathInfoCacheValue{} : PathInfoCacheValue { .value = res.second });
return res.first == NarInfoDiskCache::oValid; return res.first == NarInfoDiskCache::oValid;
} }
} }
@ -301,11 +309,11 @@ void Store::queryPathInfo(const StorePath & 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("path '%s' is not valid", printStorePath(storePath)); throw InvalidPath("path '%s' is not valid", printStorePath(storePath));
return callback(ref<const ValidPathInfo>(*res)); return callback(ref<const ValidPathInfo>(res->value));
} }
} }
@ -316,7 +324,7 @@ void Store::queryPathInfo(const StorePath & 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 ? PathInfoCacheValue{} : PathInfoCacheValue{ .value = res.second });
if (res.first == NarInfoDiskCache::oInvalid || if (res.first == NarInfoDiskCache::oInvalid ||
res.second->path != storePath) res.second->path != storePath)
throw InvalidPath("path '%s' is not valid", printStorePath(storePath)); throw InvalidPath("path '%s' is not valid", printStorePath(storePath));
@ -340,7 +348,7 @@ void Store::queryPathInfo(const StorePath & storePath,
{ {
auto state_(state.lock()); auto state_(state.lock());
state_->pathInfoCache.upsert(hashPart, info); state_->pathInfoCache.upsert(hashPart, PathInfoCacheValue { .value = info });
} }
if (!info || info->path != parseStorePath(storePath)) { if (!info || info->path != parseStorePath(storePath)) {

View file

@ -16,6 +16,7 @@
#include <unordered_set> #include <unordered_set>
#include <memory> #include <memory>
#include <string> #include <string>
#include <chrono>
namespace nix { namespace nix {
@ -261,10 +262,28 @@ public:
protected: protected:
struct PathInfoCacheValue {
// Time of cache entry creation or update
std::chrono::time_point<std::chrono::steady_clock> time_point = std::chrono::steady_clock::now();
// Null if missing
std::shared_ptr<const 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 != nullptr;
}
};
struct State struct State
{ {
// FIXME: fix key // FIXME: fix key
LRUCache<std::string, std::shared_ptr<const ValidPathInfo>> pathInfoCache; LRUCache<std::string, PathInfoCacheValue> pathInfoCache;
}; };
Sync<State> state; Sync<State> state;