81 lines
1.6 KiB
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;
|
|
}
|