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.
This commit is contained in:
Michał Chojnowski
2021-01-04 17:31:54 +01:00
parent 4822730752
commit 75898ee44e
2 changed files with 26 additions and 12 deletions

View File

@@ -28,6 +28,7 @@
#include <iosfwd>
#include <functional>
#include "utils/mutable_view.hh"
#include <xxhash.h>
using bytes = basic_sstring<int8_t, uint32_t, 31, false>;
using bytes_view = std::basic_string_view<int8_t>;
@@ -47,17 +48,6 @@ inline bytes_view to_bytes_view(sstring_view view) {
return {reinterpret_cast<const int8_t*>(view.data()), view.size()};
}
namespace std {
template <>
struct hash<bytes_view> {
size_t operator()(bytes_view v) const {
return hash<sstring_view>()({reinterpret_cast<const char*>(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<bytes_view> {
}
};
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<size_t>(XXH64_digest(&_state));
}
};
namespace std {
template <>
struct hash<bytes_view> {
size_t operator()(bytes_view v) const {
bytes_view_hasher h;
appending_hash<bytes_view>{}(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) {

View File

@@ -3978,7 +3978,7 @@ drop table lwt;
-- non-frozen nested sets are not supported
create table lwt (a int, b set<map<int,int>>, c list<set<int>>, primary key (a));
{
"message" : "exceptions::invalid_request_exception (Non-frozen user types or collections are not allowed inside collections: list<set<int>>)",
"message" : "exceptions::invalid_request_exception (Non-frozen user types or collections are not allowed inside collections: set<map<int, int>>)",
"status" : "error"
}
-- frozen collection elements are however ok