diff --git a/.vscode/ipch/4f1a86d870787839/b_hashtables_tests.ipch b/.vscode/ipch/4f1a86d870787839/b_hashtables_tests.ipch new file mode 100644 index 00000000..fba057e0 Binary files /dev/null and b/.vscode/ipch/4f1a86d870787839/b_hashtables_tests.ipch differ diff --git a/.vscode/ipch/4f1a86d870787839/mmap_address.bin b/.vscode/ipch/4f1a86d870787839/mmap_address.bin new file mode 100644 index 00000000..f8ee5b75 Binary files /dev/null and b/.vscode/ipch/4f1a86d870787839/mmap_address.bin differ diff --git a/.vscode/ipch/7cdf94166c9fdc35/b_hashtables.ipch b/.vscode/ipch/7cdf94166c9fdc35/b_hashtables.ipch new file mode 100644 index 00000000..60468001 Binary files /dev/null and b/.vscode/ipch/7cdf94166c9fdc35/b_hashtables.ipch differ diff --git a/.vscode/ipch/7cdf94166c9fdc35/mmap_address.bin b/.vscode/ipch/7cdf94166c9fdc35/mmap_address.bin new file mode 100644 index 00000000..f8ee5b75 Binary files /dev/null and b/.vscode/ipch/7cdf94166c9fdc35/mmap_address.bin differ diff --git a/.vscode/ipch/7e1ed2a90ff053bf/hashtables.ipch b/.vscode/ipch/7e1ed2a90ff053bf/hashtables.ipch new file mode 100644 index 00000000..5983c592 Binary files /dev/null and b/.vscode/ipch/7e1ed2a90ff053bf/hashtables.ipch differ diff --git a/.vscode/ipch/7e1ed2a90ff053bf/mmap_address.bin b/.vscode/ipch/7e1ed2a90ff053bf/mmap_address.bin new file mode 100644 index 00000000..f8ee5b75 Binary files /dev/null and b/.vscode/ipch/7e1ed2a90ff053bf/mmap_address.bin differ diff --git a/.vscode/ipch/b7a07cdc6c6307db/hashtables_tests.ipch b/.vscode/ipch/b7a07cdc6c6307db/hashtables_tests.ipch new file mode 100644 index 00000000..c04cb418 Binary files /dev/null and b/.vscode/ipch/b7a07cdc6c6307db/hashtables_tests.ipch differ diff --git a/.vscode/ipch/b7a07cdc6c6307db/mmap_address.bin b/.vscode/ipch/b7a07cdc6c6307db/mmap_address.bin new file mode 100644 index 00000000..f8ee5b75 Binary files /dev/null and b/.vscode/ipch/b7a07cdc6c6307db/mmap_address.bin differ diff --git a/Sprint questions b/Sprint questions new file mode 100644 index 00000000..75fcf672 --- /dev/null +++ b/Sprint questions @@ -0,0 +1,20 @@ +What is an Array and how does it work? + - List of elements of same type in contiguous sequence of memory + - Can access the elements in constant time O(1) using this equation: + `memory_address = starting_address + index * data_size` + + +What is a Hash Table and how does it work? + - Underlying data structure is an.... Array! + - Values are indexed by... hashing a key + - Hash will return a large unsigned (large positive number) integer `%` (modulo, or mod) the size of the underlying array which you will use as an array index + - Hashing collisions, or when 2 keys hash to the same index, are unavoidable (birthday problem) + - Handle collisions using a Linked List (key/value pairs of the same index are chained together in the same bucket) or Open Addressing (key/value pairs of the same index are placed in the next available bucket) + + +What is a computer? + - Many way to answer this. Two things to touch on are `PROCESSOR` and `MEMORY`. + - Elaborate on one of the two... possiblities: + * Turing Machines: a theoretical construct that consists of a mechanical processor + an infinite spool of read/write tape which can solve any theoretically computable problem: a trait known as being "Turing Complete" + * The von Neumann architecture, which consists of a CPU (control + arithmetic/logic units), memory, input and output. + * Billions of transistors on a chip carefully and logically arranged to interface with memory (RAM), an operating system + file system (hard drive), input (keyboard, mouse, camera, microphone, internet) and output (screen, audio, internet). \ No newline at end of file diff --git a/basic_hashtable/b_hashtables.c b/basic_hashtable/b_hashtables.c index 7b813f68..288f4a57 100644 --- a/basic_hashtable/b_hashtables.c +++ b/basic_hashtable/b_hashtables.c @@ -45,7 +45,6 @@ void destroy_pair(Pair *pair) /**** djb2 hash function - Do not modify this! ****/ unsigned int hash(char *str, int max) @@ -64,57 +63,86 @@ unsigned int hash(char *str, int max) /**** Fill this in. - All values in storage should be initialized to NULL (hint: look up `calloc`) ****/ BasicHashTable *create_hash_table(int capacity) { - BasicHashTable *ht; + BasicHashTable *ht = malloc(sizeof(BasicHashTable)); + + ht->capacity = capacity; + ht->storage = calloc(capacity, sizeof(Pair *)); return ht; } /**** Fill this in. - If you are overwriting a value with a different key, print a warning. - Don't forget to free any malloc'ed memory! ****/ void hash_table_insert(BasicHashTable *ht, char *key, char *value) { - + int index = hash(key, ht->capacity); + if (ht->storage[index]){ + printf("Warning Key overwriting!\n"); + destroy_pair(ht->storage[index]); + ht->storage[index] = NULL; } + ht->storage[index] = create_pair(key, value); } /**** Fill this in. - Don't forget to free any malloc'ed memory! ****/ void hash_table_remove(BasicHashTable *ht, char *key) { - +int index = hash(key, ht->capacity); +if (ht->storage[index]) { + destroy_pair(ht->storage[index]); + ht->storage[index] = NULL; + } else { + printf("Key not exist\n"); + } } /**** Fill this in. - Should return NULL if the key is not found. ****/ char *hash_table_retrieve(BasicHashTable *ht, char *key) { + int index = hash(key, ht->capacity); + if (ht->storage[index] != NULL) { + + if (strcmp(ht->storage[index]->key, key) == 0) { + printf("KEY IS: %s\n", ht->storage[index]->value); + return ht->storage[index]->value; + } else { + printf("Keys don't match\n"); + } + } else { + printf("Keys don't match\n"); + } return NULL; } /**** Fill this in. - Don't forget to free any malloc'ed memory! ****/ void destroy_hash_table(BasicHashTable *ht) { - +for (int i = 0; i < ht->capacity; i++) + { + if (ht->storage[i] != NULL) + { + destroy_pair(ht->storage[i]); + } + } + free(ht->storage); + free(ht); + printf("Hash table has been deleted\n"); } @@ -122,13 +150,19 @@ void destroy_hash_table(BasicHashTable *ht) int main(void) { struct BasicHashTable *ht = create_hash_table(16); + + int index = hash("line", ht->capacity); + Pair *pair = create_pair("line", "Here today...\n"); + ht->storage[index] = pair; hash_table_insert(ht, "line", "Here today...\n"); - - printf("%s", hash_table_retrieve(ht, "line")); + hash_table_insert(ht, "test", "hello\n"); + hash_table_insert(ht, "value", "world\n"); + // hash_table_insert(ht, "key-0", "val-0"); + // printf("%s\n", hash_table_retrieve(ht, "key-0")); + // printf("%s\n", hash_table_retrieve(ht, "line")); hash_table_remove(ht, "line"); - if (hash_table_retrieve(ht, "line") == NULL) { printf("...gone tomorrow. (success)\n"); } else { @@ -139,4 +173,4 @@ int main(void) return 0; } -#endif +#endif \ No newline at end of file diff --git a/full_hashtable/hashtables.c b/full_hashtable/hashtables.c index f143b37e..d67becbb 100644 --- a/full_hashtable/hashtables.c +++ b/full_hashtable/hashtables.c @@ -74,7 +74,9 @@ unsigned int hash(char *str, int max) HashTable *create_hash_table(int capacity) { HashTable *ht; - + ht = malloc(sizeof(HashTable)); + ht->capacity = capacity; + ht->storage = calloc(capacity, sizeof(LinkedPair *)); return ht; } @@ -89,7 +91,33 @@ HashTable *create_hash_table(int capacity) */ void hash_table_insert(HashTable *ht, char *key, char *value) { - +int index = hash(key, ht->capacity); +if (ht->storage[index] != NULL) { + LinkedPair *pair = ht->storage[index]; + LinkedPair *last_pair = pair; + while (pair->next != NULL) { + if (strcmp(pair->key, key) == 0) { + pair->value = value; + printf("Value for key: %s been overwritten\n", pair->key); + break; + } else { + last_pair = pair; + pair = pair->next; + } + } + if (strcmp(pair->key, key) == 0) { + pair->value = value; + printf("Value for key: %s been overwritten\n", pair->key); + } else { + LinkedPair *new_pair = create_pair(key, value); + last_pair->next = new_pair; + printf("New Pair was added to the end\n"); + } +} else { +LinkedPair *new_pair = create_pair(key, value); +ht->storage[index] = new_pair; +printf("New Pair was added to the table\n"); +} } /* @@ -102,9 +130,68 @@ void hash_table_insert(HashTable *ht, char *key, char *value) */ void hash_table_remove(HashTable *ht, char *key) { - + int index = hash(key, ht->capacity); + + if (ht->storage[index] != NULL) { + LinkedPair *current = ht->storage[index]; + // if the key is the first one + if (strcmp(current->key, key) == 0) { + ht->storage[index] = current->next; + destroy_pair(current); + } else { + // otherwise, the key is one of the other elements + while (current->next != NULL) { + // printf("Current key: %s, value: %s\n", current->key, current->value); + if (strcmp(current->next->key, key) == 0) { + LinkedPair *next = current->next; + current->next = next->next; + destroy_pair(next); + break; + } + current = current->next; + } + + } + } } + + + // int index = hash(key, ht->capacity); + // LinkedPair *current_pair = ht->storage[index]; + // LinkedPair *previous_pair = NULL; + + // while (current_pair != NULL && strcmp(current_pair->key, key) != 0) + // { + // previous_pair = current_pair; + // current_pair = current_pair->next; + // } + + // if (current_pair == NULL) + // { + + // fprintf(stderr, "Unable to remove entry with key: %s\n", key); + // } + // else + // { + + // if (previous_pair == NULL) + // { // Removing the first element in the Linked List + // ht->storage[index] = current_pair->next; + // } + // else + // { + // previous_pair->next = current_pair->next; + // } + + // destroy_pair(current_pair); + // } + // } + +// + + + /* Fill this in. @@ -115,7 +202,21 @@ void hash_table_remove(HashTable *ht, char *key) */ char *hash_table_retrieve(HashTable *ht, char *key) { - return NULL; + int index = hash(key, ht->capacity); + if (ht->storage[index] != NULL) { + LinkedPair *pair = ht->storage[index]; + while (pair->next != NULL) { + if (strcmp(pair->key, key) == 0) { + return pair->value; + } + pair = pair->next; + } + if (strcmp(pair->key, key) == 0) { + return pair->value; + } + } + printf("Unable to retrieve entry with key: %s\n", key); + return NULL; } /* @@ -125,7 +226,23 @@ char *hash_table_retrieve(HashTable *ht, char *key) */ void destroy_hash_table(HashTable *ht) { - +for (int i = 0; i < ht->capacity; i++) + { + if (ht->storage[i] != NULL) + { + LinkedPair *pair = ht->storage[i]; + LinkedPair *temp_pair; + while (pair->next != NULL) { + temp_pair = pair; + pair = pair->next; + destroy_pair(temp_pair); + } + destroy_pair(pair); + } + } + free(ht->storage); + free(ht); + printf("Hash table has been deleted\n"); } /* @@ -139,7 +256,16 @@ void destroy_hash_table(HashTable *ht) HashTable *hash_table_resize(HashTable *ht) { HashTable *new_ht; - + new_ht = create_hash_table(2 * ht->capacity); + LinkedPair *current_pair; + for (int i = 0; i < ht->capacity; i++) { + current_pair = ht->storage[i]; + while (current_pair != NULL) { + hash_table_insert(new_ht, current_pair->key, current_pair->value); + current_pair = current_pair->next; + } + } + destroy_hash_table(ht); return new_ht; } @@ -147,21 +273,46 @@ HashTable *hash_table_resize(HashTable *ht) #ifndef TESTING int main(void) { - struct HashTable *ht = create_hash_table(2); - - hash_table_insert(ht, "line_1", "Tiny hash table\n"); - hash_table_insert(ht, "line_2", "Filled beyond capacity\n"); - hash_table_insert(ht, "line_3", "Linked list saves the day!\n"); - - printf("%s", hash_table_retrieve(ht, "line_1")); - printf("%s", hash_table_retrieve(ht, "line_2")); - printf("%s", hash_table_retrieve(ht, "line_3")); - - int old_capacity = ht->capacity; - ht = hash_table_resize(ht); - int new_capacity = ht->capacity; - - printf("\nResizing hash table from %d to %d.\n", old_capacity, new_capacity); + // struct HashTable *ht = create_hash_table(2); + + // hash_table_insert(ht, "line_1", "Tiny hash table\n"); + // hash_table_insert(ht, "line_2", "Filled beyond capacity\n"); + // hash_table_insert(ht, "line_3", "Linked list saves the day!\n"); + + // printf("%s", hash_table_retrieve(ht, "line_1")); + // printf("%s", hash_table_retrieve(ht, "line_2")); + // printf("%s", hash_table_retrieve(ht, "line_3")); + + // int old_capacity = ht->capacity; + // ht = hash_table_resize(ht); + // int new_capacity = ht->capacity; + + // printf("\nResizing hash table from %d to %d.\n", old_capacity, new_capacity); + + + struct HashTable *ht = create_hash_table(8); + + hash_table_insert(ht, "key-0", "val-0"); + hash_table_insert(ht, "key-1", "val-1"); + hash_table_insert(ht, "key-2", "val-2"); + hash_table_insert(ht, "key-3", "val-3"); + hash_table_insert(ht, "key-4", "val-4"); + hash_table_insert(ht, "key-5", "val-5"); + hash_table_insert(ht, "key-6", "val-6"); + hash_table_insert(ht, "key-7", "val-7"); + hash_table_insert(ht, "key-8", "val-8"); + hash_table_insert(ht, "key-9", "val-9"); + + hash_table_remove(ht, "key-9"); + hash_table_remove(ht, "key-8"); + hash_table_remove(ht, "key-7"); + hash_table_remove(ht, "key-6"); + hash_table_remove(ht, "key-5"); + hash_table_remove(ht, "key-4"); + hash_table_remove(ht, "key-3"); + hash_table_remove(ht, "key-2"); + hash_table_remove(ht, "key-1"); + hash_table_remove(ht, "key-0"); destroy_hash_table(ht);