diff --git a/src/libfetchers/fetch-to-store.cc b/src/libfetchers/fetch-to-store.cc index 65aa72a6c36..d9fff8cd45c 100644 --- a/src/libfetchers/fetch-to-store.cc +++ b/src/libfetchers/fetch-to-store.cc @@ -1,6 +1,7 @@ #include "fetch-to-store.hh" #include "fetchers.hh" #include "cache.hh" +#include "posix-source-accessor.hh" namespace nix { @@ -13,8 +14,16 @@ StorePath fetchToStore( PathFilter * filter, RepairFlag repair) { - // FIXME: add an optimisation for the case where the accessor is - // a `PosixSourceAccessor` pointing to a store path. + if (path.accessor->isStorePath + && path.path.isRoot() + && method == FileIngestionMethod::Recursive + && !filter) + { + if (auto accessor = path.accessor.dynamic_pointer_cast()) + if (auto storePath = store.maybeParseStorePath(accessor->root.string())) + if (storePath->name() == name) + return *storePath; + } std::optional cacheKey; diff --git a/src/libfetchers/path.cc b/src/libfetchers/path.cc index 68958d55971..8ba873b3722 100644 --- a/src/libfetchers/path.cc +++ b/src/libfetchers/path.cc @@ -155,7 +155,12 @@ struct PathInputScheme : InputScheme } input.attrs.insert_or_assign("lastModified", uint64_t(mtime)); - return {makeStorePathAccessor(store, *storePath), std::move(input)}; + auto accessor = makeStorePathAccessor(store, *storePath); + + /* Optimize fetchToStore() calls on this path. */ + accessor->isStorePath = true; + + return {accessor, std::move(input)}; } std::optional getFingerprint(ref store, const Input & input) const override diff --git a/src/libfetchers/unix/mercurial.cc b/src/libfetchers/unix/mercurial.cc index 7bdf1e9375b..e2fba21ca8a 100644 --- a/src/libfetchers/unix/mercurial.cc +++ b/src/libfetchers/unix/mercurial.cc @@ -339,6 +339,9 @@ struct MercurialInputScheme : InputScheme accessor->setPathDisplay("«" + input.to_string() + "»"); + /* Optimize fetchToStore() calls on this path. */ + accessor->isStorePath = true; + return {accessor, input}; } diff --git a/src/libutil/source-accessor.hh b/src/libutil/source-accessor.hh index d7fb0af5fac..75c9ec8faed 100644 --- a/src/libutil/source-accessor.hh +++ b/src/libutil/source-accessor.hh @@ -181,6 +181,13 @@ struct SourceAccessor : std::enable_shared_from_this */ virtual std::optional getLastModified() { return std::nullopt; } + + /** + * Whether this is a store path using + * FileIngestionMethod::Recursive. This is used to optimize + * `fetchToStore()`. + */ + bool isStorePath = false; }; /**