Files
nix/src/libutil/nar-cache.cc
Eelco Dolstra 0b2dffefea Factor out NarCache from RemoteFSAccessor
Use

```
git show --color-moved --patience --color-moved-ws=ignore-all-space
```

to review and see that this is mostly code motion.

Co-Authored-By: John Ericson <John.Ericson@Obsidian.Systems>
2026-01-21 19:15:51 -05:00

85 lines
2.2 KiB
C++

#include "nix/util/nar-cache.hh"
#include "nix/util/file-system.hh"
#include <nlohmann/json.hpp>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
namespace nix {
NarCache::NarCache(std::optional<std::filesystem::path> cacheDir_)
: cacheDir(std::move(cacheDir_))
{
if (cacheDir)
createDirs(*cacheDir);
}
ref<SourceAccessor> NarCache::getOrInsert(const Hash & narHash, std::function<void(Sink &)> populate)
{
// Check in-memory cache first
if (auto * accessor = get(nars, narHash))
return *accessor;
auto cacheAccessor = [&](ref<SourceAccessor> accessor) {
nars.emplace(narHash, accessor);
return accessor;
};
auto getNar = [&]() {
StringSink sink;
populate(sink);
return std::move(sink.s);
};
if (cacheDir) {
auto makeCacheFile = [&](const std::string & ext) {
auto res = *cacheDir / narHash.to_string(HashFormat::Nix32, false);
res += ".";
res += ext;
return res;
};
auto cacheFile = makeCacheFile("nar");
auto listingFile = makeCacheFile("ls");
if (nix::pathExists(cacheFile)) {
try {
return cacheAccessor(makeLazyNarAccessor(
nlohmann::json::parse(nix::readFile(listingFile)).template get<NarListing>(),
seekableGetNarBytes(cacheFile)));
} catch (SystemError &) {
}
try {
return cacheAccessor(makeNarAccessor(nix::readFile(cacheFile)));
} catch (SystemError &) {
}
}
auto nar = getNar();
try {
/* FIXME: do this asynchronously. */
writeFile(cacheFile, nar);
} catch (...) {
ignoreExceptionExceptInterrupt();
}
auto narAccessor = makeNarAccessor(std::move(nar));
try {
nlohmann::json j = narAccessor->getListing();
writeFile(listingFile, j.dump());
} catch (...) {
ignoreExceptionExceptInterrupt();
}
return cacheAccessor(narAccessor);
}
return cacheAccessor(makeNarAccessor(getNar()));
}
} // namespace nix