2024-05-08 22:07:31 +00:00
|
|
|
#include "dictionary.h"
|
2024-05-15 22:10:47 +00:00
|
|
|
#include <stdalign.h>
|
2024-05-14 04:20:20 +00:00
|
|
|
#include <stdio.h>
|
2024-05-09 05:32:58 +00:00
|
|
|
#include <stdlib.h>
|
2024-05-08 22:07:31 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
bool CreateDictionary(struct Dictionary *dict, usize value_size)
|
2024-05-08 22:07:31 +00:00
|
|
|
{
|
2024-05-15 22:10:47 +00:00
|
|
|
void *bkts = calloc(16, value_size);
|
2024-05-08 22:07:31 +00:00
|
|
|
|
|
|
|
if (bkts == nullptr)
|
|
|
|
return false;
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
dict->value_size = value_size;
|
|
|
|
dict->value_offset = max(alignof(u32), alignof(u8[dict->value_size]));
|
|
|
|
dict->bkt_size = dict->value_offset + value_size;
|
|
|
|
|
|
|
|
dict->filled = 0;
|
|
|
|
dict->capacity = 16;
|
|
|
|
dict->bkts = bkts;
|
2024-05-08 22:07:31 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FreeDictionary(struct Dictionary *dict)
|
|
|
|
{
|
|
|
|
free(dict->bkts);
|
|
|
|
}
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
void *index_bkt(struct Dictionary *dict, usize i)
|
2024-05-08 22:07:31 +00:00
|
|
|
{
|
2024-05-15 22:10:47 +00:00
|
|
|
return (u8 *)dict->bkts + i * dict->bkt_size;
|
2024-05-08 22:07:31 +00:00
|
|
|
}
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
u32 *get_key(struct Dictionary *dict, void *bkt)
|
2024-05-08 22:07:31 +00:00
|
|
|
{
|
2024-05-09 05:32:58 +00:00
|
|
|
return (u32 *)bkt;
|
2024-05-08 22:07:31 +00:00
|
|
|
}
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
void *get_value_ptr(struct Dictionary *dict, void *bkt)
|
2024-05-08 22:07:31 +00:00
|
|
|
{
|
2024-05-15 22:10:47 +00:00
|
|
|
return (u8 *)bkt + dict->value_offset;
|
2024-05-08 22:07:31 +00:00
|
|
|
}
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
void set_bkt(struct Dictionary *dict, void *bkt, u32 key, void *value_ptr)
|
2024-05-09 05:32:58 +00:00
|
|
|
{
|
2024-05-15 22:10:47 +00:00
|
|
|
*get_key(dict, bkt) = key;
|
|
|
|
memcpy(get_value_ptr(dict, bkt), value_ptr, dict->value_size);
|
2024-05-09 05:32:58 +00:00
|
|
|
}
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
void *probe_bkt(struct Dictionary *dict, usize index, u32 key)
|
2024-05-08 22:07:31 +00:00
|
|
|
{
|
|
|
|
for (usize i = 0; i < dict->capacity; i++) {
|
2024-05-15 22:10:47 +00:00
|
|
|
void *bkt = index_bkt(dict, (index + i) % dict->capacity);
|
2024-05-08 22:07:31 +00:00
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
if (*get_key(dict, bkt) == key)
|
2024-05-08 22:07:31 +00:00
|
|
|
return bkt;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
void *probe_empty_bkt(struct Dictionary *dict, usize index, u32 key)
|
2024-05-08 22:07:31 +00:00
|
|
|
{
|
|
|
|
for (usize i = 0; i < dict->capacity; i++) {
|
2024-05-15 22:10:47 +00:00
|
|
|
void *bkt = index_bkt(dict, (index + i) % dict->capacity);
|
2024-05-08 22:07:31 +00:00
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
u32 k = *get_key(dict, bkt);
|
2024-05-08 22:07:31 +00:00
|
|
|
if (k == 0 or k == key)
|
|
|
|
return bkt;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
void *DictionaryFind(struct Dictionary *dict, u32 key)
|
2024-05-08 22:07:31 +00:00
|
|
|
{
|
|
|
|
usize index = key % dict->capacity;
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
void *bkt = probe_bkt(dict, index, key);
|
2024-05-14 04:20:20 +00:00
|
|
|
if (bkt == nullptr)
|
|
|
|
return false;
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
return get_value_ptr(dict, bkt);
|
2024-05-08 22:07:31 +00:00
|
|
|
}
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
void *DictionarySet(struct Dictionary *dict, u32 key, void *value_ptr)
|
2024-05-08 22:07:31 +00:00
|
|
|
{
|
|
|
|
usize index = key % dict->capacity;
|
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
void *bkt = probe_empty_bkt(dict, index, key);
|
2024-05-14 04:20:20 +00:00
|
|
|
|
2024-05-15 22:10:47 +00:00
|
|
|
if (*get_key(dict, bkt) == 0)
|
|
|
|
set_bkt(dict, bkt, key, value_ptr);
|
2024-05-08 22:07:31 +00:00
|
|
|
|
|
|
|
return bkt;
|
|
|
|
}
|