@@ -129,7 +129,7 @@ As a consequence of this, split keys have a maximum size of 16.
129129#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
130130#include "pycore_pystate.h" // _PyThreadState_GET()
131131#include "pycore_setobject.h" // _PySet_NextEntry()
132- #include "pycore_tuple.h" // _PyTuple_Recycle()
132+ #include "pycore_tuple.h" // _PyTuple_Recycle(), _PyTuple_HASH_XXPRIME1, _PyTuple_HASH_XXPRIME2, _PyTuple_HASH_XXPRIME5, _PyTuple_HASH_XXROTATE
133133#include "pycore_unicodeobject.h" // _PyUnicode_InternImmortal()
134134
135135#include "stringlib/eq.h" // unicode_eq()
@@ -8222,24 +8222,27 @@ frozendict_repr(PyObject *self)
82228222 return res ;
82238223}
82248224
8225+ // Code unrolled from tuple_hash() for 2 values
82258226static inline Py_uhash_t
8226- _combine_hashes (Py_uhash_t h1 , Py_uhash_t h2 )
8227- {
8228- #if SIZEOF_PY_HASH_T == 8
8229- // 2^sizeof(Py_hash_t) / phi
8230- const Py_uhash_t GOLDEN_C = 0x9e3779b97f4a7c15ULL ;
8231- h1 += GOLDEN_C ;
8232- h1 ^= h2 ;
8233- h1 ^= (h1 << 13 ) + (h1 >> 3 );
8234- h1 ^= h1 >> 33 ;
8235- #else
8236- const Py_uhash_t GOLDEN_C = 0x9e3779b9UL ;
8237- h1 += GOLDEN_C ;
8238- h1 ^= h2 ;
8239- h1 ^= (h1 << 6 ) + (h1 >> 2 );
8240- h1 ^= h1 >> 16 ;
8241- #endif
8242- return h1 ;
8227+ _tuple2_xxhash (Py_uhash_t h1 , Py_uhash_t h2 )
8228+ {
8229+ Py_uhash_t acc = _PyTuple_HASH_XXPRIME_5 ;
8230+
8231+ acc += h1 * _PyTuple_HASH_XXPRIME_2 ;
8232+ acc = _PyTuple_HASH_XXROTATE (acc );
8233+ acc *= _PyTuple_HASH_XXPRIME_1 ;
8234+
8235+ acc += h2 * _PyTuple_HASH_XXPRIME_2 ;
8236+ acc = _PyTuple_HASH_XXROTATE (acc );
8237+ acc *= _PyTuple_HASH_XXPRIME_1 ;
8238+
8239+ acc += 2 ^ (_PyTuple_HASH_XXPRIME_5 ^ 3527539UL );
8240+
8241+ if (acc == (Py_uhash_t )- 1 ) {
8242+ acc = 1546275796 ;
8243+ }
8244+
8245+ return acc ;
82438246}
82448247
82458248// Code copied from frozenset_hash()
@@ -8253,7 +8256,7 @@ frozendict_hash(PyObject *op)
82538256 }
82548257
82558258 PyDictObject * mp = _PyAnyDict_CAST (op );
8256- Py_uhash_t hash = 0xfd1c74 ; // start at a different value from frozenset to avoid collision with empty frozenset
8259+ Py_uhash_t hash = 0xfd1c74 ; // start at a different value from frozenset to avoid collision with frozenset(frozendict.items())
82578260
82588261 PyObject * key , * value ; // borrowed refs
82598262 Py_ssize_t pos = 0 ;
@@ -8266,7 +8269,7 @@ frozendict_hash(PyObject *op)
82668269 if (value_hash == -1 ) {
82678270 return -1 ;
82688271 }
8269- hash ^= _combine_hashes (key_hash , value_hash );
8272+ hash ^= _tuple2_xxhash (key_hash , value_hash );
82708273 }
82718274
82728275 /* Factor in the number of active entries */
0 commit comments