mirror of
https://github.com/NixOS/nix
synced 2025-06-24 22:11:15 +02:00
Move the input cache into libfetchers
This commit is contained in:
parent
c7f8147282
commit
012453d1e6
7 changed files with 84 additions and 35 deletions
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
22
src/libfetchers/include/nix/fetchers/input-cache.hh
Normal file
22
src/libfetchers/include/nix/fetchers/input-cache.hh
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include "fetchers.hh"
|
||||
|
||||
namespace nix::fetchers {
|
||||
|
||||
struct CachedInput
|
||||
{
|
||||
Input lockedInput;
|
||||
ref<SourceAccessor> accessor;
|
||||
};
|
||||
|
||||
struct InputCache
|
||||
{
|
||||
virtual std::optional<CachedInput> lookup(const Input & originalInput) const = 0;
|
||||
|
||||
virtual void upsert(Input key, CachedInput cachedInput) = 0;
|
||||
|
||||
virtual void clear() = 0;
|
||||
|
||||
static ref<InputCache> getCache();
|
||||
};
|
||||
|
||||
}
|
|
@ -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',
|
||||
|
|
41
src/libfetchers/input-cache.cc
Normal file
41
src/libfetchers/input-cache.cc
Normal file
|
@ -0,0 +1,41 @@
|
|||
#include "nix/fetchers/input-cache.hh"
|
||||
#include "nix/util/sync.hh"
|
||||
|
||||
namespace nix::fetchers {
|
||||
|
||||
struct InputCacheImpl : InputCache
|
||||
{
|
||||
Sync<std::map<Input, CachedInput>> cache_;
|
||||
|
||||
std::optional<CachedInput> 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> InputCache::getCache()
|
||||
{
|
||||
static auto cache = make_ref<InputCacheImpl>();
|
||||
return cache;
|
||||
}
|
||||
|
||||
}
|
|
@ -44,6 +44,7 @@ sources = files(
|
|||
'git.cc',
|
||||
'github.cc',
|
||||
'indirect.cc',
|
||||
'input-cache.cc',
|
||||
'mercurial.cc',
|
||||
'path.cc',
|
||||
'registry.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::LockedFlake>(nix::flake::lockFlake(
|
||||
*flakeSettings->settings, eval_state->state, *flakeReference->flakeRef, *flags->lockFlags));
|
||||
return new nix_locked_flake{lockedFlake};
|
||||
|
|
|
@ -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 <nlohmann/json.hpp>
|
||||
|
||||
|
@ -23,32 +24,14 @@ using namespace flake;
|
|||
|
||||
namespace flake {
|
||||
|
||||
struct CachedInput
|
||||
{
|
||||
Input lockedInput;
|
||||
ref<SourceAccessor> accessor;
|
||||
};
|
||||
|
||||
typedef std::map<Input, CachedInput> InputCache;
|
||||
|
||||
static std::optional<CachedInput> 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<ref<SourceAccessor>, 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<ref<SourceAccessor>, 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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue