summaryrefslogtreecommitdiff
path: root/Include/internal
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-05-12 13:31:59 +0200
committerGitHub <noreply@github.com>2020-05-12 13:31:59 +0200
commit7c6e97077525f0ad3cfa0971028313b9079449fd (patch)
treec97302b548f2ff97e4a275cf004e116b5c1b91df /Include/internal
parent74ea6b5a7501fb393cd567fb21998d0bfeeb267c (diff)
downloadcpython-git-7c6e97077525f0ad3cfa0971028313b9079449fd.tar.gz
bpo-40602: Optimize _Py_hashtable for pointer keys (GH-20051)
Optimize _Py_hashtable_get() and _Py_hashtable_get_entry() for pointer keys: * key_size == sizeof(void*) * hash_func == _Py_hashtable_hash_ptr * compare_func == _Py_hashtable_compare_direct Changes: * Add get_func and get_entry_func members to _Py_hashtable_t * Convert _Py_hashtable_get() and _Py_hashtable_get_entry() functions to static nline functions. * Add specialized get and get entry for pointer keys.
Diffstat (limited to 'Include/internal')
-rw-r--r--Include/internal/pycore_hashtable.h40
1 files changed, 25 insertions, 15 deletions
diff --git a/Include/internal/pycore_hashtable.h b/Include/internal/pycore_hashtable.h
index 585f76b51d..6e094e9437 100644
--- a/Include/internal/pycore_hashtable.h
+++ b/Include/internal/pycore_hashtable.h
@@ -76,12 +76,17 @@ typedef struct {
/* Forward declaration */
struct _Py_hashtable_t;
+typedef struct _Py_hashtable_t _Py_hashtable_t;
-typedef Py_uhash_t (*_Py_hashtable_hash_func) (struct _Py_hashtable_t *ht,
+typedef Py_uhash_t (*_Py_hashtable_hash_func) (_Py_hashtable_t *ht,
const void *pkey);
-typedef int (*_Py_hashtable_compare_func) (struct _Py_hashtable_t *ht,
+typedef int (*_Py_hashtable_compare_func) (_Py_hashtable_t *ht,
const void *pkey,
const _Py_hashtable_entry_t *he);
+typedef _Py_hashtable_entry_t* (*_Py_hashtable_get_entry_func)(_Py_hashtable_t *ht,
+ const void *pkey);
+typedef int (*_Py_hashtable_get_func) (_Py_hashtable_t *ht,
+ const void *pkey, void *data);
typedef struct {
/* allocate a memory block */
@@ -93,18 +98,19 @@ typedef struct {
/* _Py_hashtable: table */
-
-typedef struct _Py_hashtable_t {
+struct _Py_hashtable_t {
size_t num_buckets;
size_t entries; /* Total number of entries in the table. */
_Py_slist_t *buckets;
size_t key_size;
size_t data_size;
+ _Py_hashtable_get_func get_func;
+ _Py_hashtable_get_entry_func get_entry_func;
_Py_hashtable_hash_func hash_func;
_Py_hashtable_compare_func compare_func;
_Py_hashtable_allocator_t alloc;
-} _Py_hashtable_t;
+};
/* hash a pointer (void*) */
PyAPI_FUNC(Py_uhash_t) _Py_hashtable_hash_ptr(
@@ -176,10 +182,12 @@ PyAPI_FUNC(int) _Py_hashtable_set(
Don't call directly this function, but use _Py_HASHTABLE_GET_ENTRY()
macro */
-PyAPI_FUNC(_Py_hashtable_entry_t*) _Py_hashtable_get_entry(
- _Py_hashtable_t *ht,
- size_t key_size,
- const void *pkey);
+static inline _Py_hashtable_entry_t *
+_Py_hashtable_get_entry(_Py_hashtable_t *ht, size_t key_size, const void *pkey)
+{
+ assert(key_size == ht->key_size);
+ return ht->get_entry_func(ht, pkey);
+}
#define _Py_HASHTABLE_GET_ENTRY(TABLE, KEY) \
_Py_hashtable_get_entry(TABLE, sizeof(KEY), &(KEY))
@@ -189,12 +197,14 @@ PyAPI_FUNC(_Py_hashtable_entry_t*) _Py_hashtable_get_entry(
exists, return 0 if the entry does not exist.
Don't call directly this function, but use _Py_HASHTABLE_GET() macro */
-PyAPI_FUNC(int) _Py_hashtable_get(
- _Py_hashtable_t *ht,
- size_t key_size,
- const void *pkey,
- size_t data_size,
- void *data);
+static inline int
+_Py_hashtable_get(_Py_hashtable_t *ht, size_t key_size, const void *pkey,
+ size_t data_size, void *data)
+{
+ assert(key_size == ht->key_size);
+ assert(data_size == ht->data_size);
+ return ht->get_func(ht, pkey, data);
+}
#define _Py_HASHTABLE_GET(TABLE, KEY, DATA) \
_Py_hashtable_get(TABLE, sizeof(KEY), &(KEY), sizeof(DATA), &(DATA))