feat(internal): allow storing "." and ".." in dir_entry_view_impl

This commit is contained in:
Marcus Holland-Moritz 2024-08-23 16:05:38 +02:00
parent b45d9c1870
commit 40e43a153f
2 changed files with 66 additions and 33 deletions

View File

@ -34,6 +34,7 @@
#include <dwarfs/file_stat.h>
#include <dwarfs/file_type.h>
#include <dwarfs/internal/packed_ptr.h>
#include <dwarfs/internal/string_table.h>
#include <dwarfs/gen-cpp2/metadata_layouts.h>
@ -119,38 +120,49 @@ class dir_entry_view_impl {
using DirEntryView =
::apache::thrift::frozen::View<thrift::metadata::dir_entry>;
enum class entry_name_type : uint8_t {
other,
self,
parent,
};
dir_entry_view_impl(DirEntryView v, uint32_t self_index,
uint32_t parent_index, global_metadata const& g)
uint32_t parent_index, global_metadata const& g,
entry_name_type name_type)
: v_{v}
, self_index_{self_index}
, parent_index_{parent_index}
, g_{&g} {}
, g_{&g, name_type} {}
dir_entry_view_impl(InodeView v, uint32_t self_index, uint32_t parent_index,
global_metadata const& g)
global_metadata const& g, entry_name_type name_type)
: v_{v}
, self_index_{self_index}
, parent_index_{parent_index}
, g_{&g} {}
, g_{&g, name_type} {}
static std::shared_ptr<dir_entry_view_impl>
from_dir_entry_index_shared(uint32_t self_index, uint32_t parent_index,
global_metadata const& g);
static std::shared_ptr<dir_entry_view_impl>
from_dir_entry_index_shared(uint32_t self_index, global_metadata const& g);
static std::shared_ptr<dir_entry_view_impl> from_dir_entry_index_shared(
uint32_t self_index, uint32_t parent_index, global_metadata const& g,
entry_name_type name_type = entry_name_type::other);
static std::shared_ptr<dir_entry_view_impl> from_dir_entry_index_shared(
uint32_t self_index, global_metadata const& g,
entry_name_type name_type = entry_name_type::other);
static dir_entry_view_impl
from_dir_entry_index(uint32_t self_index, uint32_t parent_index,
global_metadata const& g);
global_metadata const& g,
entry_name_type name_type = entry_name_type::other);
static dir_entry_view_impl
from_dir_entry_index(uint32_t self_index, global_metadata const& g);
from_dir_entry_index(uint32_t self_index, global_metadata const& g,
entry_name_type name_type = entry_name_type::other);
// TODO: this works, but it's strange; a limited version of
// dir_entry_view_impl
// should work without a parent for these use cases
static std::string name(uint32_t index, global_metadata const& g);
static std::string
name(uint32_t index, global_metadata const& g); // TODO: remove?
static std::shared_ptr<inode_view_impl>
inode_shared(uint32_t index, global_metadata const& g);
inode_shared(uint32_t index, global_metadata const& g); // TODO: remove?
std::string name() const;
std::shared_ptr<inode_view_impl> inode_shared() const;
@ -175,16 +187,18 @@ class dir_entry_view_impl {
auto make_inode() const;
template <template <typename...> class Ctor>
static auto make_dir_entry_view(uint32_t self_index, uint32_t parent_index,
global_metadata const& g);
static auto
make_dir_entry_view(uint32_t self_index, uint32_t parent_index,
global_metadata const& g, entry_name_type name_type);
template <template <typename...> class Ctor>
static auto
make_dir_entry_view(uint32_t self_index, global_metadata const& g);
static auto make_dir_entry_view(uint32_t self_index, global_metadata const& g,
entry_name_type name_type);
std::variant<DirEntryView, InodeView> v_;
uint32_t self_index_, parent_index_;
global_metadata const* g_;
dwarfs::internal::packed_ptr<global_metadata const, 2, entry_name_type> const
g_;
};
using chunk_view = ::apache::thrift::frozen::View<thrift::metadata::chunk>;

View File

