Thanks to visit codestin.com
Credit goes to github.com

Skip to content

bpo-40609: _Py_hashtable_t values become void* #20065

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 21 additions & 67 deletions Include/internal/pycore_hashtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,9 @@ typedef struct {

Py_uhash_t key_hash;
void *key;
/* data (data_size bytes) follows */
void *value;
} _Py_hashtable_entry_t;

#define _Py_HASHTABLE_ENTRY_PDATA(ENTRY) \
((const void *)((char *)(ENTRY) \
+ sizeof(_Py_hashtable_entry_t)))

#define _Py_HASHTABLE_ENTRY_READ_DATA(TABLE, ENTRY, DATA) \
do { \
assert(sizeof(DATA) == (TABLE)->data_size); \
memcpy(&(DATA), _Py_HASHTABLE_ENTRY_PDATA((ENTRY)), \
sizeof(DATA)); \
} while (0)


/* _Py_hashtable: prototypes */

Expand All @@ -55,12 +44,8 @@ typedef struct _Py_hashtable_t _Py_hashtable_t;
typedef Py_uhash_t (*_Py_hashtable_hash_func) (const void *key);
typedef int (*_Py_hashtable_compare_func) (const void *key1, const void *key2);
typedef void (*_Py_hashtable_destroy_func) (void *key);
typedef void (*_Py_hashtable_value_destroy_func) (_Py_hashtable_t *ht,
_Py_hashtable_entry_t *entry);
typedef _Py_hashtable_entry_t* (*_Py_hashtable_get_entry_func)(_Py_hashtable_t *ht,
const void *key);
typedef int (*_Py_hashtable_get_func) (_Py_hashtable_t *ht,
const void *key, void *data);

typedef struct {
/* allocate a memory block */
Expand All @@ -76,14 +61,12 @@ struct _Py_hashtable_t {
size_t num_buckets;
size_t entries; /* Total number of entries in the table. */
_Py_slist_t *buckets;
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_destroy_func key_destroy_func;
_Py_hashtable_value_destroy_func value_destroy_func;
_Py_hashtable_destroy_func value_destroy_func;
_Py_hashtable_allocator_t alloc;
};

Expand All @@ -96,95 +79,66 @@ PyAPI_FUNC(int) _Py_hashtable_compare_direct(
const void *key2);

PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new(
size_t data_size,
_Py_hashtable_hash_func hash_func,
_Py_hashtable_compare_func compare_func);

PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new_full(
size_t data_size,
size_t init_size,
_Py_hashtable_hash_func hash_func,
_Py_hashtable_compare_func compare_func,
_Py_hashtable_destroy_func key_destroy_func,
_Py_hashtable_value_destroy_func value_destroy_func,
_Py_hashtable_destroy_func value_destroy_func,
_Py_hashtable_allocator_t *allocator);

PyAPI_FUNC(void) _Py_hashtable_destroy(_Py_hashtable_t *ht);

PyAPI_FUNC(void) _Py_hashtable_clear(_Py_hashtable_t *ht);

typedef int (*_Py_hashtable_foreach_func) (_Py_hashtable_t *ht,
_Py_hashtable_entry_t *entry,
void *arg);
const void *key, const void *value,
void *user_data);

/* Call func() on each entry of the hashtable.
Iteration stops if func() result is non-zero, in this case it's the result
of the call. Otherwise, the function returns 0. */
PyAPI_FUNC(int) _Py_hashtable_foreach(
_Py_hashtable_t *ht,
_Py_hashtable_foreach_func func,
void *arg);
void *user_data);

PyAPI_FUNC(size_t) _Py_hashtable_size(_Py_hashtable_t *ht);
PyAPI_FUNC(size_t) _Py_hashtable_size(const _Py_hashtable_t *ht);

/* Add a new entry to the hash. The key must not be present in the hash table.
Return 0 on success, -1 on memory error.

Don't call directly this function,
but use _Py_HASHTABLE_SET() and _Py_HASHTABLE_SET_NODATA() macros */
Return 0 on success, -1 on memory error. */
PyAPI_FUNC(int) _Py_hashtable_set(
_Py_hashtable_t *ht,
const void *key,
size_t data_size,
const void *data);

#define _Py_HASHTABLE_SET(TABLE, KEY, DATA) \
_Py_hashtable_set(TABLE, (KEY), sizeof(DATA), &(DATA))

#define _Py_HASHTABLE_SET_NODATA(TABLE, KEY) \
_Py_hashtable_set(TABLE, (KEY), 0, NULL)
void *value);


/* Get an entry.
Return NULL if the key does not exist.

Don't call directly this function, but use _Py_HASHTABLE_GET_ENTRY()
macro */
Return NULL if the key does not exist. */
static inline _Py_hashtable_entry_t *
_Py_hashtable_get_entry(_Py_hashtable_t *ht, const void *key)
{
return ht->get_entry_func(ht, key);
}

#define _Py_HASHTABLE_GET_ENTRY(TABLE, KEY) \
_Py_hashtable_get_entry(TABLE, (const void *)(KEY))

/* Get value from an entry.
Return NULL if the entry is not found.

/* Get data from an entry. Copy entry data into data and return 1 if the entry
exists, return 0 if the entry does not exist.
Use _Py_hashtable_get_entry() to distinguish entry value equal to NULL
and entry not found. */
extern void *_Py_hashtable_get(_Py_hashtable_t *ht, const void *key);

Don't call directly this function, but use _Py_HASHTABLE_GET() macro */
static inline int
_Py_hashtable_get(_Py_hashtable_t *ht, const void *key,
size_t data_size, void *data)
{
assert(data_size == ht->data_size);
return ht->get_func(ht, key, data);
}

#define _Py_HASHTABLE_GET(TABLE, KEY, DATA) \
_Py_hashtable_get(TABLE, (KEY), sizeof(DATA), &(DATA))


/* Don't call directly this function, but use _Py_HASHTABLE_POP() macro */
PyAPI_FUNC(int) _Py_hashtable_pop(
// Remove a key and its associated value without calling key and value destroy
// functions.
// Return the removed value if the key was found.
// Return NULL if the key was not found.
PyAPI_FUNC(void*) _Py_hashtable_steal(
_Py_hashtable_t *ht,
const void *key,
size_t data_size,
void *data);

#define _Py_HASHTABLE_POP(TABLE, KEY, DATA) \
_Py_hashtable_pop(TABLE, (KEY), sizeof(DATA), &(DATA))
const void *key);


#ifdef __cplusplus
Expand Down
Loading