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; | ||
|  | } |