diff options
author | Victor Stinner <vstinner@python.org> | 2023-12-06 14:09:22 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-06 14:09:22 (GMT) |
commit | 828451dfde324f9499ffebc023a22b84dc5a125b (patch) | |
tree | ceee17c26f9c9238b602ef9156e6eb8530d032f1 /Include | |
parent | f8852634edf1232ac1aa4561e34796b52f9f7aa2 (diff) | |
download | cpython-828451dfde324f9499ffebc023a22b84dc5a125b.zip cpython-828451dfde324f9499ffebc023a22b84dc5a125b.tar.gz cpython-828451dfde324f9499ffebc023a22b84dc5a125b.tar.bz2 |
gh-111545: Add Py_HashPointer() function (#112096)
* Implement _Py_HashPointerRaw() as a static inline function.
* Add Py_HashPointer() tests to test_capi.test_hash.
* Keep _Py_HashPointer() function as an alias to Py_HashPointer().
Diffstat (limited to 'Include')
-rw-r--r-- | Include/cpython/pyhash.h | 6 | ||||
-rw-r--r-- | Include/internal/pycore_pyhash.h | 16 |
2 files changed, 19 insertions, 3 deletions
diff --git a/Include/cpython/pyhash.h b/Include/cpython/pyhash.h index 6f7113d..396c208 100644 --- a/Include/cpython/pyhash.h +++ b/Include/cpython/pyhash.h @@ -21,7 +21,9 @@ /* Helpers for hash functions */ PyAPI_FUNC(Py_hash_t) _Py_HashDouble(PyObject *, double); -PyAPI_FUNC(Py_hash_t) _Py_HashPointer(const void*); + +// Kept for backward compatibility +#define _Py_HashPointer Py_HashPointer /* hash function definition */ @@ -33,3 +35,5 @@ typedef struct { } PyHash_FuncDef; PyAPI_FUNC(PyHash_FuncDef*) PyHash_GetFuncDef(void); + +PyAPI_FUNC(Py_hash_t) Py_HashPointer(const void *ptr); diff --git a/Include/internal/pycore_pyhash.h b/Include/internal/pycore_pyhash.h index c3b72d9..0ce0890 100644 --- a/Include/internal/pycore_pyhash.h +++ b/Include/internal/pycore_pyhash.h @@ -5,8 +5,20 @@ # error "this header requires Py_BUILD_CORE define" #endif -// Similar to _Py_HashPointer(), but don't replace -1 with -2 -extern Py_hash_t _Py_HashPointerRaw(const void*); +// Similar to Py_HashPointer(), but don't replace -1 with -2. +static inline Py_hash_t +_Py_HashPointerRaw(const void *ptr) +{ + uintptr_t x = (uintptr_t)ptr; + Py_BUILD_ASSERT(sizeof(x) == sizeof(ptr)); + + // Bottom 3 or 4 bits are likely to be 0; rotate x by 4 to the right + // to avoid excessive hash collisions for dicts and sets. + x = (x >> 4) | (x << (8 * sizeof(uintptr_t) - 4)); + + Py_BUILD_ASSERT(sizeof(x) == sizeof(Py_hash_t)); + return (Py_hash_t)x; +} // Export for '_datetime' shared extension PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t); |