From e40e50a11774dce661e3c4a28b77120a6be4b3a5 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 23 Oct 2024 16:49:54 +0200 Subject: [PATCH 1/6] Hash: Move to template --- include/cppcore/Common/Hash.h | 54 +++++++++++++++------------- include/cppcore/Container/THashMap.h | 10 +++--- test/common/HashTest.cpp | 29 ++++++++------- 3 files changed, 51 insertions(+), 42 deletions(-) diff --git a/include/cppcore/Common/Hash.h b/include/cppcore/Common/Hash.h index c44993e..cf6d300 100644 --- a/include/cppcore/Common/Hash.h +++ b/include/cppcore/Common/Hash.h @@ -27,79 +27,81 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. namespace cppcore { //------------------------------------------------------------------------------------------------- -/// @class Hash +/// @class THash /// @ingroup CPPCore /// /// @brief This class is used to calculate the hash value for a given integer or character buffer. //------------------------------------------------------------------------------------------------- -class Hash { +template +class THash { public: /// @brief The default class constructor. - Hash(); + THash(); /// @brief The class constructor with a given hash value. /// @param hash [in] An integer value to compute the hash from. - explicit Hash(unsigned int hash); + explicit THash(T hash); /// @brief The class constructor with a given char buffer. /// @param value [in] A character buffer to compute the hash from. /// @param base [in] The table base. - explicit Hash(const char *buffer, unsigned int base); + explicit THash(const char *buffer, T base); /// @brief The class constructor with a given unsigned int value. /// @param value [in] An unsigned int value to compute the hash from. /// @param base [in] The table base. - explicit Hash(unsigned int value, unsigned int base); + explicit THash(T value, T base); /// @brief The class destructor. - ~Hash(); + ~THash() = default; /// @brief Computes the hash value for a given character buffer. /// @param buffer [in] The buffer. /// @param base [in] The table base. /// @return The hash value. - static unsigned int toHash(const char *buffer, unsigned int base); + static T toHash(const char *buffer, T base); /// @brief Computes the hash value for a given unsigned int value. /// @param buffer [in] The unsigned int value. /// @param base [in] The table base. /// @return The hash value. - static unsigned int toHash(unsigned int value, unsigned int base); + static T toHash(T value, T base); /// brief Returns the stored hash value. /// @return The hash value. - unsigned int hashValue() const; + T hashValue() const; private: unsigned int m_hash; }; -inline Hash::Hash() : +template +inline THash::THash() : m_hash(0) { // empty } -inline Hash::Hash(unsigned int hash) : +template +inline THash::THash(T hash) : m_hash(hash) { // empty } -inline Hash::Hash(const char *buffer, unsigned int base) : - m_hash(Hash::toHash(buffer, base)) { +template +inline THash::THash(const char *buffer, T base) : + m_hash(THash::toHash(buffer, base)) { // empty } -inline Hash::Hash(unsigned int value, unsigned int base) : - m_hash(Hash::toHash(value, base)) { +template +inline THash::THash(T value, T base) : + m_hash(THash::toHash(value, base)) { // empty } -inline Hash::~Hash() { - // empty -} - -inline unsigned int Hash::toHash(const char *buffer, unsigned int base) { - unsigned int hash(0); +template +inline T THash::toHash(const char *buffer, T base) { + T hash = 0; if (nullptr == buffer) { return hash; } @@ -113,12 +115,14 @@ inline unsigned int Hash::toHash(const char *buffer, unsigned int base) { return hash; } -inline unsigned int Hash::toHash(unsigned int value, unsigned int base) { - const unsigned int hash(value % base); +template +inline T THash::toHash(T value, T base) { + const T hash = value % base; return hash; } -inline unsigned int Hash::hashValue() const { +template +inline T THash::hashValue() const { return m_hash; } diff --git a/include/cppcore/Container/THashMap.h b/include/cppcore/Container/THashMap.h index a1ade6b..f0ec339 100644 --- a/include/cppcore/Container/THashMap.h +++ b/include/cppcore/Container/THashMap.h @@ -44,6 +44,8 @@ namespace cppcore { template > class THashMap { public: + using Hash = THash; + /// @brief The initial hash size. static constexpr size_t InitSize = 1024; /// @brief Marker for unset node keys. @@ -176,7 +178,7 @@ inline void THashMap::clear() { template inline void THashMap::insert(const T &key, const U &value) { - const unsigned int hash = Hash::toHash(key, (unsigned int)m_buffersize); + const T hash = Hash::toHash(key, (unsigned int)m_buffersize); if (nullptr == m_buffer[hash]) { Node *node = new Node; node->m_key = key; @@ -190,7 +192,7 @@ inline void THashMap::insert(const T &key, const U &value) { template inline bool THashMap::remove(const T &key) { - const unsigned int hash = Hash::toHash(key, (unsigned int)m_buffersize); + const T hash = Hash::toHash(key, (unsigned int)m_buffersize); if (nullptr == m_buffer[hash]) { return false; } @@ -220,7 +222,7 @@ inline bool THashMap::hasKey(const T &key) const { if (0 == m_buffersize) { return false; } - const unsigned int hash(Hash::toHash(key, (unsigned int)m_buffersize)); + const T hash = THash::toHash(key, (unsigned int)m_buffersize); const Node *node = m_buffer[hash]; if (nullptr == node) { return false; @@ -245,7 +247,7 @@ inline bool THashMap::hasKey(const T &key) const { template inline bool THashMap::getValue(const T &key, U &value) const { - const size_t pos = Hash::toHash(key, (unsigned int)m_buffersize); + const size_t pos = Hash::toHash(key, (unsigned int) m_buffersize); if (m_buffer[pos]->m_key == key) { value = m_buffer[pos]->m_value; return true; diff --git a/test/common/HashTest.cpp b/test/common/HashTest.cpp index 1e5a37f..80a4e9a 100644 --- a/test/common/HashTest.cpp +++ b/test/common/HashTest.cpp @@ -29,67 +29,70 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using namespace cppcore; class HashTest : public testing::Test { +public: + using UiHash = THash; + protected: // empty }; TEST_F( HashTest, CreateTest ) { - Hash myHash1; + UiHash myHash1; EXPECT_EQ( myHash1.hashValue(), 0U ); - Hash myHash2( 10U ); + UiHash myHash2(10U); EXPECT_EQ( myHash2.hashValue(), 10U ); - Hash myHash3( "test", 7 ); + UiHash myHash3("test", 7); EXPECT_NE( myHash3.hashValue(), 0U ); } TEST_F( HashTest, MakeStringHashTest ) { static const unsigned int Base = 7; - Hash myHash_empty; + UiHash myHash_empty; EXPECT_EQ( myHash_empty.hashValue(), 0U ); std::string value; value = ( "huhu1" ); - const unsigned int hash1 = Hash::toHash( value.c_str(), Base ); + const unsigned int hash1 = UiHash::toHash(value.c_str(), Base); EXPECT_NE( hash1, 0U ); EXPECT_LE( hash1, Base ); value = ( "huhu2" ); - const unsigned int hash2 = Hash::toHash( value.c_str(), Base ); + const unsigned int hash2 = UiHash::toHash(value.c_str(), Base); EXPECT_NE( hash2, 0U ); EXPECT_LE( hash2, Base ); value = ( "huhu3" ); - const unsigned int hash3 = Hash::toHash( value.c_str(), Base ); + const unsigned int hash3 = UiHash::toHash(value.c_str(), Base); EXPECT_NE( hash3, 0U ); EXPECT_LE( hash3, Base ); - Hash myHash_inited( value.c_str(), Base ); + UiHash myHash_inited(value.c_str(), Base); EXPECT_EQ( myHash_inited.hashValue(), hash3 ); } TEST_F( HashTest, MakeUIntHashTest ) { static const unsigned int Base = 7U; - Hash myHash_empty; + UiHash myHash_empty; EXPECT_EQ( myHash_empty.hashValue(), 0U ); unsigned int value = 17U; - const unsigned int hash1 = Hash::toHash( value, Base ); + const unsigned int hash1 = UiHash::toHash(value, Base); EXPECT_NE( hash1, 0U ); EXPECT_LE( hash1, Base ); value = 27U; - const unsigned int hash2 = Hash::toHash( value, Base ); + const unsigned int hash2 = UiHash::toHash(value, Base); EXPECT_NE( hash2, 0U ); EXPECT_LE( hash2, Base ); value = 37U; - const unsigned int hash3 = Hash::toHash( value, Base ); + const unsigned int hash3 = UiHash::toHash(value, Base); EXPECT_NE( hash3, 0U ); EXPECT_LE( hash3, Base ); - Hash myHash_inited( value, Base ); + UiHash myHash_inited(value, Base); EXPECT_EQ( myHash_inited.hashValue(), hash3 ); } From ec0a4b686ad8b4236d1b91c7471270abad06d4b5 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 23 Oct 2024 21:22:24 +0200 Subject: [PATCH 2/6] Update include/cppcore/Container/THashMap.h Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- include/cppcore/Container/THashMap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cppcore/Container/THashMap.h b/include/cppcore/Container/THashMap.h index f0ec339..54f7f69 100644 --- a/include/cppcore/Container/THashMap.h +++ b/include/cppcore/Container/THashMap.h @@ -178,7 +178,7 @@ inline void THashMap::clear() { template inline void THashMap::insert(const T &key, const U &value) { - const T hash = Hash::toHash(key, (unsigned int)m_buffersize); + const T hash = Hash::toHash(key, static_cast(m_buffersize)); if (nullptr == m_buffer[hash]) { Node *node = new Node; node->m_key = key; From 63857df0774c885d4e347625747196718f8d051f Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 23 Oct 2024 21:23:39 +0200 Subject: [PATCH 3/6] Update Hash.h --- include/cppcore/Common/Hash.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cppcore/Common/Hash.h b/include/cppcore/Common/Hash.h index cf6d300..f41af5a 100644 --- a/include/cppcore/Common/Hash.h +++ b/include/cppcore/Common/Hash.h @@ -72,7 +72,7 @@ class THash { T hashValue() const; private: - unsigned int m_hash; + T m_hash; }; template From e788628e8aa3294ffef4e767ff84a886a81e96a9 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 23 Oct 2024 21:27:12 +0200 Subject: [PATCH 4/6] Update Hash.h --- include/cppcore/Common/Hash.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/cppcore/Common/Hash.h b/include/cppcore/Common/Hash.h index f41af5a..c55ddb3 100644 --- a/include/cppcore/Common/Hash.h +++ b/include/cppcore/Common/Hash.h @@ -101,6 +101,7 @@ inline THash::THash(T value, T base) : template inline T THash::toHash(const char *buffer, T base) { + static_assert(std::is_integral::value, "THash requires T to be an integral type."); T hash = 0; if (nullptr == buffer) { return hash; @@ -114,7 +115,7 @@ inline T THash::toHash(const char *buffer, T base) { return hash; } - +0 template inline T THash::toHash(T value, T base) { const T hash = value % base; From d3ef0a180a4af63a08334feebc14f7b5248cd4b2 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 23 Oct 2024 21:29:14 +0200 Subject: [PATCH 5/6] Update Hash.h --- include/cppcore/Common/Hash.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cppcore/Common/Hash.h b/include/cppcore/Common/Hash.h index c55ddb3..d12223d 100644 --- a/include/cppcore/Common/Hash.h +++ b/include/cppcore/Common/Hash.h @@ -115,7 +115,7 @@ inline T THash::toHash(const char *buffer, T base) { return hash; } -0 + template inline T THash::toHash(T value, T base) { const T hash = value % base; From f60b2d78b8e385e593f56356edad86202132688d Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 23 Oct 2024 21:31:05 +0200 Subject: [PATCH 6/6] Update Hash.h --- include/cppcore/Common/Hash.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/cppcore/Common/Hash.h b/include/cppcore/Common/Hash.h index d12223d..f41af5a 100644 --- a/include/cppcore/Common/Hash.h +++ b/include/cppcore/Common/Hash.h @@ -101,7 +101,6 @@ inline THash::THash(T value, T base) : template inline T THash::toHash(const char *buffer, T base) { - static_assert(std::is_integral::value, "THash requires T to be an integral type."); T hash = 0; if (nullptr == buffer) { return hash;