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>
25 namespace murmur3_details {
26 [[nodiscard]] DAW_ATTRIB_FLATINLINE
static constexpr daw::UInt32
27 murmur3_32_scramble( daw::UInt32 k ) {
28 using prime1 = daw::constant<0xcc9e'2d51_u32>;
29 using prime2 = daw::constant<0x1b87'3593_u32>;
31 k = rotate_left<15>( k );
43 inline constexpr auto fnv1a_basis_v<daw::UInt32> = 0x811c'9dc5_u32;
45 inline constexpr auto fnv1a_prime_v<daw::UInt32> = 0x0100'0193_u32;
48 inline constexpr auto fnv1a_basis_v<daw::UInt64> = 0xcbf2'9ce4'8422'2325_u64;
50 inline constexpr auto fnv1a_prime_v<daw::UInt64> = 0x0000'0100'0000'01b3_u64;
53 template<std::
size_t N,
typename Hash>
54 [[nodiscard]] DAW_ATTRIB_INLINE
static constexpr auto
55 fnv1a_N( daw::not_null<char const *> first,
56 Hash hash = fnv1a_basis_v<Hash> ) {
57 daw::algorithm::do_n_arg<N>( [&]( std::size_t n ) {
58 hash ^=
static_cast<Hash
>(
static_cast<unsigned char>( first[n] ) );
59 hash *= fnv1a_prime_v<Hash>;
64 template<
typename Hash,
bool expect_
long_
strings,
typename StringView>
65 [[nodiscard]]
static constexpr Hash
fnv1a( StringView key ) {
66 static_assert( daw::traits::is_string_view_like_v<StringView>,
67 "Can only pass contiguous character ranges to fnv1a" );
68 std::size_t len = std::size( key );
69 daw::not_null ptr = std::data( key );
70 auto hash = fnv1a_basis_v<Hash>;
71 if constexpr( expect_long_strings ) {
72 while( DAW_UNLIKELY( len >= 8 ) ) {
73 hash = fnv1a_N<8>( ptr, hash );
78 hash = fnv1a_N<4>( ptr, hash );
83 for( std::size_t n = 0; n < len; ++n ) {
84 hash ^=
static_cast<unsigned char>( ptr[n] );
85 hash *= fnv1a_prime_v<Hash>;
90 template<
bool expect_
long_
strings>
93 if(
auto const Sz = std::size( key );
96 auto const *ptr = std::data( key );
97 for( std::size_t n = 0; n < Sz; ++n ) {
99 result |=
static_cast<unsigned char>( ptr[n] );
104 return fnv1a<json_name_hash_t, expect_long_strings>( key );
107 template<
typename StringView>
108 [[nodiscard]]
static constexpr daw::UInt32
110 static_assert( daw::traits::is_string_view_like_v<StringView>,
111 "Can only pass contiguous character ranges to fnv1a" );
112 daw::UInt32 h = to_uint32( seed );
113 daw::UInt32 k = 0_u32;
114 char const *first = std::data( key );
115 char const *
const last = daw::data_end( key );
116 while( ( last - first ) >= 4 ) {
119 k = daw::to_uint32_buffer( first );
121 h ^= murmur3_details::murmur3_32_scramble( k );
122 h = rotate_left<13>( h );
123 h = h * 5 + 0xe654'6b64_u32;
128 for(
auto i = ( last - first ); i > 0; --i ) {
130 k |=
static_cast<unsigned char>( first[i - 1] );
133 h ^= murmur3_details::murmur3_32_scramble( k );
135 h ^= to_uint32( std::size( key ) );
137 h *= 0x85eb'ca6b_u32;
139 h *= 0xc2b2'ae35_u32;
constexpr T fnv1a_prime_v
static constexpr daw::UInt32 murmur3_32(StringView key, std::uint32_t seed=0)
static DAW_ATTRIB_INLINE constexpr auto fnv1a_N(daw::not_null< char const * > first, Hash hash=fnv1a_basis_v< Hash >)
daw::UInt64 json_name_hash_t
constexpr T fnv1a_basis_v
static DAW_ATTRIB_INLINE constexpr json_name_hash_t name_hash(daw::string_view key)
static constexpr Hash fnv1a(StringView key)