diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 0c37ecd30..66bc95625 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -685,6 +685,42 @@ static bool goodStorePath(const StorePath & expected, const StorePath & actual) && (expected.name() == Store::MissingName || expected.name() == actual.name()); } +bool Store::queryPathInfoFromClientCache(const StorePath & storePath, + Callback> & callback) +{ + auto hashPart = std::string(storePath.hashPart()); + + { + auto res = state.lock()->pathInfoCache.get(std::string(storePath.to_string())); + if (res && res->isKnownNow()) { + stats.narInfoReadAverted++; + if (!res->didExist()) + throw InvalidPath("path '%s' is not valid", printStorePath(storePath)); + callback(ref(res->value)); + return true; + } + } + + if (diskCache) { + auto res = diskCache->lookupNarInfo(getUri(), hashPart); + if (res.first != NarInfoDiskCache::oUnknown) { + stats.narInfoReadAverted++; + { + auto state_(state.lock()); + state_->pathInfoCache.upsert(std::string(storePath.to_string()), + res.first == NarInfoDiskCache::oInvalid ? PathInfoCacheValue{} : PathInfoCacheValue{ .value = res.second }); + if (res.first == NarInfoDiskCache::oInvalid || + !goodStorePath(storePath, res.second->path)) + throw InvalidPath("path '%s' is not valid", printStorePath(storePath)); + } + callback(ref(res.second)); + return true; + } + } + + return false; +} + void Store::queryPathInfo(const StorePath & storePath, Callback> callback) noexcept @@ -692,32 +728,8 @@ void Store::queryPathInfo(const StorePath & storePath, auto hashPart = std::string(storePath.hashPart()); try { - { - auto res = state.lock()->pathInfoCache.get(std::string(storePath.to_string())); - if (res && res->isKnownNow()) { - stats.narInfoReadAverted++; - if (!res->didExist()) - throw InvalidPath("path '%s' is not valid", printStorePath(storePath)); - return callback(ref(res->value)); - } - } - - if (diskCache) { - auto res = diskCache->lookupNarInfo(getUri(), hashPart); - if (res.first != NarInfoDiskCache::oUnknown) { - stats.narInfoReadAverted++; - { - auto state_(state.lock()); - state_->pathInfoCache.upsert(std::string(storePath.to_string()), - res.first == NarInfoDiskCache::oInvalid ? PathInfoCacheValue{} : PathInfoCacheValue{ .value = res.second }); - if (res.first == NarInfoDiskCache::oInvalid || - !goodStorePath(storePath, res.second->path)) - throw InvalidPath("path '%s' is not valid", printStorePath(storePath)); - } - return callback(ref(res.second)); - } - } - + if (queryPathInfoFromClientCache(storePath, callback)) + return; } catch (...) { return callback.rethrow(); } auto callbackPtr = std::make_shared(std::move(callback)); diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 9667b5e9e..2a1092d9e 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -282,6 +282,18 @@ public: void queryPathInfo(const StorePath & path, Callback> callback) noexcept; + /** + * NOTE: this is not the final interface - to be modified in next commit. + * + * Asynchronous version that only queries the local narinfo cache and not + * the actual store. + * + * @return true if the path was known and the callback invoked + * @return false if the path was not known and the callback not invoked + * @throw InvalidPathError if the path is known to be invalid + */ + bool queryPathInfoFromClientCache(const StorePath & path, Callback> & callback); + /** * Query the information about a realisation. */