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:
36
bytes.hh
36
bytes.hh
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user