@ -809,6 +809,15 @@ auto inode_view_impl::getgid() const -> gid_type {
// TODO: pretty certain some of this stuff can be simplified
std::string dir_entry_view_impl::name() const {
switch (g_.get_data()) {
case entry_name_type::other:
break;
case entry_name_type::self:
return ".";
case entry_name_type::parent:
return "..";
}
return v_ |
match{
[this](DirEntryView const& dev) {
@ -859,7 +868,8 @@ bool dir_entry_view_impl::is_root() const {
template <template <typename...> class Ctor>
auto dir_entry_view_impl::make_dir_entry_view(uint32_t self_index,
uint32_t parent_index,
global_metadata const& g) {
global_metadata const& g,
entry_name_type name_type) {
auto& meta = g.meta();
if (auto de = meta.dir_entries()) {
@ -872,7 +882,8 @@ auto dir_entry_view_impl::make_dir_entry_view(uint32_t self_index,
auto dev = (*de)[self_index];
return Ctor<dir_entry_view_impl>()(dev, self_index, parent_index, g);
return Ctor<dir_entry_view_impl>()(dev, self_index, parent_index, g,
name_type);
}
DWARFS_CHECK(self_index < meta.inodes().size(),
@ -884,12 +895,14 @@ auto dir_entry_view_impl::make_dir_entry_view(uint32_t self_index,
auto iv = meta.inodes()[self_index];
return Ctor<dir_entry_view_impl>()(iv, self_index, parent_index, g);
return Ctor<dir_entry_view_impl>()(iv, self_index, parent_index, g,
name_type);
}
template <template <typename...> class Ctor>
auto dir_entry_view_impl::make_dir_entry_view(uint32_t self_index,
global_metadata const& g) {
global_metadata const& g,
entry_name_type name_type) {
auto& meta = g.meta();
if (auto de = meta.dir_entries()) {
@ -900,8 +913,8 @@ auto dir_entry_view_impl::make_dir_entry_view(uint32_t self_index,
DWARFS_CHECK(dev.inode_num() < meta.directories().size(),
fmt::format("inode_num out of range: {0} >= {1}",
dev.inode_num(), meta.directories().size()));
return Ctor<dir_entry_view_impl>()(dev, self_index,
g.parent_dir_entry(dev.inode_num()), g);
return Ctor<dir_entry_view_impl>()(
dev, self_index, g.parent_dir_entry(dev.inode_num()), g, name_type);
}
DWARFS_CHECK(self_index < meta.inodes().size(),
@ -916,33 +929,39 @@ auto dir_entry_view_impl::make_dir_entry_view(uint32_t self_index,
iv, self_index,
meta.entry_table_v2_2()[meta.directories()[iv.inode_v2_2()]
.parent_entry()],
g);
g, name_type);
}
std::shared_ptr<dir_entry_view_impl>
dir_entry_view_impl::from_dir_entry_index_shared(uint32_t self_index,
uint32_t parent_index,
global_metadata const& g) {
return make_dir_entry_view<shared_ptr_ctor>(self_index, parent_index, g);
global_metadata const& g,
entry_name_type name_type) {
return make_dir_entry_view<shared_ptr_ctor>(self_index, parent_index, g,
name_type);
}
std::shared_ptr<dir_entry_view_impl>
dir_entry_view_impl::from_dir_entry_index_shared(uint32_t self_index,
global_metadata const& g) {
return make_dir_entry_view<shared_ptr_ctor>(self_index, g);
global_metadata const& g,
entry_name_type name_type) {
return make_dir_entry_view<shared_ptr_ctor>(self_index, g, name_type);
}
dir_entry_view_impl
dir_entry_view_impl::from_dir_entry_index(uint32_t self_index,
uint32_t parent_index,
global_metadata const& g) {
return make_dir_entry_view<stack_ctor>(self_index, parent_index, g);
global_metadata const& g,
entry_name_type name_type) {
return make_dir_entry_view<stack_ctor>(self_index, parent_index, g,
name_type);
}
dir_entry_view_impl
dir_entry_view_impl::from_dir_entry_index(uint32_t self_index,
global_metadata const& g) {
return make_dir_entry_view<stack_ctor>(self_index, g);
global_metadata const& g,
entry_name_type name_type) {
return make_dir_entry_view<stack_ctor>(self_index, g, name_type);
}
std::shared_ptr<dir_entry_view_impl> dir_entry_view_impl::parent() const {