Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f9b3b58

Browse filesBrowse files
authored
bpo-40609: Remove _Py_hashtable_t.key_size (GH-20060)
Rewrite _Py_hashtable_t type to always store the key as a "const void *" pointer. Add an explicit "key" member to _Py_hashtable_entry_t. Remove _Py_hashtable_t.key_size member. hash and compare functions drop their hash table parameter, and their 'key' parameter type becomes "const void *".
1 parent 9e2ca17 commit f9b3b58
Copy full SHA for f9b3b58

File tree

4 files changed

+120
-188
lines changed
Filter options

4 files changed

+120
-188
lines changed

‎Include/internal/pycore_hashtable.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_hashtable.h
+21-53Lines changed: 21 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -30,32 +30,13 @@ typedef struct {
3030
_Py_slist_item_t _Py_slist_item;
3131

3232
Py_uhash_t key_hash;
33-
34-
/* key (key_size bytes) and then data (data_size bytes) follows */
33+
void *key;
34+
/* data (data_size bytes) follows */
3535
} _Py_hashtable_entry_t;
3636

37-
#define _Py_HASHTABLE_ENTRY_PKEY(ENTRY) \
38-
((const void *)((char *)(ENTRY) \
39-
+ sizeof(_Py_hashtable_entry_t)))
40-
4137
#define _Py_HASHTABLE_ENTRY_PDATA(TABLE, ENTRY) \
4238
((const void *)((char *)(ENTRY) \
43-
+ sizeof(_Py_hashtable_entry_t) \
44-
+ (TABLE)->key_size))
45-
46-
/* Get a key value from pkey: use memcpy() rather than a pointer dereference
47-
to avoid memory alignment issues. */
48-
#define _Py_HASHTABLE_READ_KEY(TABLE, PKEY, DST_KEY) \
49-
do { \
50-
assert(sizeof(DST_KEY) == (TABLE)->key_size); \
51-
memcpy(&(DST_KEY), (PKEY), sizeof(DST_KEY)); \
52-
} while (0)
53-
54-
#define _Py_HASHTABLE_ENTRY_READ_KEY(TABLE, ENTRY, KEY) \
55-
do { \
56-
assert(sizeof(KEY) == (TABLE)->key_size); \
57-
memcpy(&(KEY), _Py_HASHTABLE_ENTRY_PKEY(ENTRY), sizeof(KEY)); \
58-
} while (0)
39+
+ sizeof(_Py_hashtable_entry_t)))
5940

6041
#define _Py_HASHTABLE_ENTRY_READ_DATA(TABLE, ENTRY, DATA) \
6142
do { \
@@ -78,15 +59,12 @@ typedef struct {
7859
struct _Py_hashtable_t;
7960
typedef struct _Py_hashtable_t _Py_hashtable_t;
8061

81-
typedef Py_uhash_t (*_Py_hashtable_hash_func) (_Py_hashtable_t *ht,
82-
const void *pkey);
83-
typedef int (*_Py_hashtable_compare_func) (_Py_hashtable_t *ht,
84-
const void *pkey,
85-
const _Py_hashtable_entry_t *he);
62+
typedef Py_uhash_t (*_Py_hashtable_hash_func) (const void *key);
63+
typedef int (*_Py_hashtable_compare_func) (const void *key1, const void *key2);
8664
typedef _Py_hashtable_entry_t* (*_Py_hashtable_get_entry_func)(_Py_hashtable_t *ht,
87-
const void *pkey);
65+
const void *key);
8866
typedef int (*_Py_hashtable_get_func) (_Py_hashtable_t *ht,
89-
const void *pkey, void *data);
67+
const void *key, void *data);
9068

