diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2016-04-19T16·50+0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2016-04-19T16·52+0200 |
commit | e0204f8d462041387651af388074491fd0bf36d6 (patch) | |
tree | ecd20759ce49499722d140d653c5678051bcdfc2 /src/libstore/store-api.cc | |
parent | 608b0265e104b4a97f51e5745b1a32078770f3cf (diff) |
Move path info caching from BinaryCacheStore to Store
Caching path info is generally useful. For instance, it speeds up "nix path-info -rS /run/current-system" (i.e. showing the closure sizes of all paths in the closure of the current system) from 5.6s to 0.15s. This also eliminates some APIs like Store::queryDeriver() and Store::queryReferences().
Diffstat (limited to 'src/libstore/store-api.cc')
-rw-r--r-- | src/libstore/store-api.cc | 62 |
1 files changed, 53 insertions, 9 deletions
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index cc91ed287768..6543ed1f6d19 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -225,10 +225,48 @@ Path computeStorePathForText(const string & name, const string & s, } -void Store::queryReferences(const Path & path, PathSet & references) +bool Store::isValidPath(const Path & storePath) { - ValidPathInfo info = queryPathInfo(path); - references.insert(info.references.begin(), info.references.end()); + { + auto state_(state.lock()); + auto res = state_->pathInfoCache.get(storePath); + if (res) { + stats.narInfoReadAverted++; + return *res != 0; + } + } + + return isValidPathUncached(storePath); +} + + +ref<const ValidPathInfo> Store::queryPathInfo(const Path & storePath) +{ + { + auto state_(state.lock()); + auto res = state_->pathInfoCache.get(storePath); + if (res) { + stats.narInfoReadAverted++; + if (!*res) + throw InvalidPath(format("path ‘%s’ is not valid") % storePath); + return ref<ValidPathInfo>(*res); + } + } + + auto info = queryPathInfoUncached(storePath); + + { + auto state_(state.lock()); + state_->pathInfoCache.upsert(storePath, info); + stats.pathInfoCacheSize = state_->pathInfoCache.size(); + } + + if (!info) { + stats.narInfoMissing++; + throw InvalidPath(format("path ‘%s’ is not valid") % storePath); + } + + return ref<ValidPathInfo>(info); } @@ -243,19 +281,19 @@ string Store::makeValidityRegistration(const PathSet & paths, for (auto & i : paths) { s += i + "\n"; - ValidPathInfo info = queryPathInfo(i); + auto info = queryPathInfo(i); if (showHash) { - s += printHash(info.narHash) + "\n"; - s += (format("%1%\n") % info.narSize).str(); + s += printHash(info->narHash) + "\n"; + s += (format("%1%\n") % info->narSize).str(); } - Path deriver = showDerivers ? info.deriver : ""; + Path deriver = showDerivers ? info->deriver : ""; s += deriver + "\n"; - s += (format("%1%\n") % info.references.size()).str(); + s += (format("%1%\n") % info->references.size()).str(); - for (auto & j : info.references) + for (auto & j : info->references) s += j + "\n"; } @@ -263,6 +301,12 @@ string Store::makeValidityRegistration(const PathSet & paths, } +const Store::Stats & Store::getStats() +{ + return stats; +} + + ValidPathInfo decodeValidPathInfo(std::istream & str, bool hashGiven) { ValidPathInfo info; |