Skip to content

Commit 956b4a4

Browse files
committed
tuple_hash
1 parent f819900 commit 956b4a4

1 file changed

Lines changed: 26 additions & 6 deletions

File tree

Objects/tupleobject.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -320,20 +320,40 @@ tuple_hash(PyObject *op)
320320
PyTupleObject *v = _PyTuple_CAST(op);
321321
Py_ssize_t len = Py_SIZE(v);
322322
PyObject **item = v->ob_item;
323+
Py_uhash_t acc;
323324

324-
Py_uhash_t acc = _PyHASH_XXPRIME_5;
325-
for (Py_ssize_t i = 0; i < len; i++) {
326-
Py_uhash_t lane = PyObject_Hash(item[i]);
325+
switch (len) {
326+
case 0:
327+
return _PyHASH_XXPRIME_5 ^ (_PyHASH_XXPRIME_5 ^ 3527539UL);
328+
329+
case 1:
330+
Py_uhash_t lane = PyObject_Hash(item[0]);
327331
if (lane == (Py_uhash_t)-1) {
328332
return -1;
329333
}
334+
acc = _PyHASH_XXPRIME_5;
330335
acc += lane * _PyHASH_XXPRIME_2;
331336
acc = _PyHASH_XXROTATE(acc);
332337
acc *= _PyHASH_XXPRIME_1;
333-
}
338+
acc += 1 ^ (_PyHASH_XXPRIME_5 ^ 3527539UL);
334339

335-
/* Add input length, mangled to keep the historical value of hash(()). */
336-
acc += len ^ (_PyHASH_XXPRIME_5 ^ 3527539UL);
340+
break;
341+
342+
default:
343+
acc = _PyHASH_XXPRIME_5;
344+
for (Py_ssize_t i = 0; i < len; i++) {
345+
Py_uhash_t lane = PyObject_Hash(item[i]);
346+
if (lane == (Py_uhash_t)-1) {
347+
return -1;
348+
}
349+
acc += lane * _PyHASH_XXPRIME_2;
350+
acc = _PyHASH_XXROTATE(acc);
351+
acc *= _PyHASH_XXPRIME_1;
352+
}
353+
354+
/* Add input length, mangled to keep the historical value of hash(()). */
355+
acc += len ^ (_PyHASH_XXPRIME_5 ^ 3527539UL);
356+
}
337357

338358
if (acc == (Py_uhash_t)-1) {
339359
return 1546275796;

0 commit comments

Comments
 (0)