9169
typedef struct {
9270
/* allocate a memory block */
@@ -102,7 +80,6 @@ struct _Py_hashtable_t {
10280
size_t num_buckets;
10381
size_t entries; /* Total number of entries in the table. */
10482
_Py_slist_t *buckets;
105-
size_t key_size;
10683
size_t data_size;
10784

10885
_Py_hashtable_get_func get_func;
@@ -113,24 +90,19 @@ struct _Py_hashtable_t {
11390
};
11491

11592
/* hash a pointer (void*) */
116-
PyAPI_FUNC(Py_uhash_t) _Py_hashtable_hash_ptr(
117-
struct _Py_hashtable_t *ht,
118-
const void *pkey);
93+
PyAPI_FUNC(Py_uhash_t) _Py_hashtable_hash_ptr(const void *key);
11994

12095
/* comparison using memcmp() */
12196
PyAPI_FUNC(int) _Py_hashtable_compare_direct(
122-
_Py_hashtable_t *ht,
123-
const void *pkey,
124-
const _Py_hashtable_entry_t *entry);
97+
const void *key1,
98+
const void *key2);
12599

126100
PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new(
127-
size_t key_size,
128101
size_t data_size,
129102
_Py_hashtable_hash_func hash_func,
130103
_Py_hashtable_compare_func compare_func);
131104

132105
PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new_full(
133-
size_t key_size,
134106
size_t data_size,
135107
size_t init_size,
136108
_Py_hashtable_hash_func hash_func,
@@ -165,16 +137,15 @@ PyAPI_FUNC(size_t) _Py_hashtable_size(_Py_hashtable_t *ht);
165137
but use _Py_HASHTABLE_SET() and _Py_HASHTABLE_SET_NODATA() macros */
166138
PyAPI_FUNC(int) _Py_hashtable_set(
167139
_Py_hashtable_t *ht,
168-
size_t key_size,
169-
const void *pkey,
140+
const void *key,
170141
size_t data_size,
171142
const void *data);
172143

173144
#define _Py_HASHTABLE_SET(TABLE, KEY, DATA) \
174-
_Py_hashtable_set(TABLE, sizeof(KEY), &(KEY), sizeof(DATA), &(DATA))
145+
_Py_hashtable_set(TABLE, (KEY), sizeof(DATA), &(DATA))
175146

176147
#define _Py_HASHTABLE_SET_NODATA(TABLE, KEY) \
177-
_Py_hashtable_set(TABLE, sizeof(KEY), &(KEY), 0, NULL)
148+
_Py_hashtable_set(TABLE, (KEY), 0, NULL)
178149

179150

180151
/* Get an entry.
@@ -183,43 +154,40 @@ PyAPI_FUNC(int) _Py_hashtable_set(
183154
Don't call directly this function, but use _Py_HASHTABLE_GET_ENTRY()
184155
macro */
185156
static inline _Py_hashtable_entry_t *
186-
_Py_hashtable_get_entry(_Py_hashtable_t *ht, size_t key_size, const void *pkey)
157+
_Py_hashtable_get_entry(_Py_hashtable_t *ht, const void *key)
187158
{
188-
assert(key_size == ht->key_size);
189-
return ht->get_entry_func(ht, pkey);
159+
return ht->get_entry_func(ht, key);
190160
}
191161

192162
#define _Py_HASHTABLE_GET_ENTRY(TABLE, KEY) \
193-
_Py_hashtable_get_entry(TABLE, sizeof(KEY), &(KEY))
163+
_Py_hashtable_get_entry(TABLE, (const void *)(KEY))
194164

195165

196166
/* Get data from an entry. Copy entry data into data and return 1 if the entry
197167
exists, return 0 if the entry does not exist.
198168
199169
Don't call directly this function, but use _Py_HASHTABLE_GET() macro */
200170
static inline int
201-
_Py_hashtable_get(_Py_hashtable_t *ht, size_t key_size, const void *pkey,
171+
_Py_hashtable_get(_Py_hashtable_t *ht, const void *key,
202172
size_t data_size, void *data)
203173
{
204-
assert(key_size == ht->key_size);
205174
assert(data_size == ht->data_size);
206-
return ht->get_func(ht, pkey, data);
175+
return ht->get_func(ht, key, data);
207176
}
208177

209178
#define _Py_HASHTABLE_GET(TABLE, KEY, DATA) \
210-
_Py_hashtable_get(TABLE, sizeof(KEY), &(KEY), sizeof(DATA), &(DATA))
179+
_Py_hashtable_get(TABLE, (KEY), sizeof(DATA), &(DATA))
211180

212181

213182
/* Don't call directly this function, but use _Py_HASHTABLE_POP() macro */
214183
PyAPI_FUNC(int) _Py_hashtable_pop(
215184
_Py_hashtable_t *ht,
216-
size_t key_size,
217-
const void *pkey,
185+
const void *key,
218186
size_t data_size,
219187
void *data);
220188

221189
#define _Py_HASHTABLE_POP(TABLE, KEY, DATA) \
222-
_Py_hashtable_pop(TABLE, sizeof(KEY), &(KEY), sizeof(DATA), &(DATA))
190+
_Py_hashtable_pop(TABLE, (KEY), sizeof(DATA), &(DATA))
223191

224192

225193
#ifdef __cplusplus

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.