about summary refs log tree commit diff
path: root/src/libstore/store-api.cc
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2016-04-19T16·50+0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2016-04-19T16·52+0200
commite0204f8d462041387651af388074491fd0bf36d6 (patch)
treeecd20759ce49499722d140d653c5678051bcdfc2 /src/libstore/store-api.cc
parent608b0265e104b4a97f51e5745b1a32078770f3cf (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.cc62
1 files changed, 53 insertions, 9 deletions
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index cc91ed2877..6543ed1f6d 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;