From f453221c8b80e0570066a9375337f208d50e6406 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 12 May 2020 18:46:20 +0200 Subject: [PATCH] bpo-40602: Add _Py_HashPointerRaw() function (GH-20056) Add a new _Py_HashPointerRaw() function which avoids replacing -1 with -2 to micro-optimize hash table using pointer keys: using _Py_hashtable_hash_ptr() hash function. --- Include/pyhash.h | 2 ++ Python/hashtable.c | 2 +- Python/pyhash.c | 14 ++++++++++---- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Include/pyhash.h b/Include/pyhash.h index 2f398589cee..4437b870332 100644 --- a/Include/pyhash.h +++ b/Include/pyhash.h @@ -9,6 +9,8 @@ extern "C" { #ifndef Py_LIMITED_API PyAPI_FUNC(Py_hash_t) _Py_HashDouble(double); PyAPI_FUNC(Py_hash_t) _Py_HashPointer(const void*); +// Similar to _Py_HashPointer(), but don't replace -1 with -2 +PyAPI_FUNC(Py_hash_t) _Py_HashPointerRaw(const void*); PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t); #endif diff --git a/Python/hashtable.c b/Python/hashtable.c index 1548c2e4618..90fe34e6280 100644 --- a/Python/hashtable.c +++ b/Python/hashtable.c @@ -109,7 +109,7 @@ _Py_hashtable_hash_ptr(struct _Py_hashtable_t *ht, const void *pkey) { void *key; _Py_HASHTABLE_READ_KEY(ht, pkey, key); - return (Py_uhash_t)_Py_HashPointer(key); + return (Py_uhash_t)_Py_HashPointerRaw(key); } diff --git a/Python/pyhash.c b/Python/pyhash.c index a6f42e71cf6..3843079fbbc 100644 --- a/Python/pyhash.c +++ b/Python/pyhash.c @@ -129,16 +129,22 @@ _Py_HashDouble(double v) } Py_hash_t -_Py_HashPointer(const void *p) +_Py_HashPointerRaw(const void *p) { - Py_hash_t x; size_t y = (size_t)p; /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid excessive hash collisions for dicts and sets */ y = (y >> 4) | (y << (8 * SIZEOF_VOID_P - 4)); - x = (Py_hash_t)y; - if (x == -1) + return (Py_hash_t)y; +} + +Py_hash_t +_Py_HashPointer(const void *p) +{ + Py_hash_t x = _Py_HashPointerRaw(p); + if (x == -1) { x = -2; + } return x; }