11#include < nlohmann/json.hpp>
22#include " nix/store/remote-fs-accessor.hh"
33#include " nix/store/nar-accessor.hh"
4-
5- #include < sys/types.h>
6- #include < sys/stat.h>
7- #include < fcntl.h>
4+ #include " nix/store/nar-cache.hh"
85
96namespace nix {
107
11- RemoteFSAccessor::RemoteFSAccessor (ref<Store> store, bool requireValidPath, std::filesystem::path cacheDir_ )
8+ RemoteFSAccessor::RemoteFSAccessor (ref<Store> store, bool requireValidPath, std::shared_ptr<NarCache> narCache )
129 : store(store)
1310 , requireValidPath(requireValidPath)
14- , cacheDir(std::move(cacheDir_))
15- {
16- if (!cacheDir.empty ())
17- createDirs (cacheDir);
18- }
19-
20- std::filesystem::path RemoteFSAccessor::makeCacheFile (const Hash & narHash, const std::string & ext)
21- {
22- assert (!cacheDir.empty ());
23- return (cacheDir / narHash.to_string (HashFormat::Nix32, false )) + " ." + ext;
24- }
25-
26- ref<SourceAccessor> RemoteFSAccessor::addToCache (
27- std::string_view hashPart,
28- const std::filesystem::path & cacheFile,
29- const std::filesystem::path & listingFile,
30- std::string && nar)
11+ , narCache(std::move(narCache))
3112{
32- if (!cacheFile.empty ()) {
33- try {
34- /* FIXME: do this asynchronously. */
35- writeFile (cacheFile, nar);
36- } catch (...) {
37- ignoreExceptionExceptInterrupt ();
38- }
39- }
40-
41- auto narAccessor = makeNarAccessor (std::move (nar));
42- nars.emplace (hashPart, narAccessor);
43-
44- if (!listingFile.empty ()) {
45- try {
46- nlohmann::json j = listNar (narAccessor, CanonPath::root, true );
47- writeFile (listingFile, j.dump ());
48- } catch (...) {
49- ignoreExceptionExceptInterrupt ();
50- }
51- }
52-
53- return narAccessor;
5413}
5514
5615std::pair<ref<SourceAccessor>, CanonPath> RemoteFSAccessor::fetch (const CanonPath & path)
@@ -67,55 +26,46 @@ std::shared_ptr<SourceAccessor> RemoteFSAccessor::accessObject(const StorePath &
6726 if (i != nars.end ())
6827 return i->second ;
6928
70- std::filesystem::path cacheFile, listingFile ;
29+ Hash narHash{HashAlgorithm::SHA256} ;
7130
72- if (!cacheDir. empty () ) {
31+ if (narCache ) {
7332 auto info = store->queryPathInfo (storePath);
33+ narHash = info->narHash ;
7434
75- cacheFile = makeCacheFile (info->narHash , " nar" );
76- listingFile = makeCacheFile (info->narHash , " ls" );
77-
78- if (nix::pathExists (cacheFile)) {
79- try {
80- auto listing = nix::readFile (listingFile);
81- auto narAccessor = makeLazyNarAccessor (listing, [cacheFile](uint64_t offset, uint64_t length) {
82- AutoCloseFD fd = toDescriptor (open (
83- cacheFile.c_str (),
84- O_RDONLY
85- #ifndef _WIN32
86- | O_CLOEXEC
87- #endif
88- ));
89- if (!fd)
90- throw SysError (" opening NAR cache file '%s'" , cacheFile);
91-
92- if (lseek (fromDescriptorReadOnly (fd.get ()), offset, SEEK_SET) != (off_t ) offset)
93- throw SysError (" seeking in '%s'" , cacheFile);
94-
95- std::string buf (length, 0 );
96- readFull (fd.get (), buf.data (), length);
97-
98- return buf;
35+ if (auto listingData = narCache->getNarListing (narHash)) {
36+ auto narAccessor =
37+ makeLazyNarAccessor (*listingData, [narCache (narCache), narHash](uint64_t offset, uint64_t length) {
38+ return narCache->getNarBytes (narHash, offset, length);
9939 });
10040
101- nars.emplace (storePath.hashPart (), narAccessor);
102- return narAccessor;
103-
104- } catch (SystemError &) {
105- }
41+ nars.emplace (storePath.hashPart (), narAccessor);
42+ return narAccessor;
43+ }
10644
107- try {
108- auto narAccessor = makeNarAccessor (nix::readFile (cacheFile));
109- nars.emplace (storePath.hashPart (), narAccessor);
110- return narAccessor;
111- } catch (SystemError &) {
112- }
45+ if (auto nar = narCache->getNar (narHash)) {
46+ auto narAccessor = makeNarAccessor (std::move (*nar));
47+ nars.emplace (storePath.hashPart (), narAccessor);
48+ return narAccessor;
11349 }
11450 }
11551
11652 StringSink sink;
11753 store->narFromPath (storePath, sink);
118- return addToCache (storePath.hashPart (), cacheFile, listingFile, std::move (sink.s ));
54+
55+ if (narCache) {
56+ StringSource source{sink.s };
57+ narCache->upsertNar (narHash, source);
58+ }
59+
60+ auto narAccessor = makeNarAccessor (std::move (sink.s ));
61+ nars.emplace (storePath.hashPart (), narAccessor);
62+
63+ if (narCache) {
64+ nlohmann::json j = listNar (narAccessor, CanonPath::root, true );
65+ narCache->upsertNarListing (narHash, j.dump ());
66+ }
67+
68+ return narAccessor;
11969}
12070
12171std::optional<SourceAccessor::Stat> RemoteFSAccessor::maybeLstat (const CanonPath & path)
0 commit comments