Skip to content
Snippets Groups Projects
Commit ae801549 authored by dario.genga's avatar dario.genga
Browse files

Add hashtable methods

parent 8aec952c
No related branches found
No related tags found
No related merge requests found
......@@ -8,41 +8,156 @@
#include <stdlib.h>
#include <string.h>
int hash(char *key, int64_t length) {
// If the size of the int is too low the hash methods will generate overflow errors
int64_t val = 0;
for (size_t i = 0; i < strlen(key); i++) {
val = 43 * val + key[i];
}
return (val % length);
}
entry *entry_create_empty() {
entry *e = malloc(sizeof(entry));
e->key = NULL;
e->value = NULL;
e->next = NULL;
return e;
}
hm *hm_create(unsigned int length) {
hm *hashmap = malloc(sizeof(hm));
hashmap->length = length;
hashmap->entries = malloc(sizeof(entry) * length);
for (int i = 0; i < length; i++) {
hashmap->entries[i] = malloc(sizeof(entry));
for (size_t i = 0; i < length; i++) {
hashmap->entries[i] = entry_create_empty();
}
return hashmap;
}
entry *get_entry_by_key(entry *e, char *key) {
if (e->key == key) {
return e;
} else if (e->next != NULL) {
return get_entry_by_key(e->next, key);
} else {
return e;
}
}
void hm_destroy(hm **hm) {
for (int i = 0; i < (*hm)->length; i++) {
free((*hm)->entries[i]);
entry *e = (*hm)->entries[i];
while (e != NULL) {
entry *to_free = e;
e = e->next;
free(to_free);
}
}
free((*hm)->entries);
free((*hm));
(*hm) = NULL;
}
hm *hm_set(hm *hm, const char *const key, const char *const value) {
return NULL;
// Hash the key and get the corresponding entry
int key_index = hash((char *)key, hm->length);
entry *e = get_entry_by_key(hm->entries[key_index], (char *)key);
// Set the key and create the next entry if the key is not existing
if (e->key != key) {
e->key = (char *)key;
if (e->next == NULL) {
e->next = entry_create_empty();
}
}
// Set the entry value and return the hashmap
e->value = (char *)value;
return hm;
}
char *hm_get(const hm *const hm, const char *const key) {
return NULL;
int key_index = hash((char *)key, hm->length);
char *c = get_entry_by_key(hm->entries[key_index], (char *)key)->value;
return c;
}
char *hm_rm(hm *hm, const char *const key) {
return NULL;
int key_index = hash((char *)key, hm->length);
entry *e = get_entry_by_key(hm->entries[key_index], (char *)key);
entry *previous_entry = NULL;
entry *current_entry = hm->entries[key_index];
int entry_index = 0;
while (current_entry != e) {
previous_entry = current_entry;
current_entry = current_entry->next;
entry_index++;
}
if (entry_index == 0) {
hm->entries[key_index] = hm->entries[key_index]->next;
} else if (previous_entry != NULL) {
previous_entry->next = e->next;
}
char *entry_key = e->key;
free(e);
e = NULL;
return entry_key;
}
int get_entry_list_size(entry *e) {
int size = 0;
size += sizeof(e->key) + sizeof(e->value) + 16;
if (e->next != NULL) {
size += get_entry_list_size(e->next);
}
return size;
}
char *hmo_str(const hm *const hm) {
return NULL;
char *hm_to_str(const hm *const hm) {
int str_size = sizeof(hm) * hm->length;
for (int i = 0; i < hm->length; i++) {
str_size += get_entry_list_size(hm->entries[i]);
}
char *hm_str = malloc(str_size);
// Ensure that the string is empty before doing anything
hm_str[0] = '\0';
strcat(hm_str, "[\n");
for (int i = 0; i < hm->length; i++) {
strcat(hm_str, " [\n");
entry *e = hm->entries[i];
while (e != NULL && e->key != NULL) {
strcat(hm_str, " [\"");
strcat(hm_str, e->key);
strcat(hm_str, "\": \"");
strcat(hm_str, e->value);
strcat(hm_str, "\"]");
if (e->next != NULL && e->next->key != NULL) {
strcat(hm_str, ",");
}
strcat(hm_str, "\n");
e = e->next;
}
strcat(hm_str, " ]");
if (i < hm->length - 1) {
strcat(hm_str, ",");
}
strcat(hm_str, "\n");
}
strcat(hm_str, "]\n");
return hm_str;
}
void hm_print(const hm *const hm) {
return NULL;
char *str = hm_to_str(hm);
printf("%s\n", str);
free(str);
}
......@@ -9,6 +9,37 @@
int main() {
hm *hashmap = hm_create(10);
hm_set(hashmap, "Key1", "Value1");
hm_set(hashmap, "Key2", "Value1");
hm_set(hashmap, "Key1", "Value2");
hm_set(hashmap, "Key3", "Value1");
hm_set(hashmap, "Key4", "FOUR");
hm_set(hashmap, "Key1", "Value3");
hm_set(hashmap, "Key5", "I think it's good now");
hm_set(hashmap, "Key6", "6");
hm_set(hashmap, "Key7", "7");
hm_set(hashmap, "Key8", "8");
hm_set(hashmap, "Key9", "9");
hm_set(hashmap, "Key27", "MORE ?");
hm_set(hashmap, "Key10", "Is this the end ?");
printf("Value of %s : %s\n", "Key1", hm_get(hashmap, "Key1"));
printf("Value of %s : %s\n", "Key2", hm_get(hashmap, "Key2"));
printf("Value of %s : %s\n", "Key3", hm_get(hashmap, "Key3"));
printf("Value of %s : %s\n", "Key4", hm_get(hashmap, "Key4"));
printf("Value of %s : %s\n", "Key5", hm_get(hashmap, "Key5"));
printf("Value of %s : %s\n", "Key6", hm_get(hashmap, "Key6"));
printf("Value of %s : %s\n", "Key7", hm_get(hashmap, "Key7"));
printf("Value of %s : %s\n", "Key8", hm_get(hashmap, "Key8"));
printf("Value of %s : %s\n", "Key9", hm_get(hashmap, "Key9"));
printf("Value of %s : %s\n", "Key10", hm_get(hashmap, "Key10"));
hm_print(hashmap);
hm_rm(hashmap, "Key1");
hm_print(hashmap);
hm_rm(hashmap, "Key10");
hm_print(hashmap);
hm_destroy(&hashmap);
return EXIT_SUCCESS;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment