blob: bbb4aa726b7e2ff928cd9fe3e13a8c96be42f290 [file] [log] [blame]
#include "map.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifdef MAP_DEBUG
#define MAP_DEBUG_PRINTF printf
#else
#define MAP_DEBUG_PRINTF // nothing
#endif
map_t *new_map_sized(uint64_t size)
{
map_t *m = malloc(sizeof(map_t));
/*
* Calloc zeroes the memory, which is what we want.
*/
map_node empty = EMPTY_NODE;
m->items = calloc(size, sizeof(map_node));
m->len = MAP_ALLOC_SIZE;
m->full = 0;
for (int i = 0; i < m->len; i++)
{
m->items[i] = empty;
}
return m;
}
map_t *new_map()
{
return new_map_sized(MAP_ALLOC_SIZE);
}
void free_map(map_t *m)
{
free(m->items);
free(m);
}
void free_map_items(map_t *m)
{
for (int i = 0; i < m->len; i++)
{
if (m->items[i].key != NULL)
{
free(m->items[i].key);
free(m->items[i].val);
}
}
free(m->items);
free(m);
}
void map_set(map_t *m, char *k, void *v)
{
uint64_t h = hash(k);
uint32_t i = h % m->len;
MAP_DEBUG_PRINTF("hash %u i %u\n", h, i);
m->count++;
if (m->full++ < m->len)
{
map_node val =
{
malloc(strlen(k) + 1),
v,
1,
h,
};
strcpy(val.key, k);
uint32_t current = i;
while (MAP_USED_AT(m->items, current))
{
if (current == m->len - 1)
{
current = 0;
}
else
{
current++;
}
}
MAP_DEBUG_PRINTF("Current %d\n", current);
m->items[current] = val;
MAP_DEBUG_PRINTF("val %d\n", *(int *) m->items[current].val);
}
else
{
/* resize map */
map_t *n_m = new_map_sized(m->len * 2);
for (uint64_t j = 0; j < m->len; j++)
{
if (!MAP_USED_AT(m->items, j))
{
continue;
}
uint32_t current = m->items[j].h;
while (MAP_USED_AT(m->items, current))
{
if (current == m->len - 1)
{
current = 0;
}
else
{
current++;
}
}
n_m->items[current] = m->items[j];
}
free_map(m);
m = n_m;
}
}
int map_exists(map_t *m, char *k)
{
uint64_t h = hash(k);
uint32_t i = h % m->len;
uint32_t current = i;
while (m->items[current].used)
{
if (strcmp(m->items[current].key, k) == 0)
{
return 1;
}
if (current >= m->len - 1)
{
current = 0;
MAP_DEBUG_PRINTF("Current reset to 0\n");
}
else
{
current++;
MAP_DEBUG_PRINTF("Incrementing current\n");
}
}
return 0;
}
void *map_get(map_t *m, char *k)
{
uint64_t h = hash(k);
uint32_t i = h % m->len;
uint32_t current = i;
MAP_DEBUG_PRINTF("%s should be %s\n", m->items[current].key, k);
MAP_DEBUG_PRINTF("streq %d\n", strcmp(m->items[current].key, k));
MAP_DEBUG_PRINTF("Current get %d\n", current);
while (strcmp(m->items[current].key, k) != 0)
{
MAP_DEBUG_PRINTF("While at %d\n", current);
if (current >= m->len - 1)
{
current = 0;
MAP_DEBUG_PRINTF("Current reset to 0\n");
}
else
{
current++;
MAP_DEBUG_PRINTF("Incrementing current\n");
}
}
MAP_DEBUG_PRINTF("val %d\n", *(int *) m->items[current].val);
return m->items[current].val;
//return 1;
}
void map_debug(map_t *m)
{
for (int i = 0; i < m->len; i++)
{
if (m->items[i].val != NULL)
{
MAP_DEBUG_PRINTF("i = %d, k = %s, v = %d\n",
i, m->items[i].key, *(int *) m->items[i].val);
}
}
}