#ifndef MAP_H #define MAP_H #include #include #ifndef MAP_MAX_SIZE #define MAP_MAX_SIZE 5000 #endif /* MAP_MAX_SIZE */ struct map_item { void *data; size_t size; const uint64_t hkey; struct map_item *hit; }; struct map { /* uint64_t *hkeys; */ struct map_item *items; size_t size; }; struct map* map_create(); __attribute__((access (read_write, 1), access (read_only, 2), access (read_only, 3), nonnull)) void map_add(struct map *__restrict__ map, const char *__restrict__ key, void *__restrict__ data, size_t size); __attribute__((access (read_write, 1), access (read_only, 3), nonnull)) void map_add_h(struct map *__restrict__ map, uint64_t hkey, void *__restrict__ data, size_t size); __attribute__((access (read_only, 1), access (read_only, 2), nonnull)) void* map_get(struct map const *__restrict__ map, const char *__restrict__ key); __attribute__((access (read_only, 1), nonnull)) void* map_get_h(struct map const *__restrict__ map, uint64_t hkey); __attribute__((access (read_only, 1), access (read_only, 2), nonnull)) struct map_item* map_get_item(struct map const *__restrict__ map, const char *__restrict__ key); __attribute__((access (read_only, 1), nonnull)) struct map_item* map_get_item_h(struct map const *__restrict__ map, uint64_t hkey); __attribute__((access (read_write, 1), nonnull)) void map_destroy(struct map *map); #define MAP_IMP #if defined(MAP_IMP) || defined(IMPLEMENTATIONS) #define HASH_IMP #include "./hash.h" #undef HASH_IMP #include #include #include struct map* map_create() { /* NOTE: Should probraly do something more here */ struct map *ret = calloc(1, sizeof(struct map)); if ( ret == NULL ) { fprintf(stderr, "[ERROR] Failed to calloc: map_create\n"); exit(EXIT_FAILURE); } ret->items = calloc(MAP_MAX_SIZE, sizeof(struct map_item)); if ( ret->items == NULL ) { fprintf(stderr, "[ERROR] Failed to calloc: map_create\n"); exit(EXIT_FAILURE); } return ret; } void map_add(struct map *__restrict__ map, const char *__restrict__ key, void *__restrict__ data, size_t size) { map_add_h(map, hash(key, strlen(key)), data, size); } void map_add_h(struct map *__restrict__ map, uint64_t hkey, void *__restrict__ data, size_t size) { struct map_item *pitem = &map->items[hkey % MAP_MAX_SIZE]; while ( pitem->data != NULL ) { if ( pitem->hit == NULL ) { pitem->hit = calloc(1, sizeof(struct map_item)); if ( pitem->hit == NULL ) { fprintf(stderr, "[ERROR] Failed to calloc: map_add\n"); exit(EXIT_FAILURE); } } pitem = pitem->hit; } pitem->data = calloc(1, size); if ( pitem->data == NULL ) { fprintf(stderr, "[ERROR] Failed to calloc: map_add\n"); exit(EXIT_FAILURE); } pitem->size = size; memcpy(pitem->data, data, size); /* const kkkkkk */ *(uint64_t*) &pitem->hkey = hkey; } void* map_get(struct map const *__restrict__ map, const char *__restrict__ key) { return map_get_h(map, hash(key, strlen(key))); } void* map_get_h(struct map const *__restrict__ map, uint64_t hkey) { struct map_item *pitem = map_get_item_h(map, hkey); if ( pitem == NULL ) { return NULL; } return pitem->data; } struct map_item* map_get_item(struct map const *__restrict__ map, const char *__restrict__ key) { return map_get_item_h(map, hash(key, strlen(key))); } struct map_item* map_get_item_h(struct map const *__restrict__ map, uint64_t hkey) { struct map_item *pitem = &map->items[hkey % MAP_MAX_SIZE]; while ( pitem->hkey != hkey) { if ( pitem->hit == NULL ) { return NULL; } pitem = pitem->hit; } return pitem; } void map_destroy(struct map *map) { (void) map; } #endif /* MAP_IMP || IMPLEMENTATIONS */ #endif /* MAP_H */