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:
parent
f45db85887
commit
0cb06d7eda
1 changed files with 47 additions and 41 deletions
|
@ -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)),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue