follow up to #9778: define and use an unsigned hash type

This commit is contained in:
Benjamin Peterson 2010-10-23 16:20:50 +00:00
parent 2b9af63b4f
commit 8035bc5c04
7 changed files with 22 additions and 20 deletions

View File

@ -135,7 +135,7 @@ Used in: PY_LONG_LONG
#else #else
#define _PyHASH_BITS 31 #define _PyHASH_BITS 31
#endif #endif
#define _PyHASH_MODULUS ((1UL << _PyHASH_BITS) - 1) #define _PyHASH_MODULUS (((size_t)1 << _PyHASH_BITS) - 1)
#define _PyHASH_INF 314159 #define _PyHASH_INF 314159
#define _PyHASH_NAN 0 #define _PyHASH_NAN 0
#define _PyHASH_IMAG 1000003UL #define _PyHASH_IMAG 1000003UL
@ -179,6 +179,8 @@ typedef Py_intptr_t Py_ssize_t;
/* Py_hash_t is the same size as a pointer. */ /* Py_hash_t is the same size as a pointer. */
typedef Py_ssize_t Py_hash_t; typedef Py_ssize_t Py_hash_t;
/* Py_uhash_t is the unsigned equivalent needed to calculate numeric hash. */
typedef size_t Py_uhash_t;
/* Largest possible value of size_t. /* Largest possible value of size_t.
SIZE_MAX is part of C99, so it might be defined on some SIZE_MAX is part of C99, so it might be defined on some

View File

@ -397,12 +397,12 @@ complex_repr(PyComplexObject *v)
static Py_hash_t static Py_hash_t
complex_hash(PyComplexObject *v) complex_hash(PyComplexObject *v)
{ {
unsigned long hashreal, hashimag, combined; Py_uhash_t hashreal, hashimag, combined;
hashreal = (unsigned long)_Py_HashDouble(v->cval.real); hashreal = (Py_uhash_t)_Py_HashDouble(v->cval.real);
if (hashreal == (unsigned long)-1) if (hashreal == (Py_uhash_t)-1)
return -1; return -1;
hashimag = (unsigned long)_Py_HashDouble(v->cval.imag); hashimag = (Py_uhash_t)_Py_HashDouble(v->cval.imag);
if (hashimag == (unsigned long)-1) if (hashimag == (Py_uhash_t)-1)
return -1; return -1;
/* Note: if the imaginary part is 0, hashimag is 0 now, /* Note: if the imaginary part is 0, hashimag is 0 now,
* so the following returns hashreal unchanged. This is * so the following returns hashreal unchanged. This is
@ -411,8 +411,8 @@ complex_hash(PyComplexObject *v)
* hash(x + 0*j) must equal hash(x). * hash(x + 0*j) must equal hash(x).
*/ */
combined = hashreal + _PyHASH_IMAG * hashimag; combined = hashreal + _PyHASH_IMAG * hashimag;
if (combined == (unsigned long)-1) if (combined == (Py_uhash_t)-1)
combined = (unsigned long)-2; combined = (Py_uhash_t)-2;
return (Py_hash_t)combined; return (Py_hash_t)combined;
} }

View File

@ -2555,7 +2555,7 @@ long_richcompare(PyObject *self, PyObject *other, int op)
static Py_hash_t static Py_hash_t
long_hash(PyLongObject *v) long_hash(PyLongObject *v)
{ {
unsigned long x; Py_uhash_t x;
Py_ssize_t i; Py_ssize_t i;
int sign; int sign;
@ -2604,8 +2604,8 @@ long_hash(PyLongObject *v)
x -= _PyHASH_MODULUS; x -= _PyHASH_MODULUS;
} }
x = x * sign; x = x * sign;
if (x == (unsigned long)-1) if (x == (Py_uhash_t)-1)
x = (unsigned long)-2; x = (Py_uhash_t)-2;
return (Py_hash_t)x; return (Py_hash_t)x;
} }

View File

