1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-29 02:11:15 +02:00

Rename FlakeCache -> InputCache and key it on Inputs instead of FlakeRefs

This commit is contained in:
Eelco Dolstra 2025-04-09 21:38:08 +02:00
parent f45db85887
commit 0cb06d7eda

View file

@ -21,67 +21,68 @@
namespace nix { namespace nix {
using namespace flake; using namespace flake;
using namespace fetchers;
namespace flake { namespace flake {
struct FetchedFlake struct CachedInput
{ {
FlakeRef lockedRef; Input lockedInput;
ref<SourceAccessor> accessor; ref<SourceAccessor> accessor;
}; };
typedef std::map<FlakeRef, FetchedFlake> FlakeCache; typedef std::map<Input, CachedInput> InputCache;
static std::optional<FetchedFlake> lookupInFlakeCache( static std::optional<CachedInput> lookupInInputCache(
const FlakeCache & flakeCache, const InputCache & inputCache,
const FlakeRef & flakeRef) const Input & originalInput)
{ {
auto i = flakeCache.find(flakeRef); auto i = inputCache.find(originalInput);
if (i == flakeCache.end()) return std::nullopt; if (i == inputCache.end()) return std::nullopt;
debug("mapping '%s' to previously seen input '%s' -> '%s", 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; return i->second;
} }
static std::tuple<ref<SourceAccessor>, FlakeRef, FlakeRef> fetchOrSubstituteTree( static std::tuple<ref<SourceAccessor>, Input, Input> getAccessorCached(
EvalState & state, EvalState & state,
const FlakeRef & originalRef, const Input & originalInput,
bool useRegistries, bool useRegistries,
FlakeCache & flakeCache) InputCache & inputCache)
{ {
auto fetched = lookupInFlakeCache(flakeCache, originalRef); auto fetched = lookupInInputCache(inputCache, originalInput);
FlakeRef resolvedRef = originalRef; Input resolvedInput = originalInput;
if (!fetched) { if (!fetched) {
if (originalRef.input.isDirect()) { if (originalInput.isDirect()) {
auto [accessor, lockedRef] = originalRef.lazyFetch(state.store); auto [accessor, lockedInput] = originalInput.getAccessor(state.store);
fetched.emplace(FetchedFlake{.lockedRef = lockedRef, .accessor = accessor}); fetched.emplace(CachedInput{.lockedInput = lockedInput, .accessor = accessor});
} else { } else {
if (useRegistries) { if (useRegistries) {
resolvedRef = originalRef.resolve( auto [res, extraAttrs] = lookupInRegistries(state.store, originalInput,
state.store,
[](fetchers::Registry::RegistryType type) { [](fetchers::Registry::RegistryType type) {
/* Only use the global registry and CLI flags /* Only use the global registry and CLI flags
to resolve indirect flakerefs. */ to resolve indirect flakerefs. */
return type == fetchers::Registry::Flag || type == fetchers::Registry::Global; return type == fetchers::Registry::Flag || type == fetchers::Registry::Global;
}); });
fetched = lookupInFlakeCache(flakeCache, originalRef); resolvedInput = std::move(res);
fetched = lookupInInputCache(inputCache, originalInput);
if (!fetched) { if (!fetched) {
auto [accessor, lockedRef] = resolvedRef.lazyFetch(state.store); auto [accessor, lockedInput] = resolvedInput.getAccessor(state.store);
fetched.emplace(FetchedFlake{.lockedRef = lockedRef, .accessor = accessor}); fetched.emplace(CachedInput{.lockedInput = lockedInput, .accessor = accessor});
} }
flakeCache.insert_or_assign(resolvedRef, *fetched); inputCache.insert_or_assign(resolvedInput, *fetched);
} }
else { 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 mountInput( static StorePath mountInput(
@ -136,7 +137,7 @@ static std::pair<std::map<FlakeId, FlakeInput>, fetchers::Attrs> parseFlakeInput
static void parseFlakeInputAttr( static void parseFlakeInputAttr(
EvalState & state, EvalState & state,
const Attr & attr, const nix::Attr & attr,
fetchers::Attrs & attrs) fetchers::Attrs & attrs)
{ {
// Allow selecting a subset of enum values // Allow selecting a subset of enum values
@ -407,13 +408,16 @@ static Flake getFlake(
EvalState & state, EvalState & state,
const FlakeRef & originalRef, const FlakeRef & originalRef,
bool useRegistries, bool useRegistries,
FlakeCache & flakeCache, InputCache & inputCache,
const InputAttrPath & lockRootAttrPath, const InputAttrPath & lockRootAttrPath,
CopyMode copyMode) CopyMode copyMode)
{ {
// Fetch a lazy tree first. // Fetch a lazy tree first.
auto [accessor, resolvedRef, lockedRef] = fetchOrSubstituteTree( auto [accessor, resolvedInput, lockedInput] = getAccessorCached(
state, originalRef, useRegistries, flakeCache); 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. // 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, {accessor}, lockRootAttrPath);
@ -425,10 +429,10 @@ static Flake getFlake(
debug("refetching input '%s' due to self attribute", newLockedRef); 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'. // FIXME: need to remove attrs that are invalidated by the changed input attrs, such as 'narHash'.
newLockedRef.input.attrs.erase("narHash"); newLockedRef.input.attrs.erase("narHash");
auto [accessor2, resolvedRef2, lockedRef2] = fetchOrSubstituteTree( auto [accessor2, resolvedInput2, lockedInput2] = getAccessorCached(
state, newLockedRef, false, flakeCache); state, newLockedRef.input, false, inputCache);
accessor = accessor2; accessor = accessor2;
lockedRef = lockedRef2; lockedRef = FlakeRef(std::move(lockedInput2), newLockedRef.subdir);
} }
// Re-parse flake.nix from the store. // Re-parse flake.nix from the store.
@ -440,8 +444,8 @@ static Flake getFlake(
Flake getFlake(EvalState & state, const FlakeRef & originalRef, bool useRegistries, CopyMode copyMode) Flake getFlake(EvalState & state, const FlakeRef & originalRef, bool useRegistries, CopyMode copyMode)
{ {
FlakeCache flakeCache; InputCache inputCache;
return getFlake(state, originalRef, useRegistries, flakeCache, {}, copyMode); return getFlake(state, originalRef, useRegistries, inputCache, {}, copyMode);
} }
static LockFile readLockFile( static LockFile readLockFile(
@ -461,11 +465,11 @@ LockedFlake lockFlake(
const FlakeRef & topRef, const FlakeRef & topRef,
const LockFlags & lockFlags) const LockFlags & lockFlags)
{ {
FlakeCache flakeCache; InputCache inputCache;
auto useRegistries = lockFlags.useRegistries.value_or(settings.useRegistries); auto useRegistries = lockFlags.useRegistries.value_or(settings.useRegistries);
auto flake = getFlake(state, topRef, useRegistries, flakeCache, {}, lockFlags.copyMode); auto flake = getFlake(state, topRef, useRegistries, inputCache, {}, lockFlags.copyMode);
if (lockFlags.applyNixConfig) { if (lockFlags.applyNixConfig) {
flake.config.apply(settings); flake.config.apply(settings);
@ -647,7 +651,7 @@ LockedFlake lockFlake(
if (auto resolvedPath = resolveRelativePath()) { if (auto resolvedPath = resolveRelativePath()) {
return readFlake(state, ref, ref, ref, *resolvedPath, inputAttrPath); return readFlake(state, ref, ref, ref, *resolvedPath, inputAttrPath);
} else { } else {
return getFlake(state, ref, useRegistries, flakeCache, inputAttrPath, inputCopyMode); return getFlake(state, ref, useRegistries, inputCache, inputAttrPath, inputCopyMode);
} }
}; };
@ -795,8 +799,10 @@ LockedFlake lockFlake(
if (auto resolvedPath = resolveRelativePath()) { if (auto resolvedPath = resolveRelativePath()) {
return {*resolvedPath, *input.ref}; return {*resolvedPath, *input.ref};
} else { } else {
auto [accessor, resolvedRef, lockedRef] = fetchOrSubstituteTree( auto [accessor, resolvedInput, lockedInput] = getAccessorCached(
state, *input.ref, useRegistries, flakeCache); state, input.ref->input, useRegistries, inputCache);
auto lockedRef = FlakeRef(std::move(lockedInput), input.ref->subdir);
return { return {
state.storePath(mountInput(state, lockedRef.input, input.ref->input, accessor, inputCopyMode)), state.storePath(mountInput(state, lockedRef.input, input.ref->input, accessor, inputCopyMode)),