Files
visual-structs/src/hashtable.c
T

106 lines
2.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "../includes/hashtable.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
//Reference https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash
//FNV = FowlerNollVo
#define FNV_OFFSET 0xcbf29ce484222325 //Or 14695981039346656037 in decimal
#define FNV_PRIME 0x100000001b3 //Or 1099511628211 in decimal
#define DEFAULTHASHTABLESIZE 64
Bucket* CreateBucket();
void AddToBucket(char* key, char* text, Bucket* bucket);
HashTable* CreateHashTable(void) {
HashTable* table = calloc(1, sizeof(HashTable));
table->Values = calloc(DEFAULTHASHTABLESIZE, sizeof(Bucket*));
table->Capacity = DEFAULTHASHTABLESIZE;
return table;
}
void AddItemToHashTable(char* key, char* item, HashTable* table) {
//FNV-1a hash
unsigned long long hash = FNV_OFFSET;
for(int i = 0; i < strlen(key); i ++) {
hash ^= key[i];
hash *= FNV_PRIME;
}
unsigned int index = hash % table->Capacity;
Bucket* bucket = table->Values[index];
if (!bucket) table->Values[index] = CreateBucket();
AddToBucket(key, item, table->Values[index]);
}
char* HashTableBucketLinearScan(char* key, Bucket* bucket) {
for(int i = 0; i < bucket->Size; i++) {
BucketKeyPair* pair = bucket->KeyPairs[i];
if (strcmp(key, pair->Key) == 0) return pair->Value;
}
return NULL;
}
char* GetHashTableItem(char* key, HashTable* table) {
unsigned long long hash = FNV_OFFSET;
for(int i = 0; i < strlen(key); i ++) {
hash ^= key[i];
hash *= FNV_PRIME;
}
unsigned int index = hash % table->Capacity;
Bucket* bucket = table->Values[index];
if (!bucket) return NULL;
if (bucket->Size == 1) return bucket->KeyPairs[0]->Value;
return HashTableBucketLinearScan(key, bucket);
}
Bucket* CreateBucket() {
Bucket* bucket = calloc(1, sizeof(Bucket));
bucket->KeyPairs = calloc(16, sizeof(BucketKeyPair*));
bucket->Capacity = 16;
return bucket;
}
void AddToBucket(char* key, char* text, Bucket* bucket) {
BucketKeyPair* keyPair = calloc(1, sizeof(BucketKeyPair));
keyPair->Key = key;
keyPair->Value = text;
bucket->KeyPairs[bucket->Size] = keyPair;
bucket->Size++;
}
void PrintHashTable(HashTable* table) {
printf("Capacity %d\nBuckets:\n", table->Capacity);
for(int i = 0; i < table->Capacity; i++) {
Bucket* bucket = table->Values[i];
if (!bucket) continue;
printf("Bucket %d: \n", i+1);
for(int j = 0; j < bucket->Size; j++) {
printf("(%s) '%s'\n", bucket->KeyPairs[j]->Key, bucket->KeyPairs[j]->Value);
}
printf("\n");
}
}