MySQL  8.0.27
Source Code Documentation
my_hash_combine.h
Go to the documentation of this file.
1 /* Copyright (c) 2017, 2021, Oracle and/or its affiliates.
2 
3 The code in this file is copied from Boost 1.63.0
4 boost/functional/hash/hash.hpp, which contains the following copyright notice:
5 
6 Copyright 2005-2014 Daniel James.
7 Distributed under the Boost Software License, Version 1.0. (See accompanying
8 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 
10  Based on Peter Dimov's proposal
11  http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
12  issue 6.18._
13 
14  This also contains public domain code from MurmurHash. From the
15  MurmurHash header:
16 
17 MurmurHash3 was written by Austin Appleby, and is placed in the public
18 domain. The author hereby disclaims copyright to this source code. */
19 
20 /** @file include/my_hash_combine.h
21 A convenient way to combine two hash values.
22 
23 It was decided to copy (parts of) the boost::hash_combine() implementation
24 instead of using it directly (by including <boost/functional/hash.hpp>)
25 because of the following reasons, raised by Steinar and Tor:
26 
27 Pros:
28 
29  - It solves a real problem (how to hash std::pair).
30  - Few dependencies (just type_traits and enable_if).
31  - Seems like a reasonable implementation.
32 
33 Cons:
34 
35  - It's more Boost.
36  - Doesn't seem to be accepted into C++17, so it's something we'd have to
37  drag around for a long time without an easy migration path off it.
38  - It solves the problem in a suboptimal way; combining values after
39  hash-finalization is going to both hash worse and slower than before it.
40  The real way requires an interface change to how std::hash works
41  (exposing more internal hasher state). I know people have been working on
42  this, but evidently it didn't reach C++17 either.
43  - Uses boost::hash instead of std::hash. This is probably the biggest killer
44  for me.
45  - Can easily be implemented by ourselves by lifting the core parts of the
46  Boost implementation. (It's about 20 lines.)
47 
48 I could go either way, but my immediate thought is probably that we should
49 copy the Boost implementation into some header, and then prefix it with a
50 warning saying that you shouldn't use this if you need optimal performance or
51 hash distribution.
52 
53 Steinar */
54 
55 #ifndef MY_HASH_COMBINE_INCLUDED
56 #define MY_HASH_COMBINE_INCLUDED
57 
58 #if defined(_MSC_VER)
59 #define MY_FUNCTIONAL_HASH_ROTL32(x, r) _rotl(x, r)
60 #else
61 #define MY_FUNCTIONAL_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r))
62 #endif /* _MSC_VER */
63 
64 #include <stdint.h>
65 
66 template <typename SizeT>
67 inline void my_hash_combine(SizeT &seed, SizeT value) {
68  seed ^= value + 0x9e3779b9 + (seed << 6) + (seed >> 2);
69 }
70 
71 inline void my_hash_combine(uint32_t &h1, uint32_t k1) {
72  const uint32_t c1 = 0xcc9e2d51;
73  const uint32_t c2 = 0x1b873593;
74 
75  k1 *= c1;
76  k1 = MY_FUNCTIONAL_HASH_ROTL32(k1, 15);
77  k1 *= c2;
78 
79  h1 ^= k1;
80  h1 = MY_FUNCTIONAL_HASH_ROTL32(h1, 13);
81  h1 = h1 * 5 + 0xe6546b64;
82 }
83 
84 inline void my_hash_combine(uint64_t &h, uint64_t k) {
85  const uint64_t m = 0xc6a4a7935bd1e995ull;
86  const int r = 47;
87 
88  k *= m;
89  k ^= k >> r;
90  k *= m;
91 
92  h ^= k;
93  h *= m;
94 
95  // Completely arbitrary number, to prevent 0's
96  // from hashing to 0.
97  h += 0xe6546b64;
98 }
99 
100 #endif /* MY_HASH_COMBINE_INCLUDED */
#define MY_FUNCTIONAL_HASH_ROTL32(x, r)
Definition: my_hash_combine.h:61
void my_hash_combine(SizeT &seed, SizeT value)
Definition: my_hash_combine.h:67
const string value("\"Value\"")
const mysql_service_registry_t * r
Definition: pfs_example_plugin_employee.cc:85