Skip to content

Commit 5d13b86

Browse files
committed
short-circuit computeFSClosure from copyClosure
1 parent 94c3bb3 commit 5d13b86

File tree

6 files changed

+36
-10
lines changed

6 files changed

+36
-10
lines changed

src/libstore-c/nix_api_store.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ nix_err nix_store_copy_closure(nix_c_context * context, Store * srcStore, Store
251251
if (context)
252252
context->last_err_code = NIX_OK;
253253
try {
254-
nix::RealisedPath::Set paths;
254+
nix::StorePathSet paths;
255255
paths.insert(path->path);
256256
nix::copyClosure(*srcStore->ptr, *dstStore->ptr, paths);
257257
}

src/libstore/include/nix/store/legacy-ssh-store.hh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ public:
175175
StorePathSet & out,
176176
bool flipDirection = false,
177177
bool includeOutputs = false,
178-
bool includeDerivers = false) override;
178+
bool includeDerivers = false,
179+
std::function<bool(const StorePath & path)> pathCallback = nullptr) override;
179180

180181
StorePathSet queryValidPaths(const StorePathSet & paths, SubstituteFlag maybeSubstitute = NoSubstitute) override;
181182

src/libstore/include/nix/store/store-api.hh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -802,13 +802,19 @@ public:
802802
* `storePath` is returned; that is, the closures under the
803803
* `referrers` relation instead of the `references` relation is
804804
* returned.
805+
*
806+
* @param onPathDiscovered A callback invoked on each discovered store
807+
* path. Returning `false` from the callback will stop recursion on
808+
* that path. Returning `true` will continue recursion. A `nullptr` is
809+
* equivalent to a callback which always returns `true`.
805810
*/
806811
virtual void computeFSClosure(
807812
const StorePathSet & paths,
808813
StorePathSet & out,
809814
bool flipDirection = false,
810815
bool includeOutputs = false,
811-
bool includeDerivers = false);
816+
bool includeDerivers = false,
817+
std::function<bool(const StorePath & path)> onPathDiscovered = nullptr);
812818

813819
void computeFSClosure(
814820
const StorePath & path,

src/libstore/legacy-ssh-store.cc

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,15 @@ void LegacySSHStore::buildPaths(
252252
}
253253

254254
void LegacySSHStore::computeFSClosure(
255-
const StorePathSet & paths, StorePathSet & out, bool flipDirection, bool includeOutputs, bool includeDerivers)
255+
const StorePathSet & paths,
256+
StorePathSet & out,
257+
bool flipDirection,
258+
bool includeOutputs,
259+
bool includeDerivers,
260+
std::function<bool(const StorePath & path)> onPathDiscovered)
256261
{
257-
if (flipDirection || includeDerivers) {
258-
Store::computeFSClosure(paths, out, flipDirection, includeOutputs, includeDerivers);
262+
if (flipDirection || includeDerivers || onPathDiscovered) {
263+
Store::computeFSClosure(paths, out, flipDirection, includeOutputs, includeDerivers, onPathDiscovered);
259264
return;
260265
}
261266

src/libstore/misc.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ void Store::computeFSClosure(
2121
StorePathSet & paths_,
2222
bool flipDirection,
2323
bool includeOutputs,
24-
bool includeDerivers)
24+
bool includeDerivers,
25+
std::function<bool(const StorePath & path)> onPathDiscovered)
2526
{
2627
std::function<std::set<StorePath>(const StorePath & path, std::future<ref<const ValidPathInfo>> &)> queryDeps;
2728
if (flipDirection)
@@ -65,6 +66,12 @@ void Store::computeFSClosure(
6566
startPaths,
6667
paths_,
6768
[&](const StorePath & path, std::function<void(std::promise<std::set<StorePath>> &)> processEdges) {
69+
if (onPathDiscovered && !onPathDiscovered(path)) {
70+
std::promise<std::set<StorePath>> promise;
71+
promise.set_value({});
72+
processEdges(promise);
73+
return;
74+
}
6875
std::promise<std::set<StorePath>> promise;
6976
std::function<void(std::future<ref<const ValidPathInfo>>)> getDependencies =
7077
[&](std::future<ref<const ValidPathInfo>> fut) {

src/libstore/store-api.cc

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,9 +1072,16 @@ void copyClosure(
10721072
if (&srcStore == &dstStore)
10731073
return;
10741074

1075-
StorePathSet closure;
1076-
srcStore.computeFSClosure(storePaths, closure);
1077-
copyPaths(srcStore, dstStore, closure, repair, checkSigs, substitute);
1075+
StorePathSet pathsToCopy;
1076+
1077+
auto onPathDiscovered = [&](const StorePath & path) -> bool {
1078+
// Only recurse if the path does not already exist in `dstStore`
1079+
return repair || !dstStore.isValidPath(path);
1080+
};
1081+
srcStore.computeFSClosure(storePaths, pathsToCopy, false, false, false, onPathDiscovered);
1082+
pathsToCopy.insert(storePaths.begin(), storePaths.end());
1083+
1084+
copyPaths(srcStore, dstStore, pathsToCopy, repair, checkSigs, substitute);
10781085
}
10791086

10801087
std::optional<ValidPathInfo>

0 commit comments

Comments
 (0)