diff options
Diffstat (limited to 'src/gehashmap.h')
-rw-r--r-- | src/gehashmap.h | 139 |
1 files changed, 64 insertions, 75 deletions
diff --git a/src/gehashmap.h b/src/gehashmap.h index 17dfdbc..c5d2cf2 100644 --- a/src/gehashmap.h +++ b/src/gehashmap.h @@ -19,13 +19,9 @@ * This macro is unsafe to use when modifying the hashmap inplace (i.e. when * calling n##_remove() in the loop). */ -#define GEHASHMAP_FOREACH(entry, map) \ - for (size_t _gehashmap_i = 0; \ - _gehashmap_i < (map)->capacity; \ - _gehashmap_i++) \ - for ((entry) = (map)->entries[_gehashmap_i]; \ - (entry) != NULL; \ - (entry) = (entry)->next) +#define GEHASHMAP_FOREACH(e, m) \ + for (size_t __ge_i = 0; __ge_i < (m).__cap; __ge_i++) \ + for ((e) = (m).__ents[__ge_i]; (e) != NULL; (e) = (e)->next) /* The GEHASHMAP_FOREACH_SAFE() macro is identical to the GEHASHMAP_FOREACH() * macro except it takes an additional “tmp” argument. This argument is of the @@ -33,15 +29,11 @@ * with by the library user. This macro allows you to modify the hashmap * inplace while iterating. */ -#define GEHASHMAP_FOREACH_SAFE(entry, tmp, map) \ - for (size_t _gehashmap_i = 0; \ - _gehashmap_i < (map)->capacity; \ - _gehashmap_i++) \ - for ((entry) = (map)->entries[_gehashmap_i], \ - (tmp) = (entry) ? (entry)->next : NULL; \ - (entry) != NULL; \ - (entry) = (tmp), \ - (tmp) = (entry) ? (entry)->next : NULL) +#define GEHASHMAP_FOREACH_SAFE(e, t, m) \ + for (size_t __ge_i = 0; __ge_i < (m).__cap; __ge_i++) \ + for ((e) = (m).__ents[__ge_i], (t) = (e) ? (e)->next : NULL; \ + (e) != NULL; \ + (e) = (t), (t) = (e) ? (e)->next : NULL) #define GEHASHMAP_DEF(k, v, n) \ GEHASHMAP_DEF_API(k, v, n) \ @@ -57,9 +49,9 @@ }; \ \ typedef struct { \ - size_t size, \ - capacity; \ - struct n_e **entries; \ + size_t __size, \ + __cap; \ + struct n_e **__ents; \ } n_t; \ \ void n##_free(n_t *); \ @@ -83,22 +75,22 @@ n##_new(n_t *map) \ { \ *map = (n_t) { \ - .size = 0, \ - .capacity = GEHASHMAP_INITIAL_SIZE, \ - .entries = calloc(GEHASHMAP_INITIAL_SIZE, \ - sizeof(struct n_e *)) \ + .__size = 0, \ + .__cap = GEHASHMAP_INITIAL_SIZE, \ + .__ents = calloc(GEHASHMAP_INITIAL_SIZE, \ + sizeof(struct n_e *)) \ }; \ - return map->entries == NULL ? -1 : 0; \ + return map->__ents == NULL ? -1 : 0; \ } \ \ /* Function to destroy a hashmap */ \ void \ n##_free(n_t *map) \ { \ - struct n_e *entry, *tmp; \ - GEHASHMAP_FOREACH_SAFE(entry, tmp, map) \ - free(entry); \ - free(map->entries); \ + struct n_e *ent, *tmp; \ + GEHASHMAP_FOREACH_SAFE(ent, tmp, *map) \ + free(ent); \ + free(map->__ents); \ } \ \ /* Function to resize a hashmap. This function should not really be @@ -106,28 +98,26 @@ * otherwise 0 is returned. */ \ int \ - n##_resize(n_t *map, size_t new_capacity) \ + n##_resize(n_t *map, size_t ncap) \ { \ - struct n_e **new_entries = \ - calloc(new_capacity, sizeof(struct n_e *)); \ - if (new_entries == NULL) \ + struct n_e **nents = calloc(ncap, sizeof(struct n_e *)); \ + if (nents == NULL) \ return -1; \ \ - for (size_t i = 0; i < map->capacity; i++) { \ - struct n_e *entry = map->entries[i]; \ - while (entry != NULL) { \ - struct n_e *next = entry->next; \ - size_t hash = n##_key_hash(entry->key) \ - % new_capacity; \ - entry->next = new_entries[hash]; \ - new_entries[hash] = entry; \ - entry = next; \ + for (size_t i = 0; i < map->__cap; i++) { \ + struct n_e *ent = map->__ents[i]; \ + while (ent != NULL) { \ + struct n_e *next = ent->next; \ + size_t hash = n##_key_hash(ent->key) % ncap; \ + ent->next = nents[hash]; \ + nents[hash] = ent; \ + ent = next; \ } \ } \ \ - free(map->entries); \ - map->entries = new_entries; \ - map->capacity = new_capacity; \ + free(map->__ents); \ + map->__ents = nents; \ + map->__cap = ncap; \ \ return 0; \ } \ @@ -141,30 +131,29 @@ n##_set(n_t *map, k key, v val) \ { \ size_t hash; \ - struct n_e *entry; \ + struct n_e *ent; \ \ - if (map->size + 1 > map->capacity * GEHASHMAP_LOAD_FACTOR) { \ - if (n##_resize(map, map->capacity * 2) == -1) \ + if (map->__size + 1 > map->__cap * GEHASHMAP_LOAD_FACTOR) { \ + if (n##_resize(map, map->__cap * 2) == -1) \ return -1; \ } \ \ - hash = n##_key_hash(key) % map->capacity; \ - entry = map->entries[hash]; \ - for (; entry != NULL; entry = entry->next) { \ - if (n##_key_iseq(entry->key, key)) { \ - entry->val = val; \ + hash = n##_key_hash(key) % map->__cap; \ + for (ent = map->__ents[hash]; ent != NULL; ent = ent->next) { \ + if (n##_key_iseq(ent->key, key)) { \ + ent->val = val; \ return 0; \ } \ } \ \ - if ((entry = malloc(sizeof(struct n_e))) == NULL) \ + if ((ent = malloc(sizeof(struct n_e))) == NULL) \ return -1; \ \ - entry->key = key; \ - entry->val = val; \ - entry->next = map->entries[hash]; \ - map->entries[hash] = entry; \ - map->size++; \ + ent->key = key; \ + ent->val = val; \ + ent->next = map->__ents[hash]; \ + map->__ents[hash] = ent; \ + map->__size++; \ \ return 0; \ } \ @@ -177,13 +166,13 @@ bool \ n##_get(n_t *map, k key, v *val) \ { \ - size_t hash = n##_key_hash(key) % map->capacity; \ - struct n_e *entry = map->entries[hash]; \ + struct n_e *ent; \ + size_t hash = n##_key_hash(key) % map->__cap; \ \ - for (; entry != NULL; entry = entry->next) { \ - if (n##_key_iseq(entry->key, key)) { \ + for (ent = map->__ents[hash]; ent != NULL; ent = ent->next) { \ + if (n##_key_iseq(ent->key, key)) { \ if (val != NULL) \ - *val = entry->val; \ + *val = ent->val; \ return true; \ } \ } \ @@ -208,25 +197,25 @@ int \ n##_remove(n_t *map, k key) \ { \ - size_t hash = n##_key_hash(key) % map->capacity; \ - struct n_e *entry; \ + struct n_e *ent; \ + size_t hash = n##_key_hash(key) % map->__cap; \ \ - if ((entry = map->entries[hash]) == NULL) \ + if ((ent = map->__ents[hash]) == NULL) \ return -1; \ \ - if (n##_key_iseq(entry->key, key)) { \ - map->entries[hash] = entry->next; \ - free(entry); \ - map->size--; \ + if (n##_key_iseq(ent->key, key)) { \ + map->__ents[hash] = ent->next; \ + free(ent); \ + map->__size--; \ return 0; \ } \ \ - for (; entry->next != NULL; entry = entry->next) { \ - if (n##_key_iseq(entry->next->key, key)) { \ - struct n_e *next = entry->next; \ - entry->next = next->next; \ + for (; ent->next != NULL; ent = ent->next) { \ + if (n##_key_iseq(ent->next->key, key)) { \ + struct n_e *next = ent->next; \ + ent->next = next->next; \ free(next); \ - map->size--; \ + map->__size--; \ return 0; \ } \ } \ |