13 #include <daw/daw_do_n.h>
14 #include <daw/daw_endian.h>
15 #include <daw/daw_string_view.h>
16 #include <daw/daw_uint_buffer.h>
23 namespace murmur3_details {
24 [[nodiscard]] DAW_ATTRIB_FLATINLINE
static inline constexpr UInt32
25 murmur3_32_scramble( UInt32 k ) {
26 using prime1 = daw::constant<0xcc9e'2d51_u32>;
27 using prime2 = daw::constant<0x1b87'3593_u32>;
29 k = rotate_left<15>( k );
35 template<std::
size_t N,
typename CharT>
37 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr UInt32
38 fnv1a_32_N( CharT *first, UInt32 hash = 0x811c'9dc5_u32 ) {
39 daw::algorithm::do_n_arg<N>( [&]( std::size_t n ) {
40 hash ^=
static_cast<UInt32
>(
static_cast<unsigned char>( first[n] ) );
41 hash *= 0x0100'0193_u32;
46 template<
bool expect_
long_
strings,
typename StringView>
47 [[nodiscard]]
static constexpr UInt32
fnv1a_32( StringView key ) {
48 static_assert( daw::traits::is_string_view_like_v<StringView>,
49 "Can only pass contiguous character ranges to fnv1a" );
50 std::size_t len = std::size( key );
51 auto *ptr = std::data( key );
52 auto hash = 0x811c'9dc5_u32;
53 if constexpr( expect_long_strings ) {
54 while( DAW_UNLIKELY( len >= 8 ) ) {
55 hash = fnv1a_32_N<8>( ptr, hash );
60 hash = fnv1a_32_N<4>( ptr, hash );
65 for( std::size_t n = 0; n < len; ++n ) {
66 hash ^=
static_cast<unsigned char>( ptr[n] );
67 hash *= 0x0100'0193_u32;
72 template<
bool expect_
long_
strings>
73 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr UInt32
75 if(
auto const Sz = std::size( key );
76 DAW_LIKELY( Sz <=
sizeof( UInt32 ) ) ) {
78 auto const *ptr = std::data( key );
79 for( std::size_t n = 0; n < Sz; ++n ) {
81 result |=
static_cast<unsigned char>( ptr[n] );
83 return result * 0xCC9E'2d51UL;
85 return fnv1a_32<expect_long_strings>( key );
88 template<
typename StringView>
89 [[nodiscard]]
static constexpr UInt32
murmur3_32( StringView key,
90 std::uint32_t seed = 0 ) {
91 static_assert( daw::traits::is_string_view_like_v<StringView>,
92 "Can only pass contiguous character ranges to fnv1a" );
93 UInt32 h = to_uint32( seed );
95 char const *first = std::data( key );
96 char const *
const last = daw::data_end( key );
97 while( ( last - first ) >= 4 ) {
100 k = daw::to_uint32_buffer( first );
102 h ^= murmur3_details::murmur3_32_scramble( k );
103 h = rotate_left<13>( h );
104 h = h * 5 + 0xe654'6b64_u32;
109 for(
auto i = ( last - first ); i > 0; --i ) {
111 k |=
static_cast<unsigned char>( first[i - 1] );
114 h ^= murmur3_details::murmur3_32_scramble( k );
116 h ^= to_uint32( std::size( key ) );
118 h *= 0x85eb'ca6b_u32;
120 h *= 0xc2b2'ae35_u32;
static constexpr UInt32 murmur3_32(StringView key, std::uint32_t seed=0)
static constexpr UInt32 fnv1a_32(StringView key)
static constexpr DAW_ATTRIB_INLINE UInt32 fnv1a_32_N(CharT *first, UInt32 hash=0x811c '9dc5_u32)
static constexpr DAW_ATTRIB_INLINE UInt32 name_hash(daw::string_view key)