diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2020-03-13 17:03:30 +0100 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2020-03-13 17:03:30 +0100 |
commit | 0c2088d4386a350f0005ff1a278d0384dbc26881 (patch) | |
tree | 20e36c571123b315441552d34ce8ee1213dbf0fa /src/libstore | |
parent | ae9119167ebb24c95e8e45e12889ea147926ceb7 (diff) | |
parent | eab7d790a36ff0aa648321a39eaeaa4248755156 (diff) |
Merge remote-tracking branch 'origin/master' into flakes
Diffstat (limited to 'src/libstore')
-rw-r--r-- | src/libstore/binary-cache-store.cc | 2 | ||||
-rw-r--r-- | src/libstore/local-store.cc | 17 | ||||
-rw-r--r-- | src/libstore/store-api.cc | 24 | ||||
-rw-r--r-- | src/libstore/store-api.hh | 21 |
4 files changed, 47 insertions, 17 deletions
diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc index 717faec92..3a2d84861 100644 --- a/src/libstore/binary-cache-store.cc +++ b/src/libstore/binary-cache-store.cc @@ -106,7 +106,7 @@ void BinaryCacheStore::writeNarInfo(ref<NarInfo> narInfo) { 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) diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 2025af33e..ae7513ad8 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -615,7 +615,8 @@ uint64_t LocalStore::addValidPath(State & state, { 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; @@ -996,16 +997,18 @@ void LocalStore::addToStore(const ValidPathInfo & info, Source & source, deletePath(realPath); + if (info.ca != "" && + !((hasPrefix(info.ca, "text:") && !info.references.count(info.path)) + || info.references.empty())) + settings.requireExperimentalFeature("ca-references"); + /* While restoring the path from the NAR, compute the hash of the NAR. */ std::unique_ptr<AbstractHashSink> hashSink; - if (info.ca == "") + if (info.ca == "" || !info.references.count(info.path)) hashSink = std::make_unique<HashSink>(htSHA256); - else { - if (!info.references.empty()) - settings.requireExperimentalFeature("ca-references"); + else hashSink = std::make_unique<HashModuloSink>(htSHA256, storePathToHash(printStorePath(info.path))); - } LambdaSource wrapperSource([&](unsigned char * data, size_t len) -> size_t { size_t n = source.read(data, len); @@ -1260,7 +1263,7 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) printMsg(lvlTalkative, "checking contents of '%s'", printStorePath(i)); std::unique_ptr<AbstractHashSink> hashSink; - if (info->ca == "") + if (info->ca == "" || !info->references.count(info->path)) hashSink = std::make_unique<HashSink>(info->narHash.type); else hashSink = std::make_unique<HashModuloSink>(info->narHash.type, storePathToHash(printStorePath(info->path))); diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index eb17d5cd2..66a9d9fb5 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -227,6 +227,14 @@ std::string Store::getUri() 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) { @@ -235,9 +243,9 @@ bool Store::isValidPath(const StorePath & storePath) { auto state_(state.lock()); auto res = state_->pathInfoCache.get(hashPart); - if (res) { + if (res && res->isKnownNow()) { stats.narInfoReadAverted++; - return *res != 0; + return res->didExist(); } } @@ -247,7 +255,7 @@ bool Store::isValidPath(const StorePath & storePath) stats.narInfoReadAverted++; auto state_(state.lock()); 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; } } @@ -302,11 +310,11 @@ void Store::queryPathInfo(const StorePath & storePath, { auto res = state.lock()->pathInfoCache.get(hashPart); - if (res) { + if (res && res->isKnownNow()) { stats.narInfoReadAverted++; - if (!*res) + if (!res->didExist()) throw InvalidPath("path '%s' is not valid", printStorePath(storePath)); - return callback(ref<const ValidPathInfo>(*res)); + return callback(ref<const ValidPathInfo>(res->value)); } } @@ -317,7 +325,7 @@ void Store::queryPathInfo(const StorePath & storePath, { auto state_(state.lock()); 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 || res.second->path != storePath) throw InvalidPath("path '%s' is not valid", printStorePath(storePath)); @@ -341,7 +349,7 @@ void Store::queryPathInfo(const StorePath & storePath, { auto state_(state.lock()); - state_->pathInfoCache.upsert(hashPart, info); + state_->pathInfoCache.upsert(hashPart, PathInfoCacheValue { .value = info }); } if (!info || info->path != parseStorePath(storePath)) { diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 88cfa5b5a..81014763d 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -16,6 +16,7 @@ #include <unordered_set> #include <memory> #include <string> +#include <chrono> namespace nix { @@ -262,10 +263,28 @@ public: 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 { // FIXME: fix key - LRUCache<std::string, std::shared_ptr<const ValidPathInfo>> pathInfoCache; + LRUCache<std::string, PathInfoCacheValue> pathInfoCache; }; Sync<State> state; |