Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // hash_table.h VV
- #ifndef HASH_TABLE_H
- #define HASH_TABLE_H
- #include <stdbool.h>
- #ifndef HASH_MODULUS // Allowing you to define your own hash modulus...
- // Except that it only works on the header, probably breaking if you set it. Needs a fix there.
- #define HASH_MODULUS 256
- #endif
- struct hash_bucket_t {
- bool owns_key;
- bool owns_value;
- void* key;
- void* value;
- struct hash_bucket_t* next; // Links directly to next bucket there
- };
- struct hash_table_t {
- struct hash_bucket_t buckets[HASH_MODULUS];
- unsigned int (*hash_function)(void*);
- bool (*equals_function)(void*,void*);
- };
- struct optional_t {
- bool is_present;
- void* value;
- };
- struct optional_t get_value_from_hash_table(struct hash_table_t table, void* key);
- void put_value_in_hash_table(struct hash_table_t* table, void* key, void* value, bool table_owns_key, bool table_owns_value);
- void free_hash_table(struct hash_table_t table); // PLEASE call after
- #endif
- // hash_table.c VV
- #include <stdlib.h>
- #include "hash_table.h"
- struct optional_t get_value_from_hash_table(struct hash_table_t table, void* key) {
- unsigned int hash = table.hash_function(key);
- unsigned int hash_modulo_result = hash % HASH_MODULUS;
- struct hash_bucket_t search_point = table.buckets[hash_modulo_result];
- bool found = false;
- struct optional_t result;
- result.is_present = false;
- result.value = NULL;
- if (search_point.key == NULL) {
- return result; // Not found
- }
- while (!found) {
- if (table.equals_function(key, search_point.key)) {
- result.value = search_point.value;
- result.is_present = true;
- found = true;
- } else {
- if (search_point.next == NULL) {
- found = true;
- } else {
- search_point = (*search_point.next);
- }
- }
- }
- return result;
- }
- /** NOTE You are expected to free your keys yourself. Values can be handled automatically */
- void put_value_in_hash_table(struct hash_table_t* table, void* key, void* value, bool table_owns_key, bool table_owns_value) {
- unsigned int hash = table->hash_function(key);
- unsigned int hash_modulo_result = hash % HASH_MODULUS;
- struct hash_bucket_t* placement_point = &table->buckets[hash_modulo_result];
- while (placement_point->key != NULL) {
- if (placement_point->next == NULL) {
- placement_point->next = (struct hash_bucket_t*)malloc(sizeof(struct hash_bucket_t));
- }
- placement_point = placement_point->next;
- }
- placement_point->key = key;
- placement_point->value = value;
- placement_point->owns_key = table_owns_key;
- placement_point->owns_value = table_owns_value;
- }
- static void recursive_bucket_free(struct hash_bucket_t bucket) {
- if (bucket.next != NULL) {
- recursive_bucket_free(*(bucket.next));
- }
- if (bucket.owns_value) {
- free(bucket.value);
- }
- if (bucket.owns_key) {
- free(bucket.key);
- }
- if (bucket.next != NULL) {
- free(bucket.next);
- }
- }
- void free_hash_table(struct hash_table_t table) {
- for (int i = 0; i < HASH_MODULUS; i++) {
- recursive_bucket_free(table.buckets[i]);
- }
- }
Advertisement