pawengine/hashmap.c

90 lines
2.1 KiB
C
Raw Normal View History

2025-02-09 18:48:25 +01:00
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "log.h"
#define HASH_MASK 0b111111
#define TYPE uint32_t
struct Node_ui32 {
TYPE v;
struct Node_ui32 *next;
};
struct Bucket_ui32 {
struct Node_ui32 *nodes;
};
struct Hashmap_ui32 {
struct Bucket_ui32 buckets[HASH_MASK + 1];
};
struct Hashmap_ui32 *create_hashmap_ui32() {
struct Hashmap_ui32 *map = malloc(sizeof(struct Hashmap_ui32));
for (int i = 0; i <= HASH_MASK; i++) {
map->buckets[i].nodes = NULL;
}
return map;
}
void destroy_hashmap_ui32(struct Hashmap_ui32 *map) {
for (int i = 0; i <= HASH_MASK; i++) {
struct Node_ui32 *node = map->buckets[i].nodes;
while (node != NULL) {
struct Node_ui32 *tmp = node;
node = tmp->next;
free(tmp);
}
}
memset(map, 0, sizeof(struct Hashmap_ui32));
free(map);
}
int hash(TYPE v) { return v & HASH_MASK; }
void insert_hashmap_ui32(struct Hashmap_ui32 *map, TYPE v) {
int h = hash(v);
struct Node_ui32 *node = map->buckets[h].nodes;
while (node != NULL) {
if (node->v == v) {
meow("%d was already in hashmap", v);
return;
}
node = node->next;
}
struct Node_ui32 *n = malloc(sizeof(struct Node_ui32));
n->v = v;
n->next = map->buckets[h].nodes;
map->buckets[h].nodes = n;
}
void remove_hashmap_ui32(struct Hashmap_ui32 *map, TYPE v) {
int h = hash(v);
struct Node_ui32 *prev = NULL;
struct Node_ui32 *node = map->buckets[h].nodes;
while (node != NULL) {
if (node->v == v) {
if (prev == NULL) {
if (node->next == NULL) {
map->buckets[h].nodes = NULL;
} else {
map->buckets[h].nodes = node->next;
}
} else {
prev->next = node->next;
}
free(node);
return;
}
node = node->next;
}
meow("did not find %d in hashmap", v);
}
bool get_hashmap_ui32(struct Hashmap_ui32 *map, TYPE v) {
int h = hash(v);
struct Node_ui32 *node = map->buckets[h].nodes;
while (node != NULL) {
if (node->v == v) {
return true;
}
node = node->next;
}
return false;
}