diff options
Diffstat (limited to 'src/libstore/store-api.cc')
-rw-r--r-- | src/libstore/store-api.cc | 53 |
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(); }); } |