DAW JSON Link
Loading...
Searching...
No Matches
daw_murmur3.h
Go to the documentation of this file.
1// Copyright (c) Darrell Wright
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
5//
6// Official repository: https://github.com/beached/daw_json_link
7//
8
9#pragma once
10
11#include "version.h"
12
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>
17
18#include <cstddef>
19#include <cstdint>
20#include <iterator>
21
22namespace daw {
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>;
28 k *= prime1::value;
29 k = rotate_left<15>( k );
30 k *= prime2::value;
31 return k;
32 }
33 } // namespace murmur3_details
34
35 template<std::size_t N, typename CharT>
36 DAW_ATTRIB_NONNULL( )
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;
42 } );
43 return hash;
44 }
45
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 );
56 len -= 8;
57 ptr += 8;
58 }
59 if( len >= 4 ) {
60 hash = fnv1a_32_N<4>( ptr, hash );
61 len -= 4;
62 ptr += 4;
63 }
64 }
65 for( std::size_t n = 0; n < len; ++n ) {
66 hash ^= static_cast<unsigned char>( ptr[n] );
67 hash *= 0x0100'0193_u32;
68 }
69 return hash;
70 }
71
72 template<bool expect_long_strings>
73 [[nodiscard]] DAW_ATTRIB_INLINE static constexpr UInt32
74 name_hash( daw::string_view key ) {
75 if( auto const Sz = std::size( key );
76 DAW_LIKELY( Sz <= sizeof( UInt32 ) ) ) {
77 auto result = 0_u32;
78 auto const *ptr = std::data( key );
79 for( std::size_t n = 0; n < Sz; ++n ) {
80 result <<= 8U;
81 result |= static_cast<unsigned char>( ptr[n] );
82 }
83 return result * 0xCC9E'2d51UL; // mix it up with an fnv1a prime
84 }
85 return fnv1a_32<expect_long_strings>( key );
86 }
87
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 );
94 UInt32 k = 0_u32;
95 char const *first = std::data( key );
96 char const *const last = daw::data_end( key );
97 while( ( last - first ) >= 4 ) {
98 // Here is a source of differing results across endianness.
99 // A swap here has no effects on hash properties though.
100 k = daw::to_uint32_buffer( first );
101 first += 4;
102 h ^= murmur3_details::murmur3_32_scramble( k );
103 h = rotate_left<13>( h );
104 h = h * 5 + 0xe654'6b64_u32;
105 }
106
107 // Anything left over
108 k = 0_u32;
109 for( auto i = ( last - first ); i > 0; --i ) {
110 k <<= 8U;
111 k |= static_cast<unsigned char>( first[i - 1] );
112 }
113
114 h ^= murmur3_details::murmur3_32_scramble( k );
115
116 h ^= to_uint32( std::size( key ) );
117 h ^= h >> 16U;
118 h *= 0x85eb'ca6b_u32;
119 h ^= h >> 13U;
120 h *= 0xc2b2'ae35_u32;
121 h ^= h >> 16U;
122 return h;
123 }
124} // namespace daw
static constexpr UInt32 murmur3_32(StringView key, std::uint32_t seed=0)
Definition daw_murmur3.h:89
static DAW_ATTRIB_INLINE constexpr UInt32 fnv1a_32_N(CharT *first, UInt32 hash=0x811c '9dc5_u32)
Definition daw_murmur3.h:38
static constexpr UInt32 fnv1a_32(StringView key)
Definition daw_murmur3.h:47
static DAW_ATTRIB_INLINE constexpr UInt32 name_hash(daw::string_view key)
Definition daw_murmur3.h:74