Advertisement
sci4me

String Hash Table

Feb 6th, 2017
298
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.33 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <assert.h>
  3.  
  4. #include "hash_table.h"
  5. #include "types.h"
  6.  
  7. void hash_table_init(hash_table *ht) {
  8.     ht->entries = (hash_table_entry*) calloc(INITIAL_HASH_TABLE_ENTRIES, sizeof(hash_table_entry));
  9.     ht->num_entries = INITIAL_HASH_TABLE_ENTRIES;
  10.     ht->used_entries = 0;
  11. }
  12.  
  13. void hash_table_free(hash_table *ht) {
  14.     free(ht->entries);
  15.     free(ht);
  16. }
  17.  
  18. void hash_table_put(hash_table *ht, char *key, void *value) {
  19.     if(ht->used_entries == ht->num_entries) {
  20.         hash_table_resize(ht);
  21.     }
  22.  
  23.     s32 index = hash_table_find_index(ht, key);
  24.    
  25.     if(ht->entries[index].value) {
  26.         index = hash_table_probe(ht, index);
  27.     }
  28.  
  29.     assert(index != -1);
  30.  
  31.     if(value) {
  32.         ht->used_entries++;
  33.     } else {
  34.         ht->used_entries--;
  35.     }
  36.  
  37.     ht->entries[index].key = key;
  38.     ht->entries[index].value = value;      
  39. }
  40.  
  41. void* hash_table_get(hash_table *ht, char *key) {
  42.     s32 index = hash_table_find_index(ht, key);
  43.  
  44.     if(index == -1) {
  45.         return 0;
  46.     }
  47.  
  48.     return ht->entries[index].value;
  49. }
  50.  
  51. void hash_table_resize(hash_table *ht) {
  52.     u32 new_num_entries = ht->used_entries * 2;  
  53.  
  54.     if(new_num_entries == 0) {
  55.         new_num_entries = INITIAL_HASH_TABLE_ENTRIES;
  56.     }
  57.  
  58.     hash_table_entry *old_entries = ht->entries;
  59.     u32 old_num_entries = ht->num_entries;
  60.  
  61.     ht->entries = (hash_table_entry*) calloc(new_num_entries, sizeof(hash_table_entry));
  62.     ht->num_entries = new_num_entries;
  63.     ht->used_entries = 0;
  64.    
  65.     u32 index;
  66.     for(index = 0; index < old_num_entries; index++) {
  67.         hash_table_entry entry = old_entries[index];
  68.  
  69.         if(entry.value) {
  70.             hash_table_put(ht, old_entries[index].key, old_entries[index].value);
  71.         }
  72.     }
  73.  
  74.     free(old_entries);
  75. }
  76.  
  77. s32 hash_table_find_index(hash_table *ht, char *key) {
  78.     return (s32) (hash_string(key) % ht->num_entries);
  79. }
  80.  
  81. s32 hash_table_probe(hash_table *ht, s32 index) {
  82.     do {
  83.         index++;
  84.  
  85.         if(index >= ht->num_entries) {
  86.             return -1;
  87.         }
  88.     } while(ht->entries[index].value);
  89.  
  90.     return index;
  91. }
  92.  
  93. u64 hash_string(char *str) {
  94.     if(!str) {
  95.         return 0;
  96.     }
  97.  
  98.     u64 hash = 5381;
  99.    
  100.     u8 c;
  101.     while(c = *str++) {
  102.         hash = ((hash << 5) + hash) + c;
  103.     }
  104.  
  105.     return hash;
  106. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement