@@ -62,18 +62,32 @@ private:
6262 }
6363 };
6464
65- // ////////////////////////////////////////////////////////////////////////
65+ // ///////////////////////////////////////////////////////////////////////////
6666 // / Hash combining the individual join field value hashes from RCombinedJoinFieldValue. Uses the implementation
67- // / from `boost::hash_combine` (see
68- // / https://www.boost.org/doc/libs/1_55_0/doc/html/hash/reference.html#boost.hash_combine).
67+ // / from `boost::hash_combine`. See
68+ // / https://www.boost.org/doc/libs/1_87_0/libs/container_hash/doc/html/hash.html#notes_hash_combine for more
69+ // / background. In particular, it mentions: "Several improvements of the 64 bit function have been subsequently
70+ // / proposed, by [David Stafford](https://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html), [Pelle
71+ // / Evensen](https://mostlymangling.blogspot.com/2019/12/stronger-better-morer-moremur-better.html), and [Jon
72+ // / Maiga](http://jonkagstrom.com/mx3/mx3_rev2.html). We currently use Jon Maiga’s function."
6973 struct RCombinedJoinFieldValueHash {
70- inline std::size_t operator ()(const RCombinedJoinFieldValue &joinFieldValue ) const
74+ inline std::size_t operator ()(const RCombinedJoinFieldValue &joinFieldVal ) const
7175 {
72- std::size_t combinedHash = 0 ;
73- for (const auto &fieldVal : joinFieldValue .fJoinFieldValues ) {
74- combinedHash ^= fieldVal + 0x9e3779b9 + ( fieldVal << 6 ) + (fieldVal >> 2 );
76+ std::size_t seed = 0 ;
77+ for (const auto &fieldVal : joinFieldVal .fJoinFieldValues ) {
78+ seed ^= mix (seed + 0x9e3779b9 + fieldVal);
7579 }
76- return combinedHash;
80+ return seed;
81+ }
82+
83+ inline std::size_t mix (std::size_t init) const
84+ {
85+ init ^= init >> 32 ;
86+ init *= 0xe9846af9b1a615d ;
87+ init ^= init >> 32 ;
88+ init *= 0xe9846af9b1a615d ;
89+ init ^= init >> 28 ;
90+ return init;
7791 }
7892 };
7993
0 commit comments