about summary refs log tree commit diff
path: root/src/libstore/store-api.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/store-api.cc')
-rw-r--r--src/libstore/store-api.cc53
1 files changed, 49 insertions, 4 deletions
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index dd87a046e380..f520210615a3 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -565,9 +565,30 @@ void Store::buildPaths(const PathSet & paths, BuildMode buildMode)
 void copyStorePath(ref<Store> srcStore, ref<Store> dstStore,
     const Path & storePath, RepairFlag repair, CheckSigsFlag checkSigs)
 {
+    Activity act(*logger, actCopyPath, fmt("copying path '%s'", storePath));
+
     auto info = srcStore->queryPathInfo(storePath);
 
-    StringSink sink;
+    uint64_t total = 0;
+
+    auto progress = [&](size_t len) {
+        total += len;
+        act.progress(total, info->narSize);
+    };
+
+    struct MyStringSink : StringSink
+    {
+        typedef std::function<void(size_t)> Callback;
+        Callback callback;
+        MyStringSink(Callback callback) : callback(callback) { }
+        void operator () (const unsigned char * data, size_t len) override
+        {
+            StringSink::operator ()(data, len);
+            callback(len);
+        };
+    };
+
+    MyStringSink sink(progress);
     srcStore->narFromPath({storePath}, sink);
 
     if (!info->narHash && !checkSigs) {
@@ -600,23 +621,47 @@ void copyPaths(ref<Store> srcStore, ref<Store> dstStore, const PathSet & storePa
     for (auto & path : storePaths)
         if (!valid.count(path)) missing.insert(path);
 
+    Activity act(*logger, actCopyPaths, fmt("copying %d paths", missing.size()));
+
+    std::atomic<size_t> nrDone{0};
+    std::atomic<uint64_t> bytesExpected{0};
+    std::atomic<uint64_t> nrRunning{0};
+
+    auto showProgress = [&]() {
+        act.progress(nrDone, missing.size(), nrRunning);
+    };
+
     ThreadPool pool;
 
     processGraph<Path>(pool,
         PathSet(missing.begin(), missing.end()),
 
         [&](const Path & storePath) {
-            if (dstStore->isValidPath(storePath)) return PathSet();
-            return srcStore->queryPathInfo(storePath)->references;
+            if (dstStore->isValidPath(storePath)) {
+                nrDone++;
+                showProgress();
+                return PathSet();
+            }
+
+            auto info = srcStore->queryPathInfo(storePath);
+
+            bytesExpected += info->narSize;
+            act.setExpected(actCopyPath, bytesExpected);
+
+            return info->references;
         },
 
         [&](const Path & storePath) {
             checkInterrupt();
 
             if (!dstStore->isValidPath(storePath)) {
-                printInfo("copying '%s'...", storePath);
+                MaintainCount<decltype(nrRunning)> mc(nrRunning);
+                showProgress();
                 copyStorePath(srcStore, dstStore, storePath, repair, checkSigs);
             }
+
+            nrDone++;
+            showProgress();
         });
 }