Commit 0a96b5a8 authored by gauthier's avatar gauthier

bug in obj_hashtable

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7694 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 1a24edeb
...@@ -172,14 +172,19 @@ hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t *const hashtblP, ...@@ -172,14 +172,19 @@ hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t *const hashtblP,
return HASH_TABLE_OK; return HASH_TABLE_OK;
} }
//------------------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------------------------
hashtable_rc_t hashtable_dump_content (const hash_table_t * const hashtblP, char * const buffer_pP, int * const remaining_bytes_in_buffer_pP ) hashtable_rc_t hashtable_dump_content (
const hash_table_t * const hashtblP,
char * const buffer_pP,
int * const remaining_bytes_in_buffer_pP)
//------------------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------------------------
{ {
hash_node_t *node = NULL; hash_node_t *node = NULL;
unsigned int i = 0; unsigned int i = 0;
unsigned int num_elements = 0; unsigned int num_elements = 0;
int rc;
if (hashtblP == NULL) { if (hashtblP == NULL) {
*remaining_bytes_in_buffer_pP = snprintf( rc = snprintf(
buffer_pP, buffer_pP,
*remaining_bytes_in_buffer_pP, *remaining_bytes_in_buffer_pP,
"HASH_TABLE_BAD_PARAMETER_HASHTABLE"); "HASH_TABLE_BAD_PARAMETER_HASHTABLE");
...@@ -189,13 +194,18 @@ hashtable_rc_t hashtable_dump_content (const hash_table_t * const hashtblP, char ...@@ -189,13 +194,18 @@ hashtable_rc_t hashtable_dump_content (const hash_table_t * const hashtblP, char
if (hashtblP->nodes[i] != NULL) { if (hashtblP->nodes[i] != NULL) {
node=hashtblP->nodes[i]; node=hashtblP->nodes[i];
while(node) { while(node) {
*remaining_bytes_in_buffer_pP = snprintf( rc = snprintf(
buffer_pP, buffer_pP,
*remaining_bytes_in_buffer_pP, *remaining_bytes_in_buffer_pP,
"Key 0x%"PRIx64" Element %p\n", "Key 0x%"PRIx64" Element %p\n",
node->key, node->key,
node->data); node->data);
node=node->next; node=node->next;
if ((0 > rc) || (*remaining_bytes_in_buffer_pP < rc)) {
fprintf(stderr, "Error while dumping hashtable content");
} else {
*remaining_bytes_in_buffer_pP -= rc;
}
} }
} }
i += 1; i += 1;
...@@ -242,10 +252,10 @@ hashtable_rc_t hashtable_insert(hash_table_t * const hashtblP, const hash_key_t ...@@ -242,10 +252,10 @@ hashtable_rc_t hashtable_insert(hash_table_t * const hashtblP, const hash_key_t
} }
//------------------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------------------------
/* /*
* To remove an element from the hash table, we just search for it in the linked list for that hash value, * To free an element from the hash table, we just search for it in the linked list for that hash value,
* and remove it if it is found. If it was not found, it is an error and -1 is returned. * and free it if it is found. If it was not found, it is an error and -1 is returned.
*/ */
hashtable_rc_t hashtable_remove(hash_table_t * const hashtblP, const hash_key_t keyP) hashtable_rc_t hashtable_free(hash_table_t * const hashtblP, const hash_key_t keyP)
{ {
hash_node_t *node, *prevnode=NULL; hash_node_t *node, *prevnode=NULL;
hash_size_t hash = 0; hash_size_t hash = 0;
...@@ -271,6 +281,36 @@ hashtable_rc_t hashtable_remove(hash_table_t * const hashtblP, const hash_key_t ...@@ -271,6 +281,36 @@ hashtable_rc_t hashtable_remove(hash_table_t * const hashtblP, const hash_key_t
} }
return HASH_TABLE_KEY_NOT_EXISTS; return HASH_TABLE_KEY_NOT_EXISTS;
} }
//-------------------------------------------------------------------------------------------------------------------------------
/*
* To remove an element from the hash table, we just search for it in the linked list for that hash value,
* and remove it if it is found. If it was not found, it is an error and -1 is returned.
*/
hashtable_rc_t hashtable_remove(hash_table_t * const hashtblP, const hash_key_t keyP, void** dataP)
{
hash_node_t *node, *prevnode=NULL;
hash_size_t hash = 0;
if (hashtblP == NULL) {
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
}
hash=hashtblP->hashfunc(keyP)%hashtblP->size;
node=hashtblP->nodes[hash];
while(node) {
if(node->key == keyP) {
if(prevnode) prevnode->next=node->next;
else hashtblP->nodes[hash]=node->next;
*dataP = node->data;
free(node);
hashtblP->num_elements -= 1;
return HASH_TABLE_OK;
}
prevnode=node;
node=node->next;
}
return HASH_TABLE_KEY_NOT_EXISTS;
}
//------------------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------------------------
/* /*
* Searching for an element is easy. We just search through the linked list for the corresponding hash value. * Searching for an element is easy. We just search through the linked list for the corresponding hash value.
...@@ -308,7 +348,7 @@ hashtable_rc_t hashtable_get(const hash_table_t * const hashtblP, const hash_key ...@@ -308,7 +348,7 @@ hashtable_rc_t hashtable_get(const hash_table_t * const hashtblP, const hash_key
* If the number of elements are reduced, the hash table will waste memory. That is why we provide a function for resizing the table. * If the number of elements are reduced, the hash table will waste memory. That is why we provide a function for resizing the table.
* Resizing a hash table is not as easy as a realloc(). All hash values must be recalculated and each element must be inserted into its new position. * Resizing a hash table is not as easy as a realloc(). All hash values must be recalculated and each element must be inserted into its new position.
* We create a temporary hash_table_t object (newtbl) to be used while building the new hashes. * We create a temporary hash_table_t object (newtbl) to be used while building the new hashes.
* This allows us to reuse hashtable_insert() and hashtable_remove(), when moving the elements to the new table. * This allows us to reuse hashtable_insert() and hashtable_free(), when moving the elements to the new table.
* After that, we can just free the old table and copy the elements from newtbl to hashtbl. * After that, we can just free the old table and copy the elements from newtbl to hashtbl.
*/ */
...@@ -332,7 +372,7 @@ hashtable_rc_t hashtable_resize(hash_table_t * const hashtblP, const hash_size_t ...@@ -332,7 +372,7 @@ hashtable_rc_t hashtable_resize(hash_table_t * const hashtblP, const hash_size_t
next = node->next; next = node->next;
hashtable_insert(&newtbl, node->key, node->data); hashtable_insert(&newtbl, node->key, node->data);
// Lionel GAUTHIER: BAD CODE TO BE REWRITTEN // Lionel GAUTHIER: BAD CODE TO BE REWRITTEN
hashtable_remove(hashtblP, node->key); hashtable_free(hashtblP, node->key);
} }
} }
......
...@@ -49,6 +49,9 @@ typedef enum hashtable_return_code_e { ...@@ -49,6 +49,9 @@ typedef enum hashtable_return_code_e {
HASH_TABLE_CODE_MAX HASH_TABLE_CODE_MAX
} hashtable_rc_t; } hashtable_rc_t;
#define HASH_TABLE_DEFAULT_HASH_FUNC NULL
#define HASH_TABLE_DEFAULT_FREE_FUNC NULL
typedef struct hash_node_s { typedef struct hash_node_s {
hash_key_t key; hash_key_t key;
...@@ -72,7 +75,8 @@ hashtable_rc_t hashtable_is_key_exists (const hash_table_t * const hashtbl, con ...@@ -72,7 +75,8 @@ hashtable_rc_t hashtable_is_key_exists (const hash_table_t * const hashtbl, con
hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t * const hashtblP, void funct(hash_key_t keyP, void* dataP, void* parameterP), void* parameterP); hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t * const hashtblP, void funct(hash_key_t keyP, void* dataP, void* parameterP), void* parameterP);
hashtable_rc_t hashtable_dump_content (const hash_table_t * const hashtblP, char * const buffer_pP, int * const remaining_bytes_in_buffer_pP ); hashtable_rc_t hashtable_dump_content (const hash_table_t * const hashtblP, char * const buffer_pP, int * const remaining_bytes_in_buffer_pP );
hashtable_rc_t hashtable_insert (hash_table_t * const hashtbl, const hash_key_t key, void *data); hashtable_rc_t hashtable_insert (hash_table_t * const hashtbl, const hash_key_t key, void *data);
hashtable_rc_t hashtable_remove (hash_table_t * const hashtbl, const hash_key_t key); hashtable_rc_t hashtable_free (hash_table_t * const hashtbl, const hash_key_t key);
hashtable_rc_t hashtable_remove(hash_table_t * const hashtblP, const hash_key_t keyP, void** dataP);
hashtable_rc_t hashtable_get (const hash_table_t * const hashtbl, const hash_key_t key, void **dataP); hashtable_rc_t hashtable_get (const hash_table_t * const hashtbl, const hash_key_t key, void **dataP);
hashtable_rc_t hashtable_resize (hash_table_t * const hashtbl, const hash_size_t size); hashtable_rc_t hashtable_resize (hash_table_t * const hashtbl, const hash_size_t size);
......
...@@ -52,14 +52,16 @@ typedef struct obj_hash_table_s { ...@@ -52,14 +52,16 @@ typedef struct obj_hash_table_s {
void (*freedatafunc)(void*); void (*freedatafunc)(void*);
} obj_hash_table_t; } obj_hash_table_t;
obj_hash_table_t *obj_hashtable_create (hash_size_t size, hash_size_t (*hashfunc)(const void*, int ), void (*freekeyfunc)(void*), void (*freedatafunc)(void*)); obj_hash_table_t *obj_hashtable_create (const hash_size_t size, hash_size_t (*hashfunc)(const void*, int ), void (*freekeyfunc)(void*), void (*freedatafunc)(void*));
hashtable_rc_t obj_hashtable_destroy (obj_hash_table_t *hashtblP); hashtable_rc_t obj_hashtable_destroy (obj_hash_table_t * const hashtblP);
hashtable_rc_t obj_hashtable_is_key_exists (obj_hash_table_t *hashtblP, void* keyP, int key_sizeP); hashtable_rc_t obj_hashtable_is_key_exists (const obj_hash_table_t * const hashtblP, const void* const keyP, const int key_sizeP);
hashtable_rc_t obj_hashtable_insert (obj_hash_table_t *hashtblP, void* keyP, int key_sizeP, void *dataP); hashtable_rc_t obj_hashtable_insert (obj_hash_table_t * const hashtblP, const void* const keyP, const int key_sizeP, void *dataP);
hashtable_rc_t obj_hashtable_remove (obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP); hashtable_rc_t obj_hashtable_dump_content (const obj_hash_table_t * const hashtblP,char * const buffer_pP,int * const remaining_bytes_in_buffer_pP);
hashtable_rc_t obj_hashtable_get (obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP, void ** dataP); hashtable_rc_t obj_hashtable_free (obj_hash_table_t *hashtblP, const void* keyP, const int key_sizeP);
hashtable_rc_t obj_hashtable_get_keys(obj_hash_table_t *hashtblP, void ** keysP, unsigned int *sizeP); hashtable_rc_t obj_hashtable_remove(obj_hash_table_t *hashtblP, const void* keyP, const int key_sizeP, void** dataP);
hashtable_rc_t obj_hashtable_resize (obj_hash_table_t *hashtblP, hash_size_t sizeP); hashtable_rc_t obj_hashtable_get (const obj_hash_table_t * const hashtblP, const void* const keyP, const int key_sizeP, void ** dataP);
hashtable_rc_t obj_hashtable_get_keys(const obj_hash_table_t * const hashtblP, void ** keysP, unsigned int * sizeP);
hashtable_rc_t obj_hashtable_resize (obj_hash_table_t * const hashtblP, const hash_size_t sizeP);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment