From 651df5099608e19bbbaa739c1843bd6211700a7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Thu, 3 Apr 2025 13:27:39 +0200 Subject: [PATCH] create cache entry for paths already in the nix store This allows path:/nix/store/* paths to not be copied twice to the nix store. (cherry picked from commit 61c6210dbf2096b89d1c4bc963bc3a044042fed4) --- src/libfetchers/fetch-to-store.cc | 23 +++++++++++++------ .../include/nix/fetchers/fetch-to-store.hh | 4 ++++ src/libfetchers/path.cc | 10 ++++++++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/libfetchers/fetch-to-store.cc b/src/libfetchers/fetch-to-store.cc index ea33922b6..f1b02f4e0 100644 --- a/src/libfetchers/fetch-to-store.cc +++ b/src/libfetchers/fetch-to-store.cc @@ -1,9 +1,23 @@ #include "nix/fetchers/fetch-to-store.hh" #include "nix/fetchers/fetchers.hh" -#include "nix/fetchers/cache.hh" namespace nix { +fetchers::Cache::Key makeFetchToStoreCacheKey( + const std::string &name, + const std::string &fingerprint, + ContentAddressMethod method, + const std::string &path) +{ + return fetchers::Cache::Key{"fetchToStore", { + {"name", name}, + {"fingerprint", fingerprint}, + {"method", std::string{method.render()}}, + {"path", path} + }}; + +} + StorePath fetchToStore( Store & store, const SourcePath & path, @@ -19,12 +33,7 @@ StorePath fetchToStore( std::optional cacheKey; if (!filter && path.accessor->fingerprint) { - cacheKey = fetchers::Cache::Key{"fetchToStore", { - {"name", std::string{name}}, - {"fingerprint", *path.accessor->fingerprint}, - {"method", std::string{method.render()}}, - {"path", path.path.abs()} - }}; + cacheKey = makeFetchToStoreCacheKey(std::string{name}, *path.accessor->fingerprint, method, path.path.abs()); if (auto res = fetchers::getCache()->lookupStorePath(*cacheKey, store)) { debug("store path cache hit for '%s'", path); return res->storePath; diff --git a/src/libfetchers/include/nix/fetchers/fetch-to-store.hh b/src/libfetchers/include/nix/fetchers/fetch-to-store.hh index a0144cb76..44c33c147 100644 --- a/src/libfetchers/include/nix/fetchers/fetch-to-store.hh +++ b/src/libfetchers/include/nix/fetchers/fetch-to-store.hh @@ -5,6 +5,7 @@ #include "nix/util/file-system.hh" #include "nix/util/repair-flag.hh" #include "nix/util/file-content-address.hh" +#include "nix/fetchers/cache.hh" namespace nix { @@ -22,4 +23,7 @@ StorePath fetchToStore( PathFilter * filter = nullptr, RepairFlag repair = NoRepair); +fetchers::Cache::Key makeFetchToStoreCacheKey( + const std::string & name, const std::string & fingerprint, ContentAddressMethod method, const std::string & path); + } diff --git a/src/libfetchers/path.cc b/src/libfetchers/path.cc index 173368dcc..670397cb6 100644 --- a/src/libfetchers/path.cc +++ b/src/libfetchers/path.cc @@ -2,6 +2,8 @@ #include "nix/store/store-api.hh" #include "nix/util/archive.hh" #include "nix/fetchers/store-path-accessor.hh" +#include "nix/fetchers/cache.hh" +#include "nix/fetchers/fetch-to-store.hh" namespace nix::fetchers { @@ -142,6 +144,14 @@ struct PathInputScheme : InputScheme storePath = store->addToStoreFromDump(*src, "source"); } + // To avoid copying the path again to the /nix/store, we need to add a cache entry. + ContentAddressMethod method = ContentAddressMethod::Raw::NixArchive; + auto fp = getFingerprint(store, input); + if (fp) { + auto cacheKey = makeFetchToStoreCacheKey(input.getName(), *fp, method, "/"); + fetchers::getCache()->upsert(cacheKey, *store, {}, *storePath); + } + /* Trust the lastModified value supplied by the user, if any. It's not a "secure" attribute so we don't care. */ if (!input.getLastModified())