Created
April 25, 2020 14:57
-
-
Save bnm3k/4676a267e5dfce65732d0b98c9592a2c to your computer and use it in GitHub Desktop.
A quick demonstration on using khash to store string values allocated on the heap, and eventually freeing them after use
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "khash.h" | |
#include <stdbool.h> | |
#include <stdio.h> | |
void gen_rand_string(char *buf, size_t buf_len, bool should_randomize_str_len) { | |
static char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | |
size_t str_len = buf_len - 1; | |
if (should_randomize_str_len) | |
str_len = (rand() % str_len) + 1; | |
for (size_t i = 0; i < str_len; i++) { | |
int key = rand() % (int)(sizeof(charset) - 1); | |
buf[i] = charset[key]; | |
} | |
buf[str_len] = '\0'; | |
} | |
KHASH_MAP_INIT_STR(str_to_str, char *) | |
int main() { | |
const size_t key_buf_len = 4; //max_key_len = key_buf_len - 1 | |
const size_t val_buf_len = 31; //max_val_len = val_buf_len - 1 | |
const bool should_randomize_key_len = false; | |
const bool should_randomize_val_len = true; | |
const unsigned max_items_to_insert = 10000; | |
khash_t(str_to_str) *foo_hash_table = kh_init(str_to_str); | |
unsigned items_inserted = 0; | |
for (unsigned i = 0; i < max_items_to_insert; i++) { | |
int absent; | |
char *key_buf = calloc(key_buf_len, sizeof(char)); | |
char *val_buf = calloc(val_buf_len, sizeof(char)); | |
/* gen key & val */ | |
gen_rand_string(key_buf, key_buf_len, should_randomize_key_len); | |
gen_rand_string(val_buf, val_buf_len, should_randomize_val_len); | |
/* insert key */ | |
khiter_t new_item_it = kh_put(str_to_str, foo_hash_table, key_buf, &absent); | |
/* | |
* insert val | |
* if key already present, kh_put places 0 into ret var | |
* if key not present, kh_put places a non-zero value into ret var | |
*/ | |
if (absent) { | |
kh_key(foo_hash_table, new_item_it) = key_buf; | |
kh_val(foo_hash_table, new_item_it) = val_buf; | |
items_inserted++; | |
} else { | |
free(key_buf); | |
free(val_buf); | |
} | |
} | |
printf("%d insertion attempts; %d duplicates; %d keys\n\n", max_items_to_insert, max_items_to_insert - items_inserted, items_inserted); | |
/* iterate over items method 1, print 5 items only */ | |
const char *k, *v; | |
int i = 5; | |
kh_foreach(foo_hash_table, k, v, { | |
fprintf(stdout, "%s -> %s\n", k, v); | |
if (--i < 0) break; | |
}); | |
/* free items then free table */ | |
/* also, iterate over items method 2 */ | |
for (khiter_t it = kh_begin(foo_hash_table); it != kh_end(foo_hash_table); ++it) { | |
if (kh_exist(foo_hash_table, it)) { | |
free((void *)kh_key(foo_hash_table, it)); | |
free((void *)kh_val(foo_hash_table, it)); | |
} | |
} | |
kh_destroy(str_to_str, foo_hash_table); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment