From e67d3df41ac509c62956f681deb8c98d76bfbcdd Mon Sep 17 00:00:00 2001 From: Marcus Holland-Moritz Date: Wed, 24 Mar 2021 22:57:30 +0100 Subject: [PATCH] Unpack fields for metadata export --- include/dwarfs/metadata_types.h | 4 ++++ include/dwarfs/string_table.h | 6 ++++++ src/dwarfs/metadata_v2.cpp | 36 +++++++++++++++++++++++++++++++-- src/dwarfs/string_table.cpp | 20 ++++++++++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/include/dwarfs/metadata_types.h b/include/dwarfs/metadata_types.h index 88dd34f1..d84008af 100644 --- a/include/dwarfs/metadata_types.h +++ b/include/dwarfs/metadata_types.h @@ -57,6 +57,10 @@ class global_metadata { string_table const& names() const { return names_; } + std::vector const& directories() const { + return directories_storage_; + } + private: Meta const* const meta_; std::vector const directories_storage_; diff --git a/include/dwarfs/string_table.h b/include/dwarfs/string_table.h index feafcb19..f4724fa9 100644 --- a/include/dwarfs/string_table.h +++ b/include/dwarfs/string_table.h @@ -56,6 +56,10 @@ class string_table { std::string operator[](size_t index) const { return impl_->lookup(index); } + std::vector unpack() const { return impl_->unpack(); } + + bool is_packed() const { return impl_->is_packed(); } + static thrift::metadata::string_table pack(std::vector const& input, pack_options const& options = pack_options()); @@ -65,6 +69,8 @@ class string_table { virtual ~impl() = default; virtual std::string lookup(size_t index) const = 0; + virtual std::vector unpack() const = 0; + virtual bool is_packed() const = 0; }; private: diff --git a/src/dwarfs/metadata_v2.cpp b/src/dwarfs/metadata_v2.cpp index bc335e39..c39d538e 100644 --- a/src/dwarfs/metadata_v2.cpp +++ b/src/dwarfs/metadata_v2.cpp @@ -371,6 +371,8 @@ class metadata_ final : public metadata_v2::impl { template using set_type = folly::F14ValueSet; + thrift::metadata::metadata unpack_metadata() const; + inode_view make_inode_view(uint32_t inode) const { // TODO: move compatibility details to metadata_types uint32_t index = @@ -899,15 +901,45 @@ folly::dynamic metadata_::as_dynamic() const { return obj; } +template +thrift::metadata::metadata metadata_::unpack_metadata() const { + auto meta = meta_.thaw(); + + if (auto opts = meta.options_ref()) { + if (opts->packed_chunk_table) { + meta.chunk_table = chunk_table_; + } + if (opts->packed_directories) { + meta.directories = global_.directories(); + } + if (opts->packed_shared_files_table) { + meta.shared_files_table_ref() = shared_files_; + } + if (auto const& names = global_.names(); names.is_packed()) { + meta.names = names.unpack(); + meta.compact_names_ref().reset(); + } + if (symlinks_.is_packed()) { + meta.symlinks = symlinks_.unpack(); + meta.compact_symlinks_ref().reset(); + } + opts->packed_chunk_table = false; + opts->packed_directories = false; + opts->packed_shared_files_table = false; + } + + return meta; +} + template std::string metadata_::serialize_as_json(bool simple) const { std::string json; if (simple) { apache::thrift::SimpleJSONSerializer serializer; - serializer.serialize(meta_.thaw(), &json); + serializer.serialize(unpack_metadata(), &json); } else { apache::thrift::JSONSerializer serializer; - serializer.serialize(meta_.thaw(), &json); + serializer.serialize(unpack_metadata(), &json); } return json; } diff --git a/src/dwarfs/string_table.cpp b/src/dwarfs/string_table.cpp index c8ebecfd..49194794 100644 --- a/src/dwarfs/string_table.cpp +++ b/src/dwarfs/string_table.cpp @@ -41,6 +41,12 @@ class legacy_string_table : public string_table::impl { return std::string(v_[index]); } + std::vector unpack() const override { + throw std::runtime_error("cannot unpack legacy string table"); + } + + bool is_packed() const override { return false; } + private: string_table::LegacyTableView v_; }; @@ -113,6 +119,20 @@ class packed_string_table : public string_table::impl { return std::string(beg, end); } + std::vector unpack() const override { + std::vector v; + auto size = PackedIndex ? index_.size() : v_.index().size(); + if (size > 0) { + v.reserve(size - 1); + for (size_t i = 0; i < size - 1; ++i) { + v.emplace_back(lookup(i)); + } + } + return v; + } + + bool is_packed() const override { return true; } + private: string_table::PackedTableView v_; char const* const buffer_;