#include #include "uthash.h" #include struct groupinfo { uint32_t id; /* use this field as key (name has to be "id" */ /* new_marker_value = markervalue_start + (ip - nw_addr) / group_size */ uint32_t nw_addr; uint32_t group_size; uint32_t markervalue_start; UT_hash_handle hh; /* makes this structure hashable */ }; struct groupinfo *group_hashtable = NULL; void add_group(struct groupinfo *g) { struct groupinfo *g_find; HASH_FIND_INT(group_hashtable, &g->id, g_find); /* id already in the hash? */ if (g_find == NULL) { HASH_ADD_INT( group_hashtable, id, g ); } else { printf("id already in hashtable, not adding: %d", g->id); } } /* INFO: It is ok to have concurrent readers on hashtable since uthash 1.5 */ struct groupinfo *find_group(int ip_prefix) { struct groupinfo *s; HASH_FIND_INT( group_hashtable, &ip_prefix, s ); return s; } void delete_group(struct groupinfo *g) { HASH_DEL( group_hashtable, g); } void read_groups(char *filename, uint32_t markervalue_bits) { char line[1000]; /* file format: ip\tmarkervalue\tsubnets */ FILE *ip_file = fopen(filename, "r"); while (fgets(line, 1000, ip_file) != NULL) { if (!ip_file) { perror("Error while opening the group file.\n"); exit(EXIT_FAILURE); } /* split by tabs */ char* token = strtok(line, "\t"); //printf("%s\n", token); struct in_addr addr; if (!inet_aton(token, &addr)) { printf("could not parse ip: %s\n", token); } uint32_t ip_int_ho = (uint32_t)ntohl(addr.s_addr); // remove trailing checksum bits // 0xAAAAAABB -> 0x00AAAAAA //ip_int_ho >>= (32 - markervalue_bits); //printf("ip: %u\n", ip_int_ho); token = strtok(NULL, "\t"); //printf("%s\n", token); uint32_t markervalue = atoi(token); //printf("markervlue: %d\n", markervalue); token = strtok(NULL, "\t"); //printf("%s\n", token); uint32_t subnets = atoi(token); //printf("subnets: %d\n", subnets); //printf("------\n"); struct groupinfo *newentry; newentry = malloc(sizeof(struct groupinfo)); newentry->id = ip_int_ho; add_group(newentry); } fclose(ip_file); unsigned int groups_total; groups_total = HASH_COUNT(group_hashtable); printf("there are %u groups\n", groups_total); } int main() { read_groups("./groupfile_test3.csv", 24); } int main_() { int i = 0; for (; i < 500000; ++i) { struct groupinfo *newentry; newentry = malloc(sizeof(struct groupinfo)); newentry->id = i; add_group(newentry); } unsigned int groups_total; groups_total = HASH_COUNT(group_hashtable); printf("there are %u groups\n", groups_total); struct groupinfo *g = find_group(1234); printf("value: %d\n", g->id); sleep(99999); }