bluehorizons

My Hashtables

Jun 2nd, 2026
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.87 KB | None | 0 0
  1. #include <stdlib.h>
  2. #ifndef HASH_TABLE_H
  3. #define HASH_TABLE_H
  4.  
  5. #include <stdbool.h>
  6.  
  7. #ifndef HASH_MODULUS // Allowing you to define your own hash modulus...
  8. // Except that it only works on the header, probably breaking if you set it. Needs a fix there.
  9. #define HASH_MODULUS 256
  10. #endif
  11.  
  12. struct hash_bucket_t {
  13.     bool was_malloc_created;
  14.     bool does_own_value;
  15.     void* key;
  16.     void* value;
  17.     struct hash_bucket_t* next; // Links directly to next bucket there
  18. };
  19.  
  20. struct hash_table_t {
  21.     struct hash_bucket_t buckets[HASH_MODULUS];
  22.     unsigned int (*hash_function)(void*);
  23.     bool (*equals_function)(void*,void*);
  24. };
  25.  
  26. struct optional_t {
  27.     bool is_present;
  28.     void* value;
  29. };
  30.  
  31. struct optional_t get_value_from_hash_table(struct hash_table_t table, void* key);
  32.  
  33. void put_value_in_hash_table(struct hash_table_t* table, void* key, void* value, bool free_with_table);
  34.  
  35. void free_hash_table(struct hash_table_t table); // PLEASE call after
  36.  
  37. #endif
  38.  
  39.  
  40. struct optional_t get_value_from_hash_table(struct hash_table_t table, void* key) {
  41.     unsigned int hash = table.hash_function(key);
  42.  
  43.     unsigned int hash_modulo_result = hash % HASH_MODULUS;
  44.    
  45.     struct hash_bucket_t search_point = table.buckets[hash_modulo_result];
  46.    
  47.     bool found = false;
  48.     struct optional_t result;
  49.     result.is_present = false;
  50.     result.value = NULL;
  51.  
  52.     if (search_point.key == NULL) {
  53.         return result; // Not found
  54.     }
  55.  
  56.     while (!found) {
  57.         if (table.equals_function(key, search_point.key)) {
  58.             result.value = search_point.value;
  59.             result.is_present = true;
  60.             found = true;
  61.         } else {
  62.             if (search_point.next == NULL) {
  63.                 found = true;
  64.             } else {
  65.                 search_point = (*search_point.next);
  66.             }
  67.         }
  68.     }
  69.  
  70.     return result;
  71. }
  72.  
  73. /** NOTE You are expected to free your keys yourself. Values can be handled automatically */
  74. void put_value_in_hash_table(struct hash_table_t* table, void* key, void* value, bool free_with_table) {
  75.     unsigned int hash = table->hash_function(key);
  76.  
  77.     unsigned int hash_modulo_result = hash % HASH_MODULUS;
  78.  
  79.     struct hash_bucket_t placement_point = table->buckets[hash_modulo_result];
  80.  
  81.     while (placement_point.key != NULL) {
  82.         if (placement_point.next == NULL) {
  83.             placement_point.next = (struct hash_bucket_t*)malloc(sizeof(struct hash_bucket_t));
  84.             placement_point.next->was_malloc_created = true;
  85.         }
  86.         placement_point = (*placement_point.next);
  87.     }
  88.     placement_point.key = key;
  89.     placement_point.value = value;
  90.     placement_point.does_own_value = free_with_table;
  91. }
  92.  
  93. static void recursive_bucket_free(struct hash_bucket_t bucket) {
  94.     if (bucket.next != NULL) {
  95.         recursive_bucket_free(*(bucket.next));
  96.     }
  97.     if (bucket.does_own_value) {
  98.         free(bucket.value);
  99.     }
  100.     if (bucket.next->was_malloc_created) {
  101.         free(bucket.next);
  102.     }
  103. }
  104.  
  105. void free_hash_table(struct hash_table_t table) {
  106.     for (int i = 0; i < HASH_MODULUS; i++) {
  107.         recursive_bucket_free(table.buckets[i]);
  108.     }
  109. }
  110.  
Advertisement
Add Comment
Please, Sign In to add comment