Implement Breakpoints
This commit is contained in:
112
hash.c
Normal file
112
hash.c
Normal file
@@ -0,0 +1,112 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hash.h"
|
||||
|
||||
static uint64_t hashtable_hash(const char *key)
|
||||
{
|
||||
#define FNV_OFFSET 14695981039346656037UL
|
||||
#define FNV_PRIME 1099511628211UL
|
||||
|
||||
uint64_t hash = FNV_OFFSET;
|
||||
for (const char *p = key; *p; p++) {
|
||||
hash ^= (uint64_t)(unsigned char)(*p);
|
||||
hash *= FNV_PRIME;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
void hashtable_init (HashTable *t, size_t capacity)
|
||||
{
|
||||
memset(t, 0, sizeof(*t));
|
||||
|
||||
t->capacity = capacity;
|
||||
t->buckets = malloc(t->capacity * sizeof(*t->buckets));
|
||||
|
||||
for (int i = 0; i < t->capacity; i++) {
|
||||
t->buckets[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void hashtable_deinit (HashTable *t)
|
||||
{
|
||||
for (int i = 0; i < t->capacity; i++) {
|
||||
if (t->buckets[i] != NULL) {
|
||||
if (t->buckets[i]->key != NULL) {
|
||||
free((void *)t->buckets[i]->key);
|
||||
}
|
||||
free(t->buckets[i]);
|
||||
}
|
||||
}
|
||||
free(t->buckets);
|
||||
}
|
||||
|
||||
HashEntry * hashtable_new (const char *key, void *value, size_t sz)
|
||||
{
|
||||
HashEntry *e = malloc(sizeof(*e));
|
||||
e->key = malloc(strlen(key)+1);
|
||||
e->value = malloc(sz);
|
||||
e->sz = sz;
|
||||
strcpy((char*)e->key, key);
|
||||
memcpy(e->value, value, e->sz);
|
||||
return e;
|
||||
}
|
||||
|
||||
void * hashtable_get (HashTable *t, const char *key)
|
||||
{
|
||||
uint64_t hash = hashtable_hash(key);
|
||||
size_t index = (size_t)(hash % t->capacity);
|
||||
|
||||
for (int i = index; i < t->capacity; i++) {
|
||||
if (t->buckets[i] != NULL && t->buckets[i]->key != NULL && strcmp(t->buckets[i]->key, key) == 0) {
|
||||
return t->buckets[i]->value;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool hashtable_check (HashTable *t, const char *key)
|
||||
{
|
||||
return hashtable_get(t, key) != NULL;
|
||||
}
|
||||
|
||||
void hashtable_set (HashTable *t, const char *key, void *value, size_t sz)
|
||||
{
|
||||
uint64_t hash = hashtable_hash(key);
|
||||
size_t index = (size_t)(hash % t->capacity);
|
||||
|
||||
for (int i = index; i < t->capacity; i++) {
|
||||
if (t->buckets[i] == NULL) {
|
||||
HashEntry *e = hashtable_new(key, value, sz);
|
||||
t->buckets[i] = e;
|
||||
break;
|
||||
} else if (t->buckets[i] != NULL && t->buckets[i]->key != NULL && strcmp(t->buckets[i]->key, key) == 0) {
|
||||
t->buckets[i]->sz = sz;
|
||||
t->buckets[i]->value = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool hashtable_delete (HashTable *t, const char *key)
|
||||
{
|
||||
uint64_t hash = hashtable_hash(key);
|
||||
size_t index = (size_t)(hash % t->capacity);
|
||||
|
||||
for (int i = index; i < t->capacity; i++) {
|
||||
if (t->buckets[i] != NULL && t->buckets[i]->key != NULL && strcmp(t->buckets[i]->key, key) == 0) {
|
||||
HashEntry *e = t->buckets[i];
|
||||
free((void*)e->key);
|
||||
free((void*)e->value);
|
||||
free((void*)e);
|
||||
t->buckets[i] = NULL;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user