From cbca4be23757dfbdb54aa7177a1bce04f12364eb Mon Sep 17 00:00:00 2001 From: Kurt Sassenrath Date: Mon, 6 Nov 2023 22:56:35 -0800 Subject: [PATCH] Add hash test --- include/parselink/proto/session_id.h | 25 +++++++++++++++++++++---- tests/proto/test_session_id.cpp | 18 +++++++++++++----- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/include/parselink/proto/session_id.h b/include/parselink/proto/session_id.h index 45ee1d0..0ef8f30 100644 --- a/include/parselink/proto/session_id.h +++ b/include/parselink/proto/session_id.h @@ -21,6 +21,8 @@ #include #include +#include +#include #include namespace parselink { @@ -55,12 +57,12 @@ public: [[nodiscard]] constexpr auto operator==( std::span other) const noexcept { - return std::equal(bytes_.begin(), bytes_.end(), other.begin(), other.end()); + return std::equal( + bytes_.begin(), bytes_.end(), other.begin(), other.end()); } - constexpr std::span raw() const noexcept { - return bytes_; - } + constexpr std::span raw() const noexcept { return bytes_; } + private: std::array bytes_; }; @@ -68,4 +70,19 @@ private: } // namespace proto } // namespace parselink +// Hashing support +template <> +struct std::hash { + constexpr static std::uint32_t seed_var = 0x811c9dc5; + constexpr static std::uint32_t factor = 0x01000193; + + constexpr auto operator()(auto const& sid) const noexcept { + std::uint32_t digest = seed_var * factor; + for (auto byte : sid.raw()) { + digest = (digest ^ static_cast(byte)) * factor; + } + return digest >> 8; + } +}; + #endif // session_id_6598f9bae1cbb501 diff --git a/tests/proto/test_session_id.cpp b/tests/proto/test_session_id.cpp index a1122f8..c2209a1 100644 --- a/tests/proto/test_session_id.cpp +++ b/tests/proto/test_session_id.cpp @@ -1,8 +1,9 @@ #include #include - #include +#include + namespace { using namespace boost::ut; @@ -14,8 +15,9 @@ constexpr std::array make_bytes(Bytes&&... bytes) { } constexpr std::array null_id_bytes = {}; +constexpr std::size_t expected_null_hash = 0xd98558; -} +} // namespace suite session_id_tests = [] { "test explicitly generated session ids"_test = [] { @@ -23,15 +25,21 @@ suite session_id_tests = [] { constexpr session_id sid2(null_id_bytes); expect(sid1 == sid2); expect(sid1 == null_id_bytes); - constexpr auto basic_id = make_bytes( - 0x0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f); + constexpr auto basic_id = make_bytes(0x0, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f); constexpr session_id sid3(basic_id); constexpr session_id sid4(basic_id); expect(sid3 == sid4); expect(sid3 == basic_id); }; + "test hashing"_test = [] { + session_id sid(null_id_bytes); + expect(std::hash{}(sid) == expected_null_hash); + }; + "test random generated"_test = [] { session_id sid1; session_id sid2;