From 75898ee44e4fa67b90def2c95904b038053f4d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Chojnowski?= Date: Mon, 4 Jan 2021 17:31:54 +0100 Subject: [PATCH] bytes: implement std::hash using appending_hash This is a preparation for the upcoming introduction of managed_bytes_view, intended as a fragmented replacement for bytes_view. To ease the transition, we want both types to give equal hashes for equal contents. --- bytes.hh | 36 +++++++++++++++++++++++++----------- test/cql/lwt_test.result | 2 +- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/bytes.hh b/bytes.hh index ea19dfe7cc..35730c1940 100644 --- a/bytes.hh +++ b/bytes.hh @@ -28,6 +28,7 @@ #include #include #include "utils/mutable_view.hh" +#include using bytes = basic_sstring; using bytes_view = std::basic_string_view; @@ -47,17 +48,6 @@ inline bytes_view to_bytes_view(sstring_view view) { return {reinterpret_cast(view.data()), view.size()}; } -namespace std { - -template <> -struct hash { - size_t operator()(bytes_view v) const { - return hash()({reinterpret_cast(v.begin()), v.size()}); - } -}; - -} - struct fmt_hex { bytes_view& v; fmt_hex(bytes_view& v) noexcept : v(v) {} @@ -98,6 +88,30 @@ struct appending_hash { } }; +struct bytes_view_hasher : public hasher { + XXH64_state_t _state; + bytes_view_hasher(uint64_t seed = 0) noexcept { + XXH64_reset(&_state, seed); + } + void update(const char* ptr, size_t length) noexcept { + XXH64_update(&_state, ptr, length); + } + size_t finalize() { + return static_cast(XXH64_digest(&_state)); + } +}; + +namespace std { +template <> +struct hash { + size_t operator()(bytes_view v) const { + bytes_view_hasher h; + appending_hash{}(h, v); + return h.finalize(); + } +}; +} // namespace std + inline int32_t compare_unsigned(bytes_view v1, bytes_view v2) { auto size = std::min(v1.size(), v2.size()); if (size) { diff --git a/test/cql/lwt_test.result b/test/cql/lwt_test.result index 188c6151b6..75c72040e4 100644 --- a/test/cql/lwt_test.result +++ b/test/cql/lwt_test.result @@ -3978,7 +3978,7 @@ drop table lwt; -- non-frozen nested sets are not supported create table lwt (a int, b set>, c list>, primary key (a)); { - "message" : "exceptions::invalid_request_exception (Non-frozen user types or collections are not allowed inside collections: list>)", + "message" : "exceptions::invalid_request_exception (Non-frozen user types or collections are not allowed inside collections: set>)", "status" : "error" } -- frozen collection elements are however ok