|
49 | 49 | #include "absl/hash/internal/city.h" |
50 | 50 | #include "absl/hash/internal/low_level_hash.h" |
51 | 51 | #include "absl/meta/type_traits.h" |
| 52 | +#include "absl/numeric/bits.h" |
52 | 53 | #include "absl/numeric/int128.h" |
53 | 54 | #include "absl/strings/string_view.h" |
54 | 55 | #include "absl/types/optional.h" |
@@ -1052,7 +1053,7 @@ class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> { |
1052 | 1053 | uint64_t most_significant = low_mem; |
1053 | 1054 | uint64_t least_significant = high_mem; |
1054 | 1055 | #endif |
1055 | | - return {least_significant, most_significant >> (128 - len * 8)}; |
| 1056 | + return {least_significant, most_significant}; |
1056 | 1057 | } |
1057 | 1058 |
|
1058 | 1059 | // Reads 4 to 8 bytes from p. Zero pads to fill uint64_t. |
@@ -1183,9 +1184,22 @@ inline uint64_t MixingHashState::CombineContiguousImpl( |
1183 | 1184 | } |
1184 | 1185 | v = Hash64(first, len); |
1185 | 1186 | } else if (len > 8) { |
| 1187 | + // This hash function was constructed by the ML-driven algorithm discovery |
| 1188 | + // using reinforcement learning. We fed the agent lots of inputs from |
| 1189 | + // microbenchmarks, SMHasher, low hamming distance from generated inputs and |
| 1190 | + // picked up the one that was good on micro and macrobenchmarks. |
1186 | 1191 | auto p = Read9To16(first, len); |
1187 | | - state = Mix(state, p.first); |
1188 | | - v = p.second; |
| 1192 | + uint64_t lo = p.first; |
| 1193 | + uint64_t hi = p.second; |
| 1194 | + // Rotation by 53 was found to be most often useful when discovering these |
| 1195 | + // hashing algorithms with ML techniques. |
| 1196 | + lo = absl::rotr(lo, 53); |
| 1197 | + state += kMul; |
| 1198 | + lo += state; |
| 1199 | + state ^= hi; |
| 1200 | + uint128 m = state; |
| 1201 | + m *= lo; |
| 1202 | + return static_cast<uint64_t>(m ^ (m >> 64)); |
1189 | 1203 | } else if (len >= 4) { |
1190 | 1204 | v = Read4To8(first, len); |
1191 | 1205 | } else if (len > 0) { |
|
0 commit comments