diff --git a/include/dwarfs/fstypes.h b/include/dwarfs/fstypes.h index d5bc053e..fe7f5f23 100644 --- a/include/dwarfs/fstypes.h +++ b/include/dwarfs/fstypes.h @@ -24,7 +24,9 @@ #include #include #include +#include #include +#include #include "dwarfs/block_compressor.h" // TODO: or the other way round? #include "dwarfs/checksum.h" @@ -90,6 +92,8 @@ struct filesystem_info { uint64_t uncompressed_metadata_size{0}; bool uncompressed_block_size_is_estimate{false}; bool uncompressed_metadata_size_is_estimate{false}; + std::vector compressed_block_sizes; + std::vector> uncompressed_block_sizes; }; bool is_known_compression_type(compression_type type); diff --git a/src/dwarfs/filesystem_v2.cpp b/src/dwarfs/filesystem_v2.cpp index 60ae6e61..0cac3cb9 100644 --- a/src/dwarfs/filesystem_v2.cpp +++ b/src/dwarfs/filesystem_v2.cpp @@ -443,19 +443,22 @@ filesystem_info const& filesystem_::get_info() const { if (s->type() == section_type::BLOCK) { ++info.block_count; info.compressed_block_size += s->length(); + info.compressed_block_sizes.push_back(s->length()); try { - info.uncompressed_block_size += - get_uncompressed_section_size(mm_, *s); - } catch (std::exception const& e) { + auto uncompressed_size = get_uncompressed_section_size(mm_, *s); + info.uncompressed_block_size += uncompressed_size; + info.uncompressed_block_sizes.push_back(uncompressed_size); + } catch (std::exception const&) { info.uncompressed_block_size += s->length(); info.uncompressed_block_size_is_estimate = true; + info.uncompressed_block_sizes.push_back(std::nullopt); } } else if (s->type() == section_type::METADATA_V2) { info.compressed_metadata_size += s->length(); try { info.uncompressed_metadata_size += get_uncompressed_section_size(mm_, *s); - } catch (std::exception const& e) { + } catch (std::exception const&) { info.uncompressed_metadata_size += s->length(); info.uncompressed_metadata_size_is_estimate = true; } diff --git a/src/dwarfs/metadata_v2.cpp b/src/dwarfs/metadata_v2.cpp index 11642e21..59a30f38 100644 --- a/src/dwarfs/metadata_v2.cpp +++ b/src/dwarfs/metadata_v2.cpp @@ -37,6 +37,7 @@ #include +#include #include #include #include @@ -990,6 +991,43 @@ void metadata_::dump( } } + if (meta_.block_categories()) { + auto const& catnames = *meta_.category_names(); + struct category_info { + size_t count{0}; + size_t compressed_size{0}; + size_t uncompressed_size{0}; + bool uncompressed_size_is_estimate{false}; + }; + std::map catinfo; + for (auto [block, category] : folly::enumerate(*meta_.block_categories())) { + auto& ci = catinfo[category]; + ++ci.count; + ci.compressed_size += fsinfo.compressed_block_sizes.at(block); + if (auto size = fsinfo.uncompressed_block_sizes.at(block)) { + ci.uncompressed_size += *size; + } else { + ci.uncompressed_size_is_estimate = true; + } + } + os << "categories:\n"; + for (auto const& [category, ci] : catinfo) { + os << " " << catnames[category] << ": " << ci.count << " blocks"; + if (ci.uncompressed_size_is_estimate || + ci.uncompressed_size != ci.compressed_size) { + os << ", " << size_with_unit(ci.compressed_size) << " compressed"; + } + if (!ci.uncompressed_size_is_estimate) { + os << ", " << size_with_unit(ci.uncompressed_size) << " uncompressed"; + if (ci.uncompressed_size != ci.compressed_size) { + os << fmt::format(" ({0:.2f}%)", (100.0 * ci.compressed_size) / + ci.uncompressed_size); + } + } + os << "\n"; + } + } + if (detail_level > 1) { analyze_frozen(os, meta_, data_.size(), detail_level); }