1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-13 05:56:03 +01:00

Use shared pointers in the memory source accessor

This allows aliasing, like hard links.
This commit is contained in:
John Ericson 2025-09-19 12:09:46 -04:00 committed by Sergei Zimmerman
parent f66b56ad3f
commit 4df60e639b
No known key found for this signature in database
3 changed files with 23 additions and 15 deletions

View file

@ -233,30 +233,30 @@ TEST_F(GitTest, both_roundrip)
.contents{ .contents{
{ {
"foo", "foo",
File::Regular{ make_ref<File>(File::Regular{
.contents = "hello\n\0\n\tworld!", .contents = "hello\n\0\n\tworld!",
}, }),
}, },
{ {
"bar", "bar",
File::Directory{ make_ref<File>(File::Directory{
.contents = .contents =
{ {
{ {
"baz", "baz",
File::Regular{ make_ref<File>(File::Regular{
.executable = true, .executable = true,
.contents = "good day,\n\0\n\tworld!", .contents = "good day,\n\0\n\tworld!",
}, }),
}, },
{ {
"quux", "quux",
File::Symlink{ make_ref<File>(File::Symlink{
.target = "/over/there", .target = "/over/there",
}),
}, },
}, },
}, }),
},
}, },
}, },
}; };

View file

@ -35,7 +35,7 @@ struct MemorySourceAccessor : virtual SourceAccessor
{ {
using Name = std::string; using Name = std::string;
std::map<Name, File, std::less<>> contents; std::map<Name, ref<File>, std::less<>> contents;
bool operator==(const Directory &) const noexcept; bool operator==(const Directory &) const noexcept;
// TODO libc++ 16 (used by darwin) missing `std::map::operator <=>`, can't do yet. // TODO libc++ 16 (used by darwin) missing `std::map::operator <=>`, can't do yet.
@ -89,13 +89,21 @@ struct MemorySourceAccessor : virtual SourceAccessor
SourcePath addFile(CanonPath path, std::string && contents); SourcePath addFile(CanonPath path, std::string && contents);
}; };
inline bool MemorySourceAccessor::File::Directory::operator==( inline bool
const MemorySourceAccessor::File::Directory &) const noexcept = default; MemorySourceAccessor::File::Directory::operator==(const MemorySourceAccessor::File::Directory & other) const noexcept
{
return std::ranges::equal(contents, other.contents, [](const auto & lhs, const auto & rhs) -> bool {
return lhs.first == rhs.first && *lhs.second == *rhs.second;
});
};
inline bool inline bool
MemorySourceAccessor::File::Directory::operator<(const MemorySourceAccessor::File::Directory & other) const noexcept MemorySourceAccessor::File::Directory::operator<(const MemorySourceAccessor::File::Directory & other) const noexcept
{ {
return contents < other.contents; return std::ranges::lexicographical_compare(
contents, other.contents, [](const auto & lhs, const auto & rhs) -> bool {
return lhs.first < rhs.first && *lhs.second < *rhs.second;
});
} }
inline bool MemorySourceAccessor::File::operator==(const MemorySourceAccessor::File &) const noexcept = default; inline bool MemorySourceAccessor::File::operator==(const MemorySourceAccessor::File &) const noexcept = default;

View file

@ -24,11 +24,11 @@ MemorySourceAccessor::File * MemorySourceAccessor::open(const CanonPath & path,
i, i,
{ {
std::string{name}, std::string{name},
File::Directory{}, make_ref<File>(File::Directory{}),
}); });
} }
} }
cur = &i->second; cur = &*i->second;
} }
if (newF && create) if (newF && create)
@ -92,7 +92,7 @@ MemorySourceAccessor::DirEntries MemorySourceAccessor::readDirectory(const Canon
if (auto * d = std::get_if<File::Directory>(&f->raw)) { if (auto * d = std::get_if<File::Directory>(&f->raw)) {
DirEntries res; DirEntries res;
for (auto & [name, file] : d->contents) for (auto & [name, file] : d->contents)
res.insert_or_assign(name, file.lstat().type); res.insert_or_assign(name, file->lstat().type);
return res; return res;
} else } else
throw Error("file '%s' is not a directory", path); throw Error("file '%s' is not a directory", path);