feature (hashmaps): implemented hashmaps (NOT TESTED YET)

This commit is contained in:
antifallobst 2023-05-29 16:23:03 +02:00
parent cd5737dba7
commit 713ffbc089
2 changed files with 112 additions and 0 deletions

28
inc/utils/hashmap.h Normal file
View File

@ -0,0 +1,28 @@
// This file is part of noxos and licensed under the MIT open source license
#ifndef NOXOS_HASHMAP_H
#define NOXOS_HASHMAP_H
#include <utils/stdtypes.h>
typedef struct hashmap_entry_T hashmap_entry_T;
struct hashmap_entry_T {
bool in_use;
uint64_t key;
void* value;
hashmap_entry_T* prev;
hashmap_entry_T* next;
};
typedef struct {
uint64_t size;
hashmap_entry_T* entries;
} hashmap_T;
hashmap_T hashmap_create (uint64_t size);
void hashmap_destruct (hashmap_T* hashmap);
void hashmap_insert (hashmap_T* hashmap, uint64_t key, void* value);
void hashmap_delete (hashmap_T* hashmap, uint64_t key);
void* hashmap_lookup (hashmap_T* hashmap, uint64_t key);
#endif //NOXOS_HASHMAP_H

84
src/utils/hashmap.c Normal file
View File

@ -0,0 +1,84 @@
// This file is part of noxos and licensed under the MIT open source license
#include <utils/hashmap.h>
#include <utils/memory.h>
hashmap_T hashmap_create(uint64_t size) {
hashmap_T hashmap;
hashmap.size = size;
hashmap.entries = memory_allocate(size * sizeof(hashmap_entry_T));
memory_set(hashmap.entries, 0, size * sizeof(hashmap_entry_T));
return hashmap;
}
void hashmap_destruct (hashmap_T* hashmap) {
for (uint64_t i = 0; i < hashmap->size; i++) {
hashmap_entry_T* entry = hashmap->entries[i].next;
while (entry != NULL) {
hashmap_entry_T* next = entry->next;
memory_free(entry);
entry = next;
}
}
memory_free(hashmap->entries);
}
void hashmap_insert(hashmap_T* hashmap, uint64_t key, void* value) {
uint64_t index = key % hashmap->size;
if (!hashmap->entries[index].in_use) {
hashmap->entries[index].key = key;
hashmap->entries[index].value = value;
hashmap->entries[index].in_use = true;
return;
}
hashmap_entry_T* entry = &hashmap->entries[index];
while (entry->next != NULL) entry = entry->next;
entry->next = memory_allocate(sizeof(hashmap_entry_T));
entry->next->prev = entry;
entry->next->key = key;
entry->next->value = value;
entry->next->in_use = true;
}
void hashmap_delete(hashmap_T* hashmap, uint64_t key) {
uint64_t index = key % hashmap->size;
hashmap_entry_T* entry = &hashmap->entries[index];
while (entry->key != key) {
if (entry->next == NULL) return;
entry = entry->next;
}
if (entry->prev != NULL) {
entry->prev->next = entry->next;
if (entry->next != NULL) entry->next->prev = entry->prev;
memory_free(entry);
return;
}
entry->key = 0;
entry->value = NULL;
entry->in_use = false;
}
void* hashmap_lookup(hashmap_T* hashmap, uint64_t key) {
uint64_t index = key % hashmap->size;
hashmap_entry_T* entry = &hashmap->entries[index];
while (entry->key != key) {
if (entry->next == NULL) return NULL;
entry = entry->next;
}
if (!entry->in_use) return NULL;
return entry->value;
}