summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/gehashmap.c6
-rw-r--r--src/gehashmap.h139
2 files changed, 67 insertions, 78 deletions
diff --git a/examples/gehashmap.c b/examples/gehashmap.c
index 17f8eb4..d84f363 100644
--- a/examples/gehashmap.c
+++ b/examples/gehashmap.c
@@ -68,9 +68,9 @@ main(void)
atoimap_get(map_a, "THOMAS VOẞ", &i); printf("THOMAS VOẞ -> %d\n", i);
atoimap_get(map_a, "Thomas Voss", &i); printf("Thomas Voss -> %d\n", i);
- GEHASHMAP_FOREACH_SAFE(entry, tmp, map_a)
+ GEHASHMAP_FOREACH_SAFE(entry, tmp, *map_a)
atoimap_remove(map_a, entry->key);
- GEHASHMAP_FOREACH(entry, map_a)
+ GEHASHMAP_FOREACH(entry, *map_a)
puts(entry->key);
itoumap_set(map_b, -42, +42);
@@ -101,7 +101,7 @@ main(void)
atoimap_set(map_a, strdup("THOMAS VOẞ"), 6);
atoimap_set(map_a, strdup("Thomas Voss"), 7);
- GEHASHMAP_FOREACH(entry, map_a)
+ GEHASHMAP_FOREACH(entry, *map_a)
free(entry->key);
atoimap_free(map_a);
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; \
} \
} \