MySQL 9.1.0
Source Code Documentation
my_hash_combine.h File Reference

A convenient way to combine two hash values. More...

#include <stdint.h>

Go to the source code of this file.

Macros

#define MY_FUNCTIONAL_HASH_ROTL32(x, r)   (x << r) | (x >> (32 - r))
 

Functions

template<typename SizeT >
void my_hash_combine (SizeT &seed, SizeT value)
 
void my_hash_combine (uint32_t &h1, uint32_t k1)
 
void my_hash_combine (uint64_t &h, uint64_t k)
 

Detailed Description

A convenient way to combine two hash values.

It was decided to copy (parts of) the boost::hash_combine() implementation instead of using it directly (by including <boost/functional/hash.hpp>) because of the following reasons, raised by Steinar and Tor:

Pros:

  • It solves a real problem (how to hash std::pair).
  • Few dependencies (just type_traits and enable_if).
  • Seems like a reasonable implementation.

Cons:

  • It's more Boost.
  • Doesn't seem to be accepted into C++17, so it's something we'd have to drag around for a long time without an easy migration path off it.
  • It solves the problem in a suboptimal way; combining values after hash-finalization is going to both hash worse and slower than before it. The real way requires an interface change to how std::hash works (exposing more internal hasher state). I know people have been working on this, but evidently it didn't reach C++17 either.
  • Uses boost::hash instead of std::hash. This is probably the biggest killer for me.
  • Can easily be implemented by ourselves by lifting the core parts of the Boost implementation. (It's about 20 lines.)

I could go either way, but my immediate thought is probably that we should copy the Boost implementation into some header, and then prefix it with a warning saying that you shouldn't use this if you need optimal performance or hash distribution.

Steinar

Macro Definition Documentation

◆ MY_FUNCTIONAL_HASH_ROTL32

#define MY_FUNCTIONAL_HASH_ROTL32 (   x,
  r 
)    (x << r) | (x >> (32 - r))

Function Documentation

◆ my_hash_combine() [1/3]

template<typename SizeT >
void my_hash_combine ( SizeT &  seed,
SizeT  value 
)
inline

◆ my_hash_combine() [2/3]

void my_hash_combine ( uint32_t &  h1,
uint32_t  k1 
)
inline

◆ my_hash_combine() [3/3]

void my_hash_combine ( uint64_t &  h,
uint64_t  k 
)
inline