skipstone/src/map.c

81 lines
1.6 KiB
C

#include <stdlib.h>
#include <string.h>
#include <skipstone/map.h>
skipstone_map *skipstone_map_new() {
skipstone_map *map;
if ((map = malloc(SKIPSTONE_MAP_SLOTS * sizeof(*map))) == NULL) {
goto error_malloc_map;
}
memset(map, 0, SKIPSTONE_MAP_SLOTS * sizeof(*map));
return map;
error_malloc_map:
return NULL;
}
static void _destroy(skipstone_map *map, void (*destructor)(void *), int depth) {
uint16_t i;
for (i=0; i<SKIPSTONE_MAP_SLOTS; i++) {
if (map[i].next) {
if (destructor && depth == SKIPSTONE_MAP_DEPTH) {
destructor(map[i].value);
} else {
_destroy(map[i].next, destructor, depth + 1);
}
}
}
free(map);
}
void skipstone_map_destroy(skipstone_map *map, void (*destructor)(void *)) {
_destroy(map, destructor, 0);
}
void *skipstone_map_get(skipstone_map *map, uint16_t index) {
uint16_t i;
for (i=0; i<SKIPSTONE_MAP_DEPTH; i++) {
map = map[index & 0xf].next;
if (map == NULL) {
return NULL;
}
index >>= 4;
}
return map[index & 0x0f].value;
}
int skipstone_map_set(skipstone_map *map, uint16_t index, void *value) {
uint16_t i;
for (i=0; i<SKIPSTONE_MAP_DEPTH; i++) {
skipstone_map *next = map[index & 0xf].next;
if (next == NULL) {
if ((next = skipstone_map_new()) == NULL) {
goto error_new;
}
}
map[index & 0xf].next = next;
map = next;
index >>= 4;
}
map[index & 0x0f].value = value;
return 0;
error_new:
return -1;
}