Skip to content

Instantly share code, notes, and snippets.

@tomas-stefano
Created November 2, 2010 18:55
Show Gist options
  • Select an option

  • Save tomas-stefano/660103 to your computer and use it in GitHub Desktop.

Select an option

Save tomas-stefano/660103 to your computer and use it in GitHub Desktop.
/* 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;
}
#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
#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;
}
@tomas-stefano
Copy link
Copy Markdown
Author

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).

   (hash)->hash_table[0]->key;  // this fails. How I access the key of the Hash??

@bbcoimbra
Copy link
Copy Markdown

try hash->(*hash_table).key

@tomas-stefano
Copy link
Copy Markdown
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