Victor Stinner | ed3b0bc | 2013-11-23 12:27:24 +0100 | [diff] [blame] | 1 | #ifndef Py_HASHTABLE_H |
| 2 | #define Py_HASHTABLE_H |
| 3 | |
| 4 | /* The whole API is private */ |
| 5 | #ifndef Py_LIMITED_API |
| 6 | |
| 7 | typedef struct _Py_slist_item_s { |
| 8 | struct _Py_slist_item_s *next; |
| 9 | } _Py_slist_item_t; |
| 10 | |
| 11 | typedef struct { |
| 12 | _Py_slist_item_t *head; |
| 13 | } _Py_slist_t; |
| 14 | |
| 15 | #define _Py_SLIST_ITEM_NEXT(ITEM) (((_Py_slist_item_t *)ITEM)->next) |
| 16 | |
| 17 | #define _Py_SLIST_HEAD(SLIST) (((_Py_slist_t *)SLIST)->head) |
| 18 | |
| 19 | typedef struct { |
| 20 | /* used by _Py_hashtable_t.buckets to link entries */ |
| 21 | _Py_slist_item_t _Py_slist_item; |
| 22 | |
| 23 | const void *key; |
| 24 | Py_uhash_t key_hash; |
| 25 | |
| 26 | /* data follows */ |
| 27 | } _Py_hashtable_entry_t; |
| 28 | |
Victor Stinner | d9a7352 | 2014-03-24 22:34:34 +0100 | [diff] [blame] | 29 | #define _Py_HASHTABLE_ENTRY_DATA(ENTRY) \ |
Victor Stinner | ed3b0bc | 2013-11-23 12:27:24 +0100 | [diff] [blame] | 30 | ((char *)(ENTRY) + sizeof(_Py_hashtable_entry_t)) |
| 31 | |
| 32 | #define _Py_HASHTABLE_ENTRY_DATA_AS_VOID_P(ENTRY) \ |
Victor Stinner | d9a7352 | 2014-03-24 22:34:34 +0100 | [diff] [blame] | 33 | (*(void **)_Py_HASHTABLE_ENTRY_DATA(ENTRY)) |
Victor Stinner | ed3b0bc | 2013-11-23 12:27:24 +0100 | [diff] [blame] | 34 | |
| 35 | #define _Py_HASHTABLE_ENTRY_READ_DATA(TABLE, DATA, DATA_SIZE, ENTRY) \ |
| 36 | do { \ |
| 37 | assert((DATA_SIZE) == (TABLE)->data_size); \ |
Victor Stinner | d9a7352 | 2014-03-24 22:34:34 +0100 | [diff] [blame] | 38 | memcpy(DATA, _Py_HASHTABLE_ENTRY_DATA(ENTRY), DATA_SIZE); \ |
Victor Stinner | ed3b0bc | 2013-11-23 12:27:24 +0100 | [diff] [blame] | 39 | } while (0) |
| 40 | |
| 41 | typedef Py_uhash_t (*_Py_hashtable_hash_func) (const void *key); |
| 42 | typedef int (*_Py_hashtable_compare_func) (const void *key, const _Py_hashtable_entry_t *he); |
| 43 | typedef void* (*_Py_hashtable_copy_data_func)(void *data); |
| 44 | typedef void (*_Py_hashtable_free_data_func)(void *data); |
| 45 | typedef size_t (*_Py_hashtable_get_data_size_func)(void *data); |
| 46 | |
| 47 | typedef struct { |
| 48 | /* allocate a memory block */ |
| 49 | void* (*malloc) (size_t size); |
| 50 | |
| 51 | /* release a memory block */ |
| 52 | void (*free) (void *ptr); |
| 53 | } _Py_hashtable_allocator_t; |
| 54 | |
| 55 | typedef struct { |
| 56 | size_t num_buckets; |
| 57 | size_t entries; /* Total number of entries in the table. */ |
| 58 | _Py_slist_t *buckets; |
| 59 | size_t data_size; |
| 60 | |
| 61 | _Py_hashtable_hash_func hash_func; |
| 62 | _Py_hashtable_compare_func compare_func; |
| 63 | _Py_hashtable_copy_data_func copy_data_func; |
| 64 | _Py_hashtable_free_data_func free_data_func; |
| 65 | _Py_hashtable_get_data_size_func get_data_size_func; |
| 66 | _Py_hashtable_allocator_t alloc; |
| 67 | } _Py_hashtable_t; |
| 68 | |
| 69 | /* hash and compare functions for integers and pointers */ |
| 70 | PyAPI_FUNC(Py_uhash_t) _Py_hashtable_hash_ptr(const void *key); |
| 71 | PyAPI_FUNC(Py_uhash_t) _Py_hashtable_hash_int(const void *key); |
| 72 | PyAPI_FUNC(int) _Py_hashtable_compare_direct(const void *key, const _Py_hashtable_entry_t *entry); |
| 73 | |
| 74 | PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new( |
| 75 | size_t data_size, |
| 76 | _Py_hashtable_hash_func hash_func, |
| 77 | _Py_hashtable_compare_func compare_func); |
| 78 | PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new_full( |
| 79 | size_t data_size, |
| 80 | size_t init_size, |
| 81 | _Py_hashtable_hash_func hash_func, |
| 82 | _Py_hashtable_compare_func compare_func, |
| 83 | _Py_hashtable_copy_data_func copy_data_func, |
| 84 | _Py_hashtable_free_data_func free_data_func, |
| 85 | _Py_hashtable_get_data_size_func get_data_size_func, |
| 86 | _Py_hashtable_allocator_t *allocator); |
| 87 | PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_copy(_Py_hashtable_t *src); |
| 88 | PyAPI_FUNC(void) _Py_hashtable_clear(_Py_hashtable_t *ht); |
| 89 | PyAPI_FUNC(void) _Py_hashtable_destroy(_Py_hashtable_t *ht); |
| 90 | |
| 91 | typedef int (*_Py_hashtable_foreach_func) (_Py_hashtable_entry_t *entry, void *arg); |
| 92 | |
| 93 | PyAPI_FUNC(int) _Py_hashtable_foreach( |
| 94 | _Py_hashtable_t *ht, |
| 95 | _Py_hashtable_foreach_func func, void *arg); |
| 96 | PyAPI_FUNC(size_t) _Py_hashtable_size(_Py_hashtable_t *ht); |
| 97 | |
| 98 | PyAPI_FUNC(_Py_hashtable_entry_t*) _Py_hashtable_get_entry( |
| 99 | _Py_hashtable_t *ht, |
| 100 | const void *key); |
| 101 | PyAPI_FUNC(int) _Py_hashtable_set( |
| 102 | _Py_hashtable_t *ht, |
| 103 | const void *key, |
| 104 | void *data, |
| 105 | size_t data_size); |
| 106 | PyAPI_FUNC(int) _Py_hashtable_get( |
| 107 | _Py_hashtable_t *ht, |
| 108 | const void *key, |
| 109 | void *data, |
| 110 | size_t data_size); |
| 111 | PyAPI_FUNC(int) _Py_hashtable_pop( |
| 112 | _Py_hashtable_t *ht, |
| 113 | const void *key, |
| 114 | void *data, |
| 115 | size_t data_size); |
| 116 | PyAPI_FUNC(void) _Py_hashtable_delete( |
| 117 | _Py_hashtable_t *ht, |
| 118 | const void *key); |
| 119 | |
| 120 | #define _Py_HASHTABLE_SET(TABLE, KEY, DATA) \ |
| 121 | _Py_hashtable_set(TABLE, KEY, &(DATA), sizeof(DATA)) |
| 122 | |
| 123 | #define _Py_HASHTABLE_GET(TABLE, KEY, DATA) \ |
| 124 | _Py_hashtable_get(TABLE, KEY, &(DATA), sizeof(DATA)) |
| 125 | |
| 126 | #endif /* Py_LIMITED_API */ |
| 127 | |
| 128 | #endif |