@ -692,7 +692,7 @@ _Py_HashDouble(double v)
{ {
int e, sign; int e, sign;
double m; double m;
unsigned long x, y; Py_uhash_t x, y;
if (!Py_IS_FINITE(v)) { if (!Py_IS_FINITE(v)) {
if (Py_IS_INFINITY(v)) if (Py_IS_INFINITY(v))
@ -716,7 +716,7 @@ _Py_HashDouble(double v)
x = ((x << 28) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - 28); x = ((x << 28) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - 28);
m *= 268435456.0; /* 2**28 */ m *= 268435456.0; /* 2**28 */
e -= 28; e -= 28;
y = (unsigned long)m; /* pull out integer part */ y = (Py_uhash_t)m; /* pull out integer part */
m -= y; m -= y;
x += y; x += y;
if (x >= _PyHASH_MODULUS) if (x >= _PyHASH_MODULUS)
@ -728,8 +728,8 @@ _Py_HashDouble(double v)
x = ((x << e) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - e); x = ((x << e) & _PyHASH_MODULUS) | x >> (_PyHASH_BITS - e);
x = x * sign; x = x * sign;
if (x == (unsigned long)-1) if (x == (Py_uhash_t)-1)
x = (unsigned long)-2; x = (Py_uhash_t)-2;
return (Py_hash_t)x; return (Py_hash_t)x;
} }

View File

@ -318,7 +318,7 @@ tuplehash(PyTupleObject *v)
register Py_hash_t x, y; register Py_hash_t x, y;
register Py_ssize_t len = Py_SIZE(v); register Py_ssize_t len = Py_SIZE(v);
register PyObject **p; register PyObject **p;
long mult = 1000003L; Py_hash_t mult = 1000003L;
x = 0x345678L; x = 0x345678L;
p = v->ob_item; p = v->ob_item;
while (--len >= 0) { while (--len >= 0) {
@ -327,7 +327,7 @@ tuplehash(PyTupleObject *v)
return -1; return -1;
x = (x ^ y) * mult; x = (x ^ y) * mult;
/* the cast might truncate len; that doesn't change hash stability */ /* the cast might truncate len; that doesn't change hash stability */
mult += (long)(82520L + len + len); mult += (Py_hash_t)(82520L + len + len);
} }
x += 97531L; x += 97531L;
if (x == -1) if (x == -1)

View File

@ -4314,14 +4314,14 @@ static PyObject *
wrap_hashfunc(PyObject *self, PyObject *args, void *wrapped) wrap_hashfunc(PyObject *self, PyObject *args, void *wrapped)
{ {
hashfunc func = (hashfunc)wrapped; hashfunc func = (hashfunc)wrapped;
long res; Py_hash_t res;
if (!check_num_args(args, 0)) if (!check_num_args(args, 0))
return NULL; return NULL;
res = (*func)(self); res = (*func)(self);
if (res == -1 && PyErr_Occurred()) if (res == -1 && PyErr_Occurred())
return NULL; return NULL;
return PyLong_FromLong(res); return PyLong_FromSsize_t(res);
} }
static PyObject * static PyObject *

View File

@ -569,7 +569,7 @@ get_hash_info(void)
PyStructSequence_SET_ITEM(hash_info, field++, PyStructSequence_SET_ITEM(hash_info, field++,
PyLong_FromLong(8*sizeof(Py_hash_t))); PyLong_FromLong(8*sizeof(Py_hash_t)));
PyStructSequence_SET_ITEM(hash_info, field++, PyStructSequence_SET_ITEM(hash_info, field++,
PyLong_FromLong(_PyHASH_MODULUS)); PyLong_FromSsize_t(_PyHASH_MODULUS));
PyStructSequence_SET_ITEM(hash_info, field++, PyStructSequence_SET_ITEM(hash_info, field++,
PyLong_FromLong(_PyHASH_INF)); PyLong_FromLong(_PyHASH_INF));
PyStructSequence_SET_ITEM(hash_info, field++, PyStructSequence_SET_ITEM(hash_info, field++,