Created
November 2, 2010 18:55
-
-
Save tomas-stefano/660103 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| /* Hash Tables Implementation. | |
| * | |
| * This file implements in memory hash tables with insert/del/replace/find/ | |
| * get-random-element operations. Hash tables will auto resize if needed | |
| * tables of power of two in size are used, collisions are handled by | |
| * chaining. See the source code for more information... :) | |
| * | |
| */ | |
| #include <stdlib.h> | |
| #include "hash.h" | |
| /* | |
| Return a pointer to the Hash structure | |
| PENDING: Verify if pointer is NULL | |
| */ | |
| Hash *hash_new() { | |
| Hash *hash = (Hash *) malloc(sizeof(Hash)); | |
| hash->hash_table.used = 0; | |
| return hash; | |
| } | |
| /* | |
| Add a element to the Hash sending the Hash pointer and the key/value | |
| */ | |
| int hash_add_element(Hash *hash, void *key, void *value) { | |
| HashEntry *hash_entry = (HashEntry *) malloc(sizeof(HashEntry)); | |
| HashTable *hash_table; | |
| hash_table = &(hash->hash_table); // Assign the address of hash->hash_table in hash_table pointer | |
| hash_entry->next = hash_table->table; // Point next element where table apponts to | |
| hash_table->used++; // Used one more key/value | |
| hash_entry->key = key; // Stores the key | |
| return 0; | |
| } |
This file contains hidden or 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
| #ifndef __HASH_H | |
| #define __HASH_H | |
| /* | |
| HashEntry is a structure that contains the key and the value for the actual | |
| new element, and also contains a pointer to the next HashEntry | |
| */ | |
| typedef struct hash_entry { | |
| void *key; | |
| void *value; | |
| struct HashEntry *next; | |
| } HashEntry; | |
| /* | |
| HashTable is a structure that contains the pointer to pointer of the HashEntry | |
| Every Hash has one HashTable | |
| */ | |
| typedef struct hash_table { | |
| HashEntry **table; // Array of Hash Entries | |
| unsigned long used; | |
| } HashTable; | |
| typedef struct hash { | |
| HashTable hash_table; | |
| } Hash; | |
| /* | |
| Return the size of the Hash | |
| The size of the Hash is deterministic in the used field of HashTable Structure | |
| */ | |
| #define hash_size(hash) (hash->hash_table.used) | |
| /* | |
| Hash API | |
| */ | |
| Hash *hash_new(); | |
| int hash_add_element(Hash *hash, void *key, void *value); | |
| #endif |
This file contains hidden or 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 <cgreen/cgreen.h> | |
| #include "hash.h" | |
| static void *key; | |
| static void *value; | |
| /* | |
| Should return zero when hash is empty | |
| */ | |
| void should_return_zero_if_hash_is_empty() { | |
| Hash *hash = hash_new(); | |
| assert_equal(hash_size(hash), 0); | |
| } | |
| /* | |
| Assign one element to the Hash and the size should be equal 1 | |
| */ | |
| void should_return_one_if_hash_has_one_element() { | |
| Hash *hash = hash_new(); | |
| hash_add_element(hash, key, value); | |
| assert_equal(hash_size(hash), 1); | |
| } | |
| /* | |
| Assign two elements to the Hash and the size should be equal 2 | |
| */ | |
| void should_return_two_if_hash_has_two_elements() { | |
| Hash *hash = hash_new(); | |
| hash_add_element(hash, key, value); | |
| hash_add_element(hash, key, value); | |
| assert_equal(hash_size(hash), 2); | |
| } | |
| /* | |
| Return Zero when no error occurs when it try to add element to the Hash | |
| */ | |
| void should_return_ok_when_add_element_to_the_hash() { | |
| Hash *hash_ok; | |
| hash_ok = hash_new(); | |
| int status = hash_add_element(hash_ok, key, value); | |
| assert_equal(status, 0); | |
| } | |
| /* | |
| Should assign the key properly | |
| */ | |
| void should_add_the_key_of_the_hash() { | |
| Hash *hash; | |
| hash = hash_new(); | |
| hash_add_element(hash, key, value); | |
| assert_equal((hash)->hash_table.table[0]->key, key); // FAILURE! | |
| } | |
| TestSuite *hash_tests() { | |
| TestSuite *suite = create_test_suite(); | |
| add_test(suite, should_return_zero_if_hash_is_empty); | |
| add_test(suite, should_return_one_if_hash_has_one_element); | |
| add_test(suite, should_return_two_if_hash_has_two_elements); | |
| add_test(suite, should_return_ok_when_add_element_to_the_hash); | |
| add_test(suite, should_add_the_key_of_the_hash); | |
| return suite; | |
| } |
Author
try hash->(*hash_table).key
Author
After debugging with gdb in function:
hash_add_element()
(gdb) p hash
$13 = (Hash *) 0x100100080
(gdb) p hash->hash_table
$14 = {
table = 0x0,
used = 0
}
The table ponts to NULL. Because of this that actually the tests fail. But I need to think more in how I implement this Hash thing.
Thanks for advice, but did't work here too.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The line 52 occurs a failure test and a wring assignment in the Hash.c line 30.
This occurs becausa I don't know how I access the pointer to pointer to struct(many HashEntries).