More inode methods

This commit is contained in:
Marcus Holland-Moritz 2023-08-12 11:16:26 +02:00
parent b49dd782c6
commit a90768ae0f
2 changed files with 47 additions and 0 deletions

View File

@ -51,8 +51,12 @@ class inode : public object {
virtual void scan(mmif* mm, inode_options const& options) = 0; virtual void scan(mmif* mm, inode_options const& options) = 0;
virtual void set_num(uint32_t num) = 0; virtual void set_num(uint32_t num) = 0;
virtual uint32_t num() const = 0; virtual uint32_t num() const = 0;
virtual bool has_category(fragment_category cat) const = 0;
virtual uint32_t similarity_hash() const = 0; virtual uint32_t similarity_hash() const = 0;
virtual uint32_t similarity_hash(fragment_category cat) const = 0;
virtual nilsimsa::hash_type const& nilsimsa_similarity_hash() const = 0; virtual nilsimsa::hash_type const& nilsimsa_similarity_hash() const = 0;
virtual nilsimsa::hash_type const&
nilsimsa_similarity_hash(fragment_category cat) const = 0;
virtual size_t size() const = 0; virtual size_t size() const = 0;
virtual file const* any() const = 0; virtual file const* any() const = 0;
virtual files_vector const& files() const = 0; virtual files_vector const& files() const = 0;

View File

@ -36,6 +36,7 @@
#include <fmt/format.h> #include <fmt/format.h>
#include <folly/Demangle.h>
#include <folly/small_vector.h> #include <folly/small_vector.h>
#include <folly/sorted_vector_types.h> #include <folly/sorted_vector_types.h>
@ -120,10 +121,21 @@ class inode_ : public inode {
return num_; return num_;
} }
bool has_category(fragment_category cat) const override {
DWARFS_CHECK(!fragments_.empty(),
"has_category() called with no fragments");
if (fragments_.size() == 1) {
return fragments_.get_single_category() == cat;
}
auto& m = std::get<similarity_map_type>(similarity_);
return m.find(cat) != m.end();
}
uint32_t similarity_hash() const override { uint32_t similarity_hash() const override {
if (files_.empty()) { if (files_.empty()) {
DWARFS_THROW(runtime_error, "inode has no file (similarity)"); DWARFS_THROW(runtime_error, "inode has no file (similarity)");
} }
// TODO
return similarity_hash_; return similarity_hash_;
} }
@ -131,9 +143,19 @@ class inode_ : public inode {
if (files_.empty()) { if (files_.empty()) {
DWARFS_THROW(runtime_error, "inode has no file (nilsimsa)"); DWARFS_THROW(runtime_error, "inode has no file (nilsimsa)");
} }
// TODO
return nilsimsa_similarity_hash_; return nilsimsa_similarity_hash_;
} }
uint32_t similarity_hash(fragment_category cat) const override {
return find_similarity<uint32_t>(cat);
}
nilsimsa::hash_type const&
nilsimsa_similarity_hash(fragment_category cat) const override {
return find_similarity<nilsimsa::hash_type>(cat);
}
void set_files(files_vector&& fv) override { void set_files(files_vector&& fv) override {
if (!files_.empty()) { if (!files_.empty()) {
DWARFS_THROW(runtime_error, "files already set for inode"); DWARFS_THROW(runtime_error, "files already set for inode");
@ -307,6 +329,27 @@ class inode_ : public inode {
} }
private: private:
template <typename T>
T const& find_similarity(fragment_category cat) const {
if (fragments_.empty()) [[unlikely]] {
DWARFS_THROW(runtime_error, fmt::format("inode has no fragments ({})",
folly::demangle(typeid(T))));
}
if (fragments_.size() == 1) {
if (fragments_.get_single_category() != cat) [[unlikely]] {
DWARFS_THROW(runtime_error, fmt::format("category mismatch ({})",
folly::demangle(typeid(T))));
}
return std::get<T>(similarity_);
}
auto& m = std::get<similarity_map_type>(similarity_);
if (auto it = m.find(cat); it != m.end()) {
return std::get<T>(it->second);
}
DWARFS_THROW(runtime_error, fmt::format("category not found ({})",
folly::demangle(typeid(T))));
}
template <typename T> template <typename T>
void scan_range(mmif* mm, size_t offset, size_t size, T&& scanner) { void scan_range(mmif* mm, size_t offset, size_t size, T&& scanner) {
static constexpr size_t const chunk_size = 32 << 20; static constexpr size_t const chunk_size = 32 << 20;