#include #include #include #include #include #include "hashtable.h" #define MAX_LINE 4096 typedef struct _Node { char* name; } Node; uint64_t word_hash_func(const void* o) { uint64_t hash_value = 0; const char* name = o; for (size_t i = 0; i < strlen(name); i++) { hash_value += name[i]; hash_value = hash_value * name[i]; } return hash_value; } void generate_random_word(char* buffer, size_t length) { for (size_t i = 0; i < length - 1; i++) { buffer[i] = 'a' + (rand() % 26); } buffer[length - 1] = 0; } void my_str_free(void* o) { printf("Freeing %p\n", o); free(o); } void my_ptr_free(void* o) { Node* node = o; //printf("Freeing %p\n", node); free(node->name); free(node); } void my_print(void* o) { Node* n = (Node *) o; printf("%s", n->name); } bool my_ptr_equal(const void* a, const void* b) { const Node* nodea = a; const Node* nodeb = b; if (nodea == NULL || nodeb == NULL) return false; if (nodea->name == NULL || nodeb->name == NULL) return false; printf("Comparing %s to %s\n", nodea->name, nodeb->name); if (strcmp(nodea->name, nodeb->name) == 0) return true; return false; } void count_good_guesses(void* key, void* value, void* userdata) { uint32_t* good_guesses = userdata; Node* node = value; (*good_guesses)++; char* s1 = node->name; printf("%u: Found: %p - %s\n", *good_guesses, key, s1); } int main(int argc, char** argv) { if (argc != 3) { printf("usage: %s \n", argv[0]); return EXIT_FAILURE; } char* filename = argv[1]; uint32_t num_guesses = atol(argv[2]); Hashtable* table = /*hash_table_create(str_hash, str_equal)*/ hash_table_create_notify(ptr_hash, my_ptr_equal, my_ptr_free); FILE* fp = fopen(filename, "r"); char* buffer = calloc(sizeof(char), MAX_LINE); uint32_t numwords = 0; uint32_t failed = 0; while (!feof(fp) && fgets(buffer, MAX_LINE, fp) != NULL) { buffer[strcspn(buffer, "\r\n")] = 0; /* char* newentry = strdup(buffer); bool result = hash_table_insert(table, newentry, newentry); if (result == false) { printf("Failed [%u] storing %s\n", ++failed, newentry); free(newentry); } else numwords++; */ Node* node = calloc(sizeof(Node*), 1); node->name = strdup(buffer); bool result = hash_table_insert(table, node, node); if (result == false) { printf("Failed [%u] storing %s\n", ++failed, node->name); free(node->name); free(node); } else numwords++; } fclose(fp); printf("Loaded %d words into the table.\n", numwords); hash_table_print(table); hash_table_set_print_func(table, my_print); hash_table_print(table); /* uint32_t good_guesses = 0; fp = fopen(filename, "r"); void* data = NULL; Node* node = calloc(sizeof(Node*), 1); while (!feof(fp) && fgets(buffer, MAX_LINE, fp) != NULL) { buffer[strcspn(buffer, "\r\n")] = 0; node->name = strdup(buffer); //printf("Buffer: %s\n", node->name); if ((data = hash_table_lookup(table, node)) != NULL) { char* s1 = ((Node*) data)->name; printf("Lookup: %s - Found: %s\n", node->name, s1); good_guesses++; } free(node->name); } free(node); fclose(fp); */ /* //hash_table_print(table); uint32_t good_guesses = 0; const int shortest_guess = 2; const int longest_guess = 15; void* data = NULL; Node* lookup = calloc(sizeof(Node*), 1); for (uint32_t i = 0; i < num_guesses; i++) { generate_random_word(buffer, shortest_guess + (rand() % (longest_guess - shortest_guess))); lookup->name = strdup(buffer); printf("Buffer: %s\n", lookup->name); if ((data = hash_table_lookup(table, lookup)) != NULL) { char* s1 = ((Node*) data)->name; printf("Lookup: %s - Found: %s\n", lookup->name, s1); good_guesses++; } free(lookup->name); } free(lookup); printf("%u out of %u guesses were in the table\n", good_guesses, num_guesses); */ free(buffer); printf("---------------------------------------\n"); List* values = hash_table_values(table); List* head = values; size_t i = 1; void* data = NULL; uint32_t good_guesses = 0; while (head != NULL) { Node* d = head->data; printf("%lu: %s\n", i++, (char *) d->name); if ((data = hash_table_lookup(table, d)) != NULL) { char* s1 = ((Node*) data)->name; printf("Lookup: %s - Found: %s\n", d->name, s1); good_guesses++; } head = head->next; } hash_table_list_free(values); printf("%u out of %u inserted words in table were in the table\n", good_guesses, numwords); /* List* keys = hash_table_keys(table); head = keys; data = NULL; good_guesses = 0; i = 1; while (head != NULL) { Node* d = head->data; printf("%lu: %p\n", i++, d->name); if ((data = hash_table_lookup(table, d)) != NULL) { char* s1 = ((Node*) data)->name; printf("Lookup: %s - Found: %s\n", d->name, s1); good_guesses++; } head = head->next; } hash_table_list_free(keys); */ good_guesses = 0; hash_table_foreach(table, count_good_guesses, &good_guesses); printf("%u out of %u inserted words in table were in the table\n", good_guesses, numwords); HashtableIter iter; void* key; void* value; hash_table_iter_init(&iter, table); while (hash_table_iter_next(&iter, &key, &value)) { char* s1 = ((Node*) value)->name; printf("Key: %p value: %s\n", key, s1); } Node* node1 = calloc(sizeof(Node*), 1); node1->name = strdup("Dummy Test Name"); if (hash_table_insert(table, node1, node1) == true) { hash_table_iter_init(&iter, table); printf("Hashtable size: %lu. Key found: %d\n", hash_table_size(table), hash_table_contains(table, node1)); void* data = hash_table_delete(table, node1); printf("Deleted: [%p] %s\n", node1, ((Node*) data)->name); free(((Node*) data)->name); free(data); printf("Hashtable size: %lu. Key found: %d\n", hash_table_size(table), hash_table_contains(table, node1)); Node* node2 = calloc(sizeof(Node*), 1); node2->name = strdup("Test Name"); hash_table_replace(table, node2, node2); printf("Hashtable size: %lu. Key found: %d\n", hash_table_size(table), hash_table_contains(table, node2)); } hash_table_destroy(table); table = hash_table_create(str_hash, str_equal); char *names[] = { "Adam", "Eva", "Abraham", "Kain", "Abel", NULL }; for (int i = 0; names[i]; i++) { void* name = names[i]; hash_table_insert(table, name, strdup(name)); } hash_table_iter_init(&iter, table); while (hash_table_iter_next(&iter, &key, &value)) { printf("Key: %p value: %s\n", (char*)key, (char*)value); } data = hash_table_delete(table, (void*) names[4]); printf("Deleted: [%p] %s\n", data, (char*) data); free(data); hash_table_replace(table, (void*) names[4], strdup(names[4])); hash_table_replace(table, (void*) names[4], strdup("Johannes")); hash_table_iter_init(&iter, table); while (hash_table_iter_next(&iter, &key, &value)) { printf("Key: %p value: %s\n", (char*)key, (char*)value); } hash_table_destroy(table); }