Add support for category metadata

This commit is contained in:
Marcus Holland-Moritz 2023-07-18 14:31:42 +02:00
parent a9bf89aa0c
commit c6206653d2
5 changed files with 36 additions and 5 deletions

View File

@ -30,6 +30,8 @@
#include <span> #include <span>
#include <string_view> #include <string_view>
#include <folly/dynamic.h>
#include "dwarfs/inode_fragments.h" #include "dwarfs/inode_fragments.h"
namespace boost::program_options { namespace boost::program_options {
@ -50,6 +52,7 @@ class categorizer {
virtual std::span<std::string_view const> categories() const = 0; virtual std::span<std::string_view const> categories() const = 0;
virtual bool is_single_fragment() const = 0; virtual bool is_single_fragment() const = 0;
virtual folly::dynamic category_metadata(fragment_category c) const = 0;
}; };
class random_access_categorizer : public categorizer { class random_access_categorizer : public categorizer {
@ -132,6 +135,10 @@ class categorizer_manager {
return impl_->category_name(c); return impl_->category_name(c);
} }
folly::dynamic category_metadata(fragment_category c) const {
return impl_->category_metadata(c);
}
class impl { class impl {
public: public:
virtual ~impl() = default; virtual ~impl() = default;
@ -140,6 +147,7 @@ class categorizer_manager {
virtual categorizer_job job(std::filesystem::path const& path) const = 0; virtual categorizer_job job(std::filesystem::path const& path) const = 0;
virtual std::string_view virtual std::string_view
category_name(fragment_category::value_type c) const = 0; category_name(fragment_category::value_type c) const = 0;
virtual folly::dynamic category_metadata(fragment_category c) const = 0;
}; };
private: private:

View File

@ -185,6 +185,8 @@ class categorizer_manager_ final : public categorizer_manager_private {
std::string_view std::string_view
category_name(fragment_category::value_type c) const override; category_name(fragment_category::value_type c) const override;
folly::dynamic category_metadata(fragment_category c) const override;
std::vector<std::shared_ptr<categorizer const>> const& std::vector<std::shared_ptr<categorizer const>> const&
categorizers() const override { categorizers() const override {
return categorizers_; return categorizers_;
@ -201,9 +203,9 @@ class categorizer_manager_ final : public categorizer_manager_private {
} }
private: private:
void add_category(std::string_view cat) { void add_category(std::string_view cat, size_t categorizer_index) {
if (catmap_.emplace(cat, categories_.size()).second) { if (catmap_.emplace(cat, categories_.size()).second) {
categories_.emplace_back(cat); categories_.emplace_back(cat, categorizer_index);
} else { } else {
LOG_WARN << "duplicate category: " << cat; LOG_WARN << "duplicate category: " << cat;
} }
@ -212,7 +214,7 @@ class categorizer_manager_ final : public categorizer_manager_private {
logger& lgr_; logger& lgr_;
LOG_PROXY_DECL(LoggerPolicy); LOG_PROXY_DECL(LoggerPolicy);
std::vector<std::shared_ptr<categorizer const>> categorizers_; std::vector<std::shared_ptr<categorizer const>> categorizers_;
std::vector<std::string_view> categories_; std::vector<std::pair<std::string_view, size_t>> categories_;
std::unordered_map<std::string_view, fragment_category::value_type> catmap_; std::unordered_map<std::string_view, fragment_category::value_type> catmap_;
bool has_multi_fragment_sequential_categorizers_{false}; bool has_multi_fragment_sequential_categorizers_{false};
}; };
@ -221,7 +223,7 @@ template <typename LoggerPolicy>
void categorizer_manager_<LoggerPolicy>::add( void categorizer_manager_<LoggerPolicy>::add(
std::shared_ptr<categorizer const> c) { std::shared_ptr<categorizer const> c) {
for (auto const& c : c->categories()) { for (auto const& c : c->categories()) {
add_category(c); add_category(c, categorizers_.size());
} }
if (!c->is_single_fragment() && if (!c->is_single_fragment() &&
@ -243,7 +245,15 @@ categorizer_job categorizer_manager_<LoggerPolicy>::job(
template <typename LoggerPolicy> template <typename LoggerPolicy>
std::string_view categorizer_manager_<LoggerPolicy>::category_name( std::string_view categorizer_manager_<LoggerPolicy>::category_name(
fragment_category::value_type c) const { fragment_category::value_type c) const {
return DWARFS_NOTHROW(categories_.at(c)); return DWARFS_NOTHROW(categories_.at(c)).first;
}
template <typename LoggerPolicy>
folly::dynamic categorizer_manager_<LoggerPolicy>::category_metadata(
fragment_category c) const {
auto categorizer =
DWARFS_NOTHROW(categorizers_.at(categories_.at(c.value()).second));
return categorizer->category_metadata(c);
} }
categorizer_manager::categorizer_manager(logger& lgr) categorizer_manager::categorizer_manager(logger& lgr)

View File

@ -64,6 +64,10 @@ class binary_categorizer_ final : public binary_categorizer_base {
bool is_single_fragment() const override { return false; } bool is_single_fragment() const override { return false; }
folly::dynamic category_metadata(fragment_category) const override {
return folly::dynamic();
}
private: private:
LOG_PROXY_DECL(LoggerPolicy); LOG_PROXY_DECL(LoggerPolicy);
}; };

View File

@ -156,8 +156,13 @@ class incompressible_categorizer_ final : public sequential_categorizer {
std::unique_ptr<sequential_categorizer_job> std::unique_ptr<sequential_categorizer_job>
job(std::filesystem::path const& path, size_t total_size, job(std::filesystem::path const& path, size_t total_size,
category_mapper const& mapper) const override; category_mapper const& mapper) const override;
bool is_single_fragment() const override { return true; } bool is_single_fragment() const override { return true; }
folly::dynamic category_metadata(fragment_category) const override {
return folly::dynamic();
}
private: private:
logger& lgr_; logger& lgr_;
incompressible_categorizer_config const config_; incompressible_categorizer_config const config_;

View File

@ -149,6 +149,10 @@ class libmagic_categorizer_ final : public libmagic_categorizer_base {
bool is_single_fragment() const override { return true; } bool is_single_fragment() const override { return true; }
folly::dynamic category_metadata(fragment_category) const override {
return folly::dynamic();
}
private: private:
LOG_PROXY_DECL(LoggerPolicy); LOG_PROXY_DECL(LoggerPolicy);
magic_wrapper m_; magic_wrapper m_;