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:
parent
f66b56ad3f
commit
4df60e639b
3 changed files with 23 additions and 15 deletions
|
|
@ -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",
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue