From c7f8147282a004a06a8fd2b1aa89523f8c0879f7 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 9 Apr 2025 21:38:08 +0200 Subject: [PATCH 1/3] Rename FlakeCache -> InputCache and key it on Inputs instead of FlakeRefs --- src/libflake/flake/flake.cc | 85 ++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/src/libflake/flake/flake.cc b/src/libflake/flake/flake.cc index 8856a03dd..30093bd4d 100644 --- a/src/libflake/flake/flake.cc +++ b/src/libflake/flake/flake.cc @@ -23,64 +23,64 @@ using namespace flake; namespace flake { -struct FetchedFlake +struct CachedInput { - FlakeRef lockedRef; + Input lockedInput; ref accessor; }; -typedef std::map FlakeCache; +typedef std::map InputCache; -static std::optional lookupInFlakeCache( - const FlakeCache & flakeCache, - const FlakeRef & flakeRef) +static std::optional lookupInInputCache( + const InputCache & inputCache, + const Input & originalInput) { - auto i = flakeCache.find(flakeRef); - if (i == flakeCache.end()) return std::nullopt; + auto i = inputCache.find(originalInput); + if (i == inputCache.end()) return std::nullopt; debug("mapping '%s' to previously seen input '%s' -> '%s", - flakeRef, i->first, i->second.lockedRef); + originalInput.to_string(), i->first.to_string(), i->second.lockedInput.to_string()); return i->second; } -static std::tuple, FlakeRef, FlakeRef> fetchOrSubstituteTree( +static std::tuple, Input, Input> getAccessorCached( EvalState & state, - const FlakeRef & originalRef, + const Input & originalInput, bool useRegistries, - FlakeCache & flakeCache) + InputCache & inputCache) { - auto fetched = lookupInFlakeCache(flakeCache, originalRef); - FlakeRef resolvedRef = originalRef; + auto fetched = lookupInInputCache(inputCache, originalInput); + Input resolvedInput = originalInput; if (!fetched) { - if (originalRef.input.isDirect()) { - auto [accessor, lockedRef] = originalRef.lazyFetch(state.store); - fetched.emplace(FetchedFlake{.lockedRef = lockedRef, .accessor = accessor}); + if (originalInput.isDirect()) { + auto [accessor, lockedInput] = originalInput.getAccessor(state.store); + fetched.emplace(CachedInput{.lockedInput = lockedInput, .accessor = accessor}); } else { if (useRegistries) { - resolvedRef = originalRef.resolve( - state.store, + auto [res, extraAttrs] = lookupInRegistries(state.store, originalInput, [](fetchers::Registry::RegistryType type) { /* Only use the global registry and CLI flags to resolve indirect flakerefs. */ return type == fetchers::Registry::Flag || type == fetchers::Registry::Global; }); - fetched = lookupInFlakeCache(flakeCache, originalRef); + resolvedInput = std::move(res); + fetched = lookupInInputCache(inputCache, originalInput); if (!fetched) { - auto [accessor, lockedRef] = resolvedRef.lazyFetch(state.store); - fetched.emplace(FetchedFlake{.lockedRef = lockedRef, .accessor = accessor}); + auto [accessor, lockedInput] = resolvedInput.getAccessor(state.store); + fetched.emplace(CachedInput{.lockedInput = lockedInput, .accessor = accessor}); } - flakeCache.insert_or_assign(resolvedRef, *fetched); + inputCache.insert_or_assign(resolvedInput, *fetched); } else { - throw Error("'%s' is an indirect flake reference, but registry lookups are not allowed", originalRef); + throw Error("'%s' is an indirect flake reference, but registry lookups are not allowed", originalInput.to_string()); } } - flakeCache.insert_or_assign(originalRef, *fetched); + inputCache.insert_or_assign(originalInput, *fetched); } - debug("got tree '%s' from '%s'", fetched->accessor, fetched->lockedRef); + debug("got tree '%s' from '%s'", fetched->accessor, fetched->lockedInput.to_string()); - return {fetched->accessor, resolvedRef, fetched->lockedRef}; + return {fetched->accessor, resolvedInput, fetched->lockedInput}; } static StorePath copyInputToStore( @@ -397,12 +397,15 @@ static Flake getFlake( EvalState & state, const FlakeRef & originalRef, bool useRegistries, - FlakeCache & flakeCache, + InputCache & inputCache, const InputAttrPath & lockRootAttrPath) { // Fetch a lazy tree first. - auto [accessor, resolvedRef, lockedRef] = fetchOrSubstituteTree( - state, originalRef, useRegistries, flakeCache); + auto [accessor, resolvedInput, lockedInput] = getAccessorCached( + state, originalRef.input, useRegistries, inputCache); + + auto resolvedRef = FlakeRef(std::move(resolvedInput), originalRef.subdir); + auto lockedRef = FlakeRef(std::move(lockedInput), originalRef.subdir); // Parse/eval flake.nix to get at the input.self attributes. auto flake = readFlake(state, originalRef, resolvedRef, lockedRef, {accessor}, lockRootAttrPath); @@ -414,10 +417,10 @@ static Flake getFlake( debug("refetching input '%s' due to self attribute", newLockedRef); // FIXME: need to remove attrs that are invalidated by the changed input attrs, such as 'narHash'. newLockedRef.input.attrs.erase("narHash"); - auto [accessor2, resolvedRef2, lockedRef2] = fetchOrSubstituteTree( - state, newLockedRef, false, flakeCache); + auto [accessor2, resolvedInput2, lockedInput2] = getAccessorCached( + state, newLockedRef.input, false, inputCache); accessor = accessor2; - lockedRef = lockedRef2; + lockedRef = FlakeRef(std::move(lockedInput2), newLockedRef.subdir); } // Copy the tree to the store. @@ -429,8 +432,8 @@ static Flake getFlake( Flake getFlake(EvalState & state, const FlakeRef & originalRef, bool useRegistries) { - FlakeCache flakeCache; - return getFlake(state, originalRef, useRegistries, flakeCache, {}); + InputCache inputCache; + return getFlake(state, originalRef, useRegistries, inputCache, {}); } static LockFile readLockFile( @@ -452,11 +455,11 @@ LockedFlake lockFlake( { experimentalFeatureSettings.require(Xp::Flakes); - FlakeCache flakeCache; + InputCache inputCache; auto useRegistries = lockFlags.useRegistries.value_or(settings.useRegistries); - auto flake = getFlake(state, topRef, useRegistries, flakeCache, {}); + auto flake = getFlake(state, topRef, useRegistries, inputCache, {}); if (lockFlags.applyNixConfig) { flake.config.apply(settings); @@ -631,7 +634,7 @@ LockedFlake lockFlake( if (auto resolvedPath = resolveRelativePath()) { return readFlake(state, ref, ref, ref, *resolvedPath, inputAttrPath); } else { - return getFlake(state, ref, useRegistries, flakeCache, inputAttrPath); + return getFlake(state, ref, useRegistries, inputCache, inputAttrPath); } }; @@ -779,8 +782,10 @@ LockedFlake lockFlake( if (auto resolvedPath = resolveRelativePath()) { return {*resolvedPath, *input.ref}; } else { - auto [accessor, resolvedRef, lockedRef] = fetchOrSubstituteTree( - state, *input.ref, useRegistries, flakeCache); + auto [accessor, resolvedInput, lockedInput] = getAccessorCached( + state, input.ref->input, useRegistries, inputCache); + + auto lockedRef = FlakeRef(std::move(lockedInput), input.ref->subdir); // FIXME: allow input to be lazy. auto storePath = copyInputToStore(state, lockedRef.input, input.ref->input, accessor); From 012453d1e60eee7decda6fbdafd948d688eb8aa0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 9 Apr 2025 22:11:36 +0200 Subject: [PATCH 2/3] Move the input cache into libfetchers --- src/libcmd/repl.cc | 3 ++ .../include/nix/fetchers/input-cache.hh | 22 +++++++++ .../include/nix/fetchers/meson.build | 1 + src/libfetchers/input-cache.cc | 41 ++++++++++++++++ src/libfetchers/meson.build | 1 + src/libflake-c/nix_api_flake.cc | 2 + src/libflake/flake/flake.cc | 49 ++++++------------- 7 files changed, 84 insertions(+), 35 deletions(-) create mode 100644 src/libfetchers/include/nix/fetchers/input-cache.hh create mode 100644 src/libfetchers/input-cache.cc diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index c5a95268b..3805942ce 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -28,6 +28,7 @@ #include "nix/expr/print.hh" #include "nix/util/ref.hh" #include "nix/expr/value.hh" +#include "nix/fetchers/input-cache.hh" #include "nix/util/strings.hh" @@ -458,6 +459,7 @@ ProcessLineResult NixRepl::processLine(std::string line) else if (command == ":l" || command == ":load") { state->resetFileCache(); + fetchers::InputCache::getCache()->clear(); loadFile(arg); } @@ -467,6 +469,7 @@ ProcessLineResult NixRepl::processLine(std::string line) else if (command == ":r" || command == ":reload") { state->resetFileCache(); + fetchers::InputCache::getCache()->clear(); reloadFiles(); } diff --git a/src/libfetchers/include/nix/fetchers/input-cache.hh b/src/libfetchers/include/nix/fetchers/input-cache.hh new file mode 100644 index 000000000..62092baef --- /dev/null +++ b/src/libfetchers/include/nix/fetchers/input-cache.hh @@ -0,0 +1,22 @@ +#include "fetchers.hh" + +namespace nix::fetchers { + +struct CachedInput +{ + Input lockedInput; + ref accessor; +}; + +struct InputCache +{ + virtual std::optional lookup(const Input & originalInput) const = 0; + + virtual void upsert(Input key, CachedInput cachedInput) = 0; + + virtual void clear() = 0; + + static ref getCache(); +}; + +} diff --git a/src/libfetchers/include/nix/fetchers/meson.build b/src/libfetchers/include/nix/fetchers/meson.build index 3a752d9cb..e6ddedd97 100644 --- a/src/libfetchers/include/nix/fetchers/meson.build +++ b/src/libfetchers/include/nix/fetchers/meson.build @@ -9,6 +9,7 @@ headers = files( 'filtering-source-accessor.hh', 'git-lfs-fetch.hh', 'git-utils.hh', + 'input-cache.hh', 'registry.hh', 'store-path-accessor.hh', 'tarball.hh', diff --git a/src/libfetchers/input-cache.cc b/src/libfetchers/input-cache.cc new file mode 100644 index 000000000..44d33428d --- /dev/null +++ b/src/libfetchers/input-cache.cc @@ -0,0 +1,41 @@ +#include "nix/fetchers/input-cache.hh" +#include "nix/util/sync.hh" + +namespace nix::fetchers { + +struct InputCacheImpl : InputCache +{ + Sync> cache_; + + std::optional lookup(const Input & originalInput) const override + { + auto cache(cache_.readLock()); + auto i = cache->find(originalInput); + if (i == cache->end()) + return std::nullopt; + debug( + "mapping '%s' to previously seen input '%s' -> '%s", + originalInput.to_string(), + i->first.to_string(), + i->second.lockedInput.to_string()); + return i->second; + } + + void upsert(Input key, CachedInput cachedInput) override + { + cache_.lock()->insert_or_assign(std::move(key), std::move(cachedInput)); + } + + void clear() override + { + cache_.lock()->clear(); + } +}; + +ref InputCache::getCache() +{ + static auto cache = make_ref(); + return cache; +} + +} diff --git a/src/libfetchers/meson.build b/src/libfetchers/meson.build index 6e7129f4c..321146ca4 100644 --- a/src/libfetchers/meson.build +++ b/src/libfetchers/meson.build @@ -44,6 +44,7 @@ sources = files( 'git.cc', 'github.cc', 'indirect.cc', + 'input-cache.cc', 'mercurial.cc', 'path.cc', 'registry.cc', diff --git a/src/libflake-c/nix_api_flake.cc b/src/libflake-c/nix_api_flake.cc index 06b139f91..0cc9a6a10 100644 --- a/src/libflake-c/nix_api_flake.cc +++ b/src/libflake-c/nix_api_flake.cc @@ -7,6 +7,7 @@ #include "nix_api_fetchers.h" #include "nix/flake/flake.hh" +#include "nix/fetchers/input-cache.hh" nix_flake_settings * nix_flake_settings_new(nix_c_context * context) { @@ -177,6 +178,7 @@ nix_locked_flake * nix_flake_lock( { nix_clear_err(context); try { + nix::fetchers::InputCache::getCache()->clear(); auto lockedFlake = nix::make_ref(nix::flake::lockFlake( *flakeSettings->settings, eval_state->state, *flakeReference->flakeRef, *flags->lockFlags)); return new nix_locked_flake{lockedFlake}; diff --git a/src/libflake/flake/flake.cc b/src/libflake/flake/flake.cc index 30093bd4d..ca2a34f5f 100644 --- a/src/libflake/flake/flake.cc +++ b/src/libflake/flake/flake.cc @@ -14,6 +14,7 @@ #include "nix/store/local-fs-store.hh" #include "nix/fetchers/fetch-to-store.hh" #include "nix/util/memory-source-accessor.hh" +#include "nix/fetchers/input-cache.hh" #include @@ -23,32 +24,14 @@ using namespace flake; namespace flake { -struct CachedInput -{ - Input lockedInput; - ref accessor; -}; - -typedef std::map InputCache; - -static std::optional lookupInInputCache( - const InputCache & inputCache, - const Input & originalInput) -{ - auto i = inputCache.find(originalInput); - if (i == inputCache.end()) return std::nullopt; - debug("mapping '%s' to previously seen input '%s' -> '%s", - originalInput.to_string(), i->first.to_string(), i->second.lockedInput.to_string()); - return i->second; -} - static std::tuple, Input, Input> getAccessorCached( EvalState & state, const Input & originalInput, - bool useRegistries, - InputCache & inputCache) + bool useRegistries) { - auto fetched = lookupInInputCache(inputCache, originalInput); + auto inputCache = InputCache::getCache(); + + auto fetched = inputCache->lookup(originalInput); Input resolvedInput = originalInput; if (!fetched) { @@ -64,18 +47,18 @@ static std::tuple, Input, Input> getAccessorCached( return type == fetchers::Registry::Flag || type == fetchers::Registry::Global; }); resolvedInput = std::move(res); - fetched = lookupInInputCache(inputCache, originalInput); + fetched = inputCache->lookup(resolvedInput); if (!fetched) { auto [accessor, lockedInput] = resolvedInput.getAccessor(state.store); fetched.emplace(CachedInput{.lockedInput = lockedInput, .accessor = accessor}); } - inputCache.insert_or_assign(resolvedInput, *fetched); + inputCache->upsert(resolvedInput, *fetched); } else { throw Error("'%s' is an indirect flake reference, but registry lookups are not allowed", originalInput.to_string()); } } - inputCache.insert_or_assign(originalInput, *fetched); + inputCache->upsert(originalInput, *fetched); } debug("got tree '%s' from '%s'", fetched->accessor, fetched->lockedInput.to_string()); @@ -397,12 +380,11 @@ static Flake getFlake( EvalState & state, const FlakeRef & originalRef, bool useRegistries, - InputCache & inputCache, const InputAttrPath & lockRootAttrPath) { // Fetch a lazy tree first. auto [accessor, resolvedInput, lockedInput] = getAccessorCached( - state, originalRef.input, useRegistries, inputCache); + state, originalRef.input, useRegistries); auto resolvedRef = FlakeRef(std::move(resolvedInput), originalRef.subdir); auto lockedRef = FlakeRef(std::move(lockedInput), originalRef.subdir); @@ -418,7 +400,7 @@ static Flake getFlake( // FIXME: need to remove attrs that are invalidated by the changed input attrs, such as 'narHash'. newLockedRef.input.attrs.erase("narHash"); auto [accessor2, resolvedInput2, lockedInput2] = getAccessorCached( - state, newLockedRef.input, false, inputCache); + state, newLockedRef.input, false); accessor = accessor2; lockedRef = FlakeRef(std::move(lockedInput2), newLockedRef.subdir); } @@ -432,8 +414,7 @@ static Flake getFlake( Flake getFlake(EvalState & state, const FlakeRef & originalRef, bool useRegistries) { - InputCache inputCache; - return getFlake(state, originalRef, useRegistries, inputCache, {}); + return getFlake(state, originalRef, useRegistries, {}); } static LockFile readLockFile( @@ -455,11 +436,9 @@ LockedFlake lockFlake( { experimentalFeatureSettings.require(Xp::Flakes); - InputCache inputCache; - auto useRegistries = lockFlags.useRegistries.value_or(settings.useRegistries); - auto flake = getFlake(state, topRef, useRegistries, inputCache, {}); + auto flake = getFlake(state, topRef, useRegistries, {}); if (lockFlags.applyNixConfig) { flake.config.apply(settings); @@ -634,7 +613,7 @@ LockedFlake lockFlake( if (auto resolvedPath = resolveRelativePath()) { return readFlake(state, ref, ref, ref, *resolvedPath, inputAttrPath); } else { - return getFlake(state, ref, useRegistries, inputCache, inputAttrPath); + return getFlake(state, ref, useRegistries, inputAttrPath); } }; @@ -783,7 +762,7 @@ LockedFlake lockFlake( return {*resolvedPath, *input.ref}; } else { auto [accessor, resolvedInput, lockedInput] = getAccessorCached( - state, input.ref->input, useRegistries, inputCache); + state, input.ref->input, useRegistries); auto lockedRef = FlakeRef(std::move(lockedInput), input.ref->subdir); From e3042f10afb5f4e64ef9a5e08bef52b168cb4bf1 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 9 Apr 2025 23:06:03 +0200 Subject: [PATCH 3/3] Move getAccessorCached() to InputCache --- .../include/nix/fetchers/input-cache.hh | 21 ++++-- src/libfetchers/input-cache.cc | 40 +++++++++++ src/libflake/flake/flake.cc | 67 +++---------------- 3 files changed, 66 insertions(+), 62 deletions(-) diff --git a/src/libfetchers/include/nix/fetchers/input-cache.hh b/src/libfetchers/include/nix/fetchers/input-cache.hh index 62092baef..6a7194741 100644 --- a/src/libfetchers/include/nix/fetchers/input-cache.hh +++ b/src/libfetchers/include/nix/fetchers/input-cache.hh @@ -2,14 +2,23 @@ namespace nix::fetchers { -struct CachedInput -{ - Input lockedInput; - ref accessor; -}; - struct InputCache { + struct CachedResult + { + ref accessor; + Input resolvedInput; + Input lockedInput; + }; + + CachedResult getAccessor(ref store, const Input & originalInput, bool useRegistries); + + struct CachedInput + { + Input lockedInput; + ref accessor; + }; + virtual std::optional lookup(const Input & originalInput) const = 0; virtual void upsert(Input key, CachedInput cachedInput) = 0; diff --git a/src/libfetchers/input-cache.cc b/src/libfetchers/input-cache.cc index 44d33428d..6772d67c7 100644 --- a/src/libfetchers/input-cache.cc +++ b/src/libfetchers/input-cache.cc @@ -1,8 +1,48 @@ #include "nix/fetchers/input-cache.hh" +#include "nix/fetchers/registry.hh" #include "nix/util/sync.hh" +#include "nix/util/source-path.hh" namespace nix::fetchers { +InputCache::CachedResult InputCache::getAccessor(ref store, const Input & originalInput, bool useRegistries) +{ + auto fetched = lookup(originalInput); + Input resolvedInput = originalInput; + + if (!fetched) { + if (originalInput.isDirect()) { + auto [accessor, lockedInput] = originalInput.getAccessor(store); + fetched.emplace(CachedInput{.lockedInput = lockedInput, .accessor = accessor}); + } else { + if (useRegistries) { + auto [res, extraAttrs] = + lookupInRegistries(store, originalInput, [](fetchers::Registry::RegistryType type) { + /* Only use the global registry and CLI flags + to resolve indirect flakerefs. */ + return type == fetchers::Registry::Flag || type == fetchers::Registry::Global; + }); + resolvedInput = std::move(res); + fetched = lookup(resolvedInput); + if (!fetched) { + auto [accessor, lockedInput] = resolvedInput.getAccessor(store); + fetched.emplace(CachedInput{.lockedInput = lockedInput, .accessor = accessor}); + } + upsert(resolvedInput, *fetched); + } else { + throw Error( + "'%s' is an indirect flake reference, but registry lookups are not allowed", + originalInput.to_string()); + } + } + upsert(originalInput, *fetched); + } + + debug("got tree '%s' from '%s'", fetched->accessor, fetched->lockedInput.to_string()); + + return {fetched->accessor, resolvedInput, fetched->lockedInput}; +} + struct InputCacheImpl : InputCache { Sync> cache_; diff --git a/src/libflake/flake/flake.cc b/src/libflake/flake/flake.cc index ca2a34f5f..cee39defc 100644 --- a/src/libflake/flake/flake.cc +++ b/src/libflake/flake/flake.cc @@ -24,48 +24,6 @@ using namespace flake; namespace flake { -static std::tuple, Input, Input> getAccessorCached( - EvalState & state, - const Input & originalInput, - bool useRegistries) -{ - auto inputCache = InputCache::getCache(); - - auto fetched = inputCache->lookup(originalInput); - Input resolvedInput = originalInput; - - if (!fetched) { - if (originalInput.isDirect()) { - auto [accessor, lockedInput] = originalInput.getAccessor(state.store); - fetched.emplace(CachedInput{.lockedInput = lockedInput, .accessor = accessor}); - } else { - if (useRegistries) { - auto [res, extraAttrs] = lookupInRegistries(state.store, originalInput, - [](fetchers::Registry::RegistryType type) { - /* Only use the global registry and CLI flags - to resolve indirect flakerefs. */ - return type == fetchers::Registry::Flag || type == fetchers::Registry::Global; - }); - resolvedInput = std::move(res); - fetched = inputCache->lookup(resolvedInput); - if (!fetched) { - auto [accessor, lockedInput] = resolvedInput.getAccessor(state.store); - fetched.emplace(CachedInput{.lockedInput = lockedInput, .accessor = accessor}); - } - inputCache->upsert(resolvedInput, *fetched); - } - else { - throw Error("'%s' is an indirect flake reference, but registry lookups are not allowed", originalInput.to_string()); - } - } - inputCache->upsert(originalInput, *fetched); - } - - debug("got tree '%s' from '%s'", fetched->accessor, fetched->lockedInput.to_string()); - - return {fetched->accessor, resolvedInput, fetched->lockedInput}; -} - static StorePath copyInputToStore( EvalState & state, fetchers::Input & input, @@ -383,14 +341,13 @@ static Flake getFlake( const InputAttrPath & lockRootAttrPath) { // Fetch a lazy tree first. - auto [accessor, resolvedInput, lockedInput] = getAccessorCached( - state, originalRef.input, useRegistries); + auto cachedInput = fetchers::InputCache::getCache()->getAccessor(state.store, originalRef.input, useRegistries); - auto resolvedRef = FlakeRef(std::move(resolvedInput), originalRef.subdir); - auto lockedRef = FlakeRef(std::move(lockedInput), originalRef.subdir); + auto resolvedRef = FlakeRef(std::move(cachedInput.resolvedInput), originalRef.subdir); + auto lockedRef = FlakeRef(std::move(cachedInput.lockedInput), originalRef.subdir); // Parse/eval flake.nix to get at the input.self attributes. - auto flake = readFlake(state, originalRef, resolvedRef, lockedRef, {accessor}, lockRootAttrPath); + auto flake = readFlake(state, originalRef, resolvedRef, lockedRef, {cachedInput.accessor}, lockRootAttrPath); // Re-fetch the tree if necessary. auto newLockedRef = applySelfAttrs(lockedRef, flake); @@ -399,14 +356,13 @@ static Flake getFlake( debug("refetching input '%s' due to self attribute", newLockedRef); // FIXME: need to remove attrs that are invalidated by the changed input attrs, such as 'narHash'. newLockedRef.input.attrs.erase("narHash"); - auto [accessor2, resolvedInput2, lockedInput2] = getAccessorCached( - state, newLockedRef.input, false); - accessor = accessor2; - lockedRef = FlakeRef(std::move(lockedInput2), newLockedRef.subdir); + auto cachedInput2 = fetchers::InputCache::getCache()->getAccessor(state.store, newLockedRef.input, useRegistries); + cachedInput.accessor = cachedInput2.accessor; + lockedRef = FlakeRef(std::move(cachedInput2.lockedInput), newLockedRef.subdir); } // Copy the tree to the store. - auto storePath = copyInputToStore(state, lockedRef.input, originalRef.input, accessor); + auto storePath = copyInputToStore(state, lockedRef.input, originalRef.input, cachedInput.accessor); // Re-parse flake.nix from the store. return readFlake(state, originalRef, resolvedRef, lockedRef, state.storePath(storePath), lockRootAttrPath); @@ -761,13 +717,12 @@ LockedFlake lockFlake( if (auto resolvedPath = resolveRelativePath()) { return {*resolvedPath, *input.ref}; } else { - auto [accessor, resolvedInput, lockedInput] = getAccessorCached( - state, input.ref->input, useRegistries); + auto cachedInput = fetchers::InputCache::getCache()->getAccessor(state.store, input.ref->input, useRegistries); - auto lockedRef = FlakeRef(std::move(lockedInput), input.ref->subdir); + auto lockedRef = FlakeRef(std::move(cachedInput.lockedInput), input.ref->subdir); // FIXME: allow input to be lazy. - auto storePath = copyInputToStore(state, lockedRef.input, input.ref->input, accessor); + auto storePath = copyInputToStore(state, lockedRef.input, input.ref->input, cachedInput.accessor); return {state.storePath(storePath), lockedRef}; }