2026-03-13 02:56:29 +00:00
|
|
|
#include "hashmap.h"
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
void init_map(HashMap *map) {
|
|
|
|
|
memset(map, 0, sizeof(HashMap));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long long hash(const char *s) {
|
|
|
|
|
const int p = 100;
|
|
|
|
|
const int m = 1e9 + 9;
|
|
|
|
|
long p_pow = 1;
|
|
|
|
|
long value = 0;
|
|
|
|
|
const unsigned long len = strlen(s);
|
|
|
|
|
for (unsigned long i = 0; i < len; i++) {
|
|
|
|
|
unsigned char c = s[i];
|
|
|
|
|
value = (value + (c - 'a' + 1) * p_pow) % m;
|
|
|
|
|
p_pow = (p_pow * p) % m;
|
|
|
|
|
}
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-13 04:22:02 +00:00
|
|
|
void *map_get(HashMap *map, char *key) {
|
2026-03-13 02:56:29 +00:00
|
|
|
Bucket *bucket = &map->buckets[hash(key) % HASHMAP_BUCKETS];
|
|
|
|
|
Entry *entry = NULL;
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < bucket->n_entries; i++) {
|
|
|
|
|
if (!strcmp(bucket->entries[i].key, key))
|
|
|
|
|
return bucket->entries[i].data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-13 04:22:02 +00:00
|
|
|
Entry *map_set(HashMap *map, char *key, void *data, size_t data_size) {
|
2026-03-13 02:56:29 +00:00
|
|
|
Bucket *bucket = &map->buckets[hash(key) % HASHMAP_BUCKETS];
|
|
|
|
|
Entry *entry = NULL;
|
|
|
|
|
|
|
|
|
|
size_t i = 0;
|
|
|
|
|
for (; i < bucket->n_entries; i++) {
|
|
|
|
|
entry = &bucket->entries[i];
|
|
|
|
|
if (!strcmp(entry->key, key)) {
|
|
|
|
|
// entry exists; replace data
|
|
|
|
|
entry->data = data;
|
|
|
|
|
return entry;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// entry doesn't exist; insert data
|
|
|
|
|
if (i >= BUCKET_ENTRIES) {
|
|
|
|
|
fprintf(stderr, "set \"%s\": bucket is full\n", key);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
entry = &bucket->entries[i];
|
|
|
|
|
entry->key = strdup(key);
|
|
|
|
|
entry->data = data;
|
|
|
|
|
entry->data_size = data_size;
|
|
|
|
|
bucket->n_entries++;
|
|
|
|
|
return entry;
|
|
|
|
|
}
|