#ifndef HASHTABLE_H #define HASHTABLE_H #include #include /****************** DEFINTIIONS ******************/ #define HT_MINIMUM_CAPACITY 8 #define HT_LOAD_FACTOR 5 #define HT_MINIMUM_THRESHOLD (HT_MINIMUM_CAPACITY) * (HT_LOAD_FACTOR) #define HT_GROWTH_FACTOR 2 #define HT_SHRINK_THRESHOLD (1 / 4) #define HT_ERROR -1 #define HT_SUCCESS 0 #define HT_UPDATED 1 #define HT_INSERTED 0 #define HT_NOT_FOUND 0 #define HT_FOUND 01 #define HT_INITIALIZER {0, 0, 0, 0, 0, NULL, NULL, NULL}; typedef int (*comparison_t)(void*, void*, size_t); typedef size_t (*hash_t)(void*, size_t); /****************** STRUCTURES ******************/ typedef struct HTNode { struct HTNode* next; void* key; void* value; } HTNode; typedef struct HashTable { size_t size; size_t threshold; size_t capacity; size_t key_size; size_t value_size; comparison_t compare; hash_t hash; HTNode** nodes; } HashTable; /****************** INTERFACE ******************/ /* Setup */ int ht_setup(HashTable* table, size_t key_size, size_t value_size, size_t capacity); int ht_copy(HashTable* first, HashTable* second); int ht_move(HashTable* first, HashTable* second); int ht_swap(HashTable* first, HashTable* second); /* Destructor */ int ht_destroy(HashTable* table); int ht_insert(HashTable* table, void* key, void* value); int ht_contains(HashTable* table, void* key); void* ht_lookup(HashTable* table, void* key); const void* ht_const_lookup(const HashTable* table, void* key); #define HT_LOOKUP_AS(type, table_pointer, key_pointer) \ (*(type*)ht_lookup((table_pointer), (key_pointer))) int ht_erase(HashTable* table, void* key); int ht_clear(HashTable* table); int ht_is_empty(HashTable* table); bool ht_is_initialized(HashTable* table); int ht_reserve(HashTable* table, size_t minimum_capacity); /****************** PRIVATE ******************/ void _ht_int_swap(size_t* first, size_t* second); void _ht_pointer_swap(void** first, void** second); size_t _ht_default_hash(void* key, size_t key_size); int _ht_default_compare(void* first_key, void* second_key, size_t key_size); size_t _ht_hash(const HashTable* table, void* key); bool _ht_equal(const HashTable* table, void* first_key, void* second_key); bool _ht_should_grow(HashTable* table); bool _ht_should_shrink(HashTable* table); HTNode* _ht_create_node(HashTable* table, void* key, void* value, HTNode* next); int _ht_push_front(HashTable* table, size_t index, void* key, void* value); void _ht_destroy_node(HTNode* node); int _ht_adjust_capacity(HashTable* table); int _ht_allocate(HashTable* table, size_t capacity); int _ht_resize(HashTable* table, size_t new_capacity); void _ht_rehash(HashTable* table, HTNode** old, size_t old_capacity); #endif /* HASHTABLE_H */