80 lines
1.5 KiB
C
80 lines
1.5 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, int depth) {
|
||
|
uint16_t i;
|
||
|
|
||
|
if (depth > SKIPSTONE_MAP_DEPTH) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (i=0; i<SKIPSTONE_MAP_SLOTS; i++) {
|
||
|
if (map[i].next) {
|
||
|
_destroy(map[i].next, depth + 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
free(map);
|
||
|
}
|
||
|
|
||
|
void skipstone_map_destroy(skipstone_map *map) {
|
||
|
_destroy(map, 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;
|
||
|
}
|
||
|
|
||
|
void *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;
|
||
|
}
|
||
|
|
||
|
return map[index & 0x0f].value = value;
|
||
|
|
||
|
error_new:
|
||
|
return NULL;
|
||
|
}
|