323
/* adapted from tuplehash(), is the specific hash value considered
327
#if PY_MAJOR_VERSION > 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 8)
328
/* Hash for tuples. This is a slightly simplified version of the xxHash
329
non-cryptographic hash:
330
- we do not use any parallellism, there is only 1 accumulator.
331
- we drop the final mixing since this is just a permutation of the
332
output space: it does not help against collisions.
333
- at the end, we mangle the length with a single constant.
334
For the xxHash specification, see
335
https://github.com/Cyan4973/xxHash/blob/master/doc/xxhash_spec.md
337
Below are the official constants from the xxHash specification. Optimizing
338
compilers should emit a single "rotate" instruction for the
339
_PyHASH_XXROTATE() expansion. If that doesn't happen for some important
340
platform, the macro could be changed to expand to a platform-specific rotate
343
#if SIZEOF_PY_UHASH_T > 4
344
#define _PyHASH_XXPRIME_1 ((Py_uhash_t)11400714785074694791ULL)
345
#define _PyHASH_XXPRIME_2 ((Py_uhash_t)14029467366897019727ULL)
346
#define _PyHASH_XXPRIME_5 ((Py_uhash_t)2870177450012600261ULL)
347
#define _PyHASH_XXROTATE(x) ((x << 31) | (x >> 33)) /* Rotate left 31 bits */
349
#define _PyHASH_XXPRIME_1 ((Py_uhash_t)2654435761UL)
350
#define _PyHASH_XXPRIME_2 ((Py_uhash_t)2246822519UL)
351
#define _PyHASH_XXPRIME_5 ((Py_uhash_t)374761393UL)
352
#define _PyHASH_XXROTATE(x) ((x << 13) | (x >> 19)) /* Rotate left 13 bits */
355
/* Tests have shown that it's not worth to cache the hash value, see
356
https://bugs.python.org/issue9685 */
358
StaticTuple_hash(StaticTuple *self)
360
Py_ssize_t i, len = self->size;
361
PyObject **item = self->items;
363
#if STATIC_TUPLE_HAS_HASH
364
if (self->hash != -1) {
369
Py_uhash_t acc = _PyHASH_XXPRIME_5;
370
for (i = 0; i < len; i++) {
371
Py_uhash_t lane = PyObject_Hash(item[i]);
372
if (lane == (Py_uhash_t)-1) {
375
acc += lane * _PyHASH_XXPRIME_2;
376
acc = _PyHASH_XXROTATE(acc);
377
acc *= _PyHASH_XXPRIME_1;
380
/* Add input length, mangled to keep the historical value of hash(()). */
381
acc += len ^ (_PyHASH_XXPRIME_5 ^ 3527539UL);
383
if (acc == (Py_uhash_t)-1) {
387
#if STATIC_TUPLE_HAS_HASH
396
324
StaticTuple_hash(StaticTuple *self)