diff --git a/include/dwarfs/inode.h b/include/dwarfs/inode.h index 45266929..0e9edd74 100644 --- a/include/dwarfs/inode.h +++ b/include/dwarfs/inode.h @@ -27,6 +27,7 @@ #include +#include "dwarfs/nilsimsa.h" #include "dwarfs/object.h" namespace dwarfs { @@ -50,7 +51,7 @@ class inode : public object { virtual void set_num(uint32_t num) = 0; virtual uint32_t num() const = 0; virtual uint32_t similarity_hash() const = 0; - virtual std::vector const& nilsimsa_similarity_hash() const = 0; + virtual nilsimsa::hash_type const& nilsimsa_similarity_hash() const = 0; virtual size_t size() const = 0; virtual file const* any() const = 0; virtual files_vector const& files() const = 0; diff --git a/include/dwarfs/nilsimsa.h b/include/dwarfs/nilsimsa.h index 3059b900..13d63713 100644 --- a/include/dwarfs/nilsimsa.h +++ b/include/dwarfs/nilsimsa.h @@ -21,10 +21,10 @@ #pragma once +#include #include #include #include -#include #include "dwarfs/compiler.h" @@ -45,11 +45,13 @@ namespace dwarfs { class nilsimsa { public: + using hash_type = std::array; + nilsimsa(); ~nilsimsa(); void update(uint8_t const* data, size_t size); - std::vector finalize() const; + void finalize(hash_type& hash) const; #ifdef DWARFS_MULTIVERSIONING __attribute__((target("popcnt"))) static int diff --git a/src/dwarfs/inode_manager.cpp b/src/dwarfs/inode_manager.cpp index 0eb3f946..ffe24ecd 100644 --- a/src/dwarfs/inode_manager.cpp +++ b/src/dwarfs/inode_manager.cpp @@ -93,6 +93,10 @@ class inode_ : public inode { public: using chunk_type = thrift::metadata::chunk; + inode_() { + std::fill(nilsimsa_similarity_hash_.begin(), nilsimsa_similarity_hash_.end(), 0); + } + void set_num(uint32_t num) override { DWARFS_CHECK(!num_, "attempt to set inode number multiple times"); num_ = num; @@ -107,7 +111,7 @@ class inode_ : public inode { return similarity_hash_; } - std::vector const& nilsimsa_similarity_hash() const override { + nilsimsa::hash_type const& nilsimsa_similarity_hash() const override { if (files_.empty()) { DWARFS_THROW(runtime_error, "inode has no file"); } @@ -156,7 +160,7 @@ class inode_ : public inode { } if (opts.with_nilsimsa) { - nilsimsa_similarity_hash_ = nc.finalize(); + nc.finalize(nilsimsa_similarity_hash_); } } } @@ -189,7 +193,7 @@ class inode_ : public inode { uint32_t similarity_hash_{0}; files_vector files_; std::vector chunks_; - std::vector nilsimsa_similarity_hash_; + nilsimsa::hash_type nilsimsa_similarity_hash_; }; } // namespace diff --git a/src/dwarfs/nilsimsa.cpp b/src/dwarfs/nilsimsa.cpp index cf88ea50..f19fa4be 100644 --- a/src/dwarfs/nilsimsa.cpp +++ b/src/dwarfs/nilsimsa.cpp @@ -19,8 +19,6 @@ * along with dwarfs. If not, see . */ -#include - #include "dwarfs/compiler.h" #include "dwarfs/nilsimsa.h" @@ -76,7 +74,7 @@ class nilsimsa::impl { update_fast(data, size); } - std::vector finalize() const { + void finalize(hash_type& hash) const { size_t total = 0; if (size_ == 3) { @@ -89,16 +87,13 @@ class nilsimsa::impl { size_t threshold = total / acc_.size(); - std::vector hash; - hash.resize(4); + std::fill(hash.begin(), hash.end(), 0); for (size_t i = 0; i < acc_.size(); i++) { if (acc_[i] > threshold) { hash[i >> 6] |= UINT64_C(1) << (i & 0x3F); } } - - return hash; } private: @@ -195,7 +190,7 @@ void nilsimsa::update(uint8_t const* data, size_t size) { impl_->update(data, size); } -std::vector nilsimsa::finalize() const { return impl_->finalize(); } +void nilsimsa::finalize(hash_type& hash) const { impl_->finalize(hash); } #ifdef DWARFS_MULTIVERSIONING __attribute__((target("popcnt"))) int