Implemented a simple hash table using the FNV-1a hashing algorithm. Not drawing routines for it yet, just the bare data structure.
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef HASTABLE_H
|
||||||
|
#define HASTABLE_H
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char* Key;
|
||||||
|
char* Value;
|
||||||
|
} BucketKeyPair;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int Size;
|
||||||
|
unsigned int Capacity;
|
||||||
|
BucketKeyPair** KeyPairs;
|
||||||
|
} Bucket;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int Capacity;
|
||||||
|
Bucket** Values;
|
||||||
|
} HashTable;
|
||||||
|
|
||||||
|
HashTable* CreateHashTable(void);
|
||||||
|
void AddItemToHashTable(char* key, char* item, HashTable* table);
|
||||||
|
char* GetHashTableItem(char* key, HashTable* table);
|
||||||
|
void PrintHashTable(HashTable* table);
|
||||||
|
|
||||||
|
#endif
|
||||||
+106
@@ -0,0 +1,106 @@
|
|||||||
|
#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 = Fowler–Noll–Vo
|
||||||
|
#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");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <SDL2/SDL_ttf.h>
|
#include <SDL2/SDL_ttf.h>
|
||||||
#include "../includes/font_cache.h"
|
#include "../includes/font_cache.h"
|
||||||
#include "../includes/list.h"
|
#include "../includes/list.h"
|
||||||
|
#include "../includes/hashtable.h"
|
||||||
|
|
||||||
const int SCREEN_WIDTH = 1280;
|
const int SCREEN_WIDTH = 1280;
|
||||||
const int SCREEN_HEIGHT = 720;
|
const int SCREEN_HEIGHT = 720;
|
||||||
@@ -131,7 +132,13 @@ int main(int argc, char** argv){
|
|||||||
AddStringToList("Hello World! 4 and a reallly long sting", list);
|
AddStringToList("Hello World! 4 and a reallly long sting", list);
|
||||||
|
|
||||||
ListFontSizeHasChanged(app.renderer, GetFont(app.DefaultFontSize, app.FontCache), list);
|
ListFontSizeHasChanged(app.renderer, GetFont(app.DefaultFontSize, app.FontCache), list);
|
||||||
|
HashTable* table = CreateHashTable();
|
||||||
|
|
||||||
|
AddItemToHashTable("TEST", "Hello, World!", table);
|
||||||
|
AddItemToHashTable("TEST2", "Hello, World", table);
|
||||||
|
AddItemToHashTable("No here", "Hello, 3", table);
|
||||||
|
PrintHashTable(table);
|
||||||
|
printf("Got %s with key %s\n", GetHashTableItem("TEST", table), "TEST");
|
||||||
// Uint64 start = 0;
|
// Uint64 start = 0;
|
||||||
// Uint64 end = 0;
|
// Uint64 end = 0;
|
||||||
// float frameCount = 0;
|
// float frameCount = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user