#include #include #include #include #include "test.h" struct test_hashmap { size_t off; char *key; }; struct test_hashmap *new_test_hashmap_value(size_t offset, const char *key) { struct test_hashmap *p; p = safe_malloc(sizeof(struct test_hashmap)); p->off = offset; p->key = safe_strdup(key); return p; } void free_test_hashmap_value(const char *key, void *val) { struct test_hashmap *p = val; ARG_UNUSED(key); safe_free(p->key); safe_free(p); } #define SEP "\n\r \t" int test_dict_insert(hash_map_t *map, const char * const *words, size_t count) { size_t ndx = 0; struct test_hashmap *p; while (ndx < count) { p = new_test_hashmap_value(ndx, words[ndx]); hash_map_insert(map, words[ndx], p); ndx++; } mod_printf("Inserted %zu items", ndx); return 0; } int test_dict_iterator(hash_map_t *map, const char * const *words, size_t count) { size_t ndx = 0, mismatch = 0; struct test_hashmap *val; char *key; HASH_MAP_FOREACH(map, &key, &val) { if (strcmp(val->key, words[val->off])) { mismatch += 1; mod_printf("Err: word mismatch '%s/%s' off: %zu", words[ndx], val->key, val->off); } ndx++; } if (ndx != count || mismatch) return -1; mod_printf("Iterated over %zu items", ndx); return 0; } int test_dict_delete(hash_map_t *map, const char * const *words, size_t count) { size_t ndx = 0, not_found = 0; struct test_hashmap *p; while (ndx < count) { p = hash_map_delete(map, words[ndx], 0); if (p == NULL) { not_found += 1; mod_printf("word '%s' not found", words[ndx]); } else { if (p->off != ndx || strcmp(p->key, words[ndx])) { not_found += 1; mod_printf("Err: word '%s/%s' off: %zu", words[ndx], p->key, ndx); } free_test_hashmap_value(NULL, p); } ndx++; } mod_printf("Deleted %zu items", ndx); return not_found * -1; } size_t test_build_word_list(char *buf, const char *const **word_list) { size_t count, ndx = 0; char *word, *state, **words; count = str_sep_count(buf, "\n\r \t"); words = safe_malloc(sizeof(char *) * count); word = strtok_r(buf, SEP, &state); while (ndx < count && word != NULL) { words[ndx] = word; word = strtok_r(NULL, SEP, &state); ndx += 1; } *word_list = (const char *const *)words; return count; } TEST_DEF(hashmap) { char *buf; const char * const *words; size_t size, count; hash_map_t map; TEST_MOD_INIT(); TEST_MOD_READ_FILE("words_alpha.txt", &buf, &size); count = test_build_word_list(buf, &words); hash_map_init(&map); TEST_MOD_EXEC( test_dict_insert(&map, words, count) ); TEST_MOD_EXEC( test_dict_iterator(&map, words, count) ); TEST_MOD_EXEC( test_dict_delete(&map, words, count) ); TEST_MOD_EXEC( map.count ); TEST_MOD_EXEC( test_dict_insert(&map, words, count) ); hash_map_free(&map, free_test_hashmap_value); safe_free(buf); safe_free((void *)words); TEST_MOD_REPORT(); }