diff --git a/common/utils/collection/hashtable/hashtable.h b/common/utils/collection/hashtable/hashtable.h index b76b88506fda53b9a00aafda70ea8cd903f611f7..28dd5508d324473e9fe4b4166c21c37d983d562b 100755 --- a/common/utils/collection/hashtable/hashtable.h +++ b/common/utils/collection/hashtable/hashtable.h @@ -12,6 +12,7 @@ typedef enum hashtable_return_code_e { HASH_TABLE_KEY_NOT_EXISTS = 2, HASH_TABLE_KEY_ALREADY_EXISTS = 3, HASH_TABLE_BAD_PARAMETER_HASHTABLE = 4, + HASH_TABLE_SYSTEM_ERROR = 5, HASH_TABLE_CODE_MAX } hashtable_rc_t; diff --git a/common/utils/collection/hashtable/obj_hashtable.c b/common/utils/collection/hashtable/obj_hashtable.c index 192a9f28eeca8e2608a4699e46413b89ec9bc75f..b2280144b73b7201b18f4d3de2c5a0eb6d7fc327 100755 --- a/common/utils/collection/hashtable/obj_hashtable.c +++ b/common/utils/collection/hashtable/obj_hashtable.c @@ -14,11 +14,11 @@ static hash_size_t def_hashfunc(const void *keyP, int key_sizeP) { - hash_size_t hash=0; + hash_size_t hash=0; - while(key_sizeP) hash^=((unsigned char*)keyP)[key_sizeP --]; + while(key_sizeP) hash^=((unsigned char*)keyP)[key_sizeP --]; - return hash; + return hash; } //------------------------------------------------------------------------------------------------------------------------------- @@ -30,27 +30,27 @@ static hash_size_t def_hashfunc(const void *keyP, int key_sizeP) */ obj_hash_table_t *obj_hashtable_create(hash_size_t sizeP, hash_size_t (*hashfuncP)(const void*, int ), void (*freekeyfuncP)(void*), void (*freedatafuncP)(void*)) { - obj_hash_table_t *hashtbl; + obj_hash_table_t *hashtbl; - if(!(hashtbl=malloc(sizeof(obj_hash_table_t)))) return NULL; + if(!(hashtbl=malloc(sizeof(obj_hash_table_t)))) return NULL; - if(!(hashtbl->nodes=calloc(sizeP, sizeof(obj_hash_node_t*)))) { - free(hashtbl); - return NULL; - } + if(!(hashtbl->nodes=calloc(sizeP, sizeof(obj_hash_node_t*)))) { + free(hashtbl); + return NULL; + } - hashtbl->size=sizeP; + hashtbl->size=sizeP; - if(hashfuncP) hashtbl->hashfunc=hashfuncP; - else hashtbl->hashfunc=def_hashfunc; + if(hashfuncP) hashtbl->hashfunc=hashfuncP; + else hashtbl->hashfunc=def_hashfunc; - if(freekeyfuncP) hashtbl->freekeyfunc=freekeyfuncP; - else hashtbl->freekeyfunc=free; + if(freekeyfuncP) hashtbl->freekeyfunc=freekeyfuncP; + else hashtbl->freekeyfunc=free; - if(freedatafuncP) hashtbl->freedatafunc=freedatafuncP; - else hashtbl->freedatafunc=free; + if(freedatafuncP) hashtbl->freedatafunc=freedatafuncP; + else hashtbl->freedatafunc=free; - return hashtbl; + return hashtbl; } //------------------------------------------------------------------------------------------------------------------------------- /* @@ -59,42 +59,46 @@ obj_hash_table_t *obj_hashtable_create(hash_size_t sizeP, hash_size_t (*hashfunc */ hashtable_rc_t obj_hashtable_destroy(obj_hash_table_t *hashtblP) { - hash_size_t n; - obj_hash_node_t *node, *oldnode; - - for(n=0; n<hashtblP->size; ++n) { - node=hashtblP->nodes[n]; - while(node) { - oldnode=node; - node=node->next; - hashtblP->freekeyfunc(oldnode->key); - hashtblP->freedatafunc(oldnode->data); - free(oldnode); - } - } - free(hashtblP->nodes); - free(hashtblP); - return HASH_TABLE_OK; + hash_size_t n; + obj_hash_node_t *node, *oldnode; + + for(n=0; n<hashtblP->size; ++n) { + node=hashtblP->nodes[n]; + while(node) { + oldnode=node; + node=node->next; + hashtblP->freekeyfunc(oldnode->key); + hashtblP->freedatafunc(oldnode->data); + free(oldnode); + } + } + free(hashtblP->nodes); + free(hashtblP); + return HASH_TABLE_OK; } //------------------------------------------------------------------------------------------------------------------------------- hashtable_rc_t obj_hashtable_is_key_exists (obj_hash_table_t *hashtblP, void* keyP, int key_sizeP) //------------------------------------------------------------------------------------------------------------------------------- { - obj_hash_node_t *node; - hash_size_t hash; - - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size; - node=hashtblP->nodes[hash]; - while(node) { - if(node->key == keyP) { - return HASH_TABLE_OK; - } - node=node->next; - } - return HASH_TABLE_KEY_NOT_EXISTS; + obj_hash_node_t *node; + hash_size_t hash; + + if (hashtblP == NULL) { + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } + hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size; + node=hashtblP->nodes[hash]; + while(node) { + if(node->key == keyP) { + return HASH_TABLE_OK; + } else if (node->key_size == key_sizeP) { + if (memcmp(node->key, keyP, key_sizeP) == 0) { + return HASH_TABLE_OK; + } + } + node=node->next; + } + return HASH_TABLE_KEY_NOT_EXISTS; } //------------------------------------------------------------------------------------------------------------------------------- /* @@ -103,35 +107,35 @@ hashtable_rc_t obj_hashtable_is_key_exists (obj_hash_table_t *hashtblP, void* ke */ hashtable_rc_t obj_hashtable_insert(obj_hash_table_t *hashtblP, void* keyP, int key_sizeP, void *dataP) { - obj_hash_node_t *node; - hash_size_t hash; - - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size; - node=hashtblP->nodes[hash]; - while(node) { - if(node->key == keyP) { - if (node->data) { - hashtblP->freedatafunc(node->data); - } - node->data=dataP; - // waste of memory here (keyP is lost) we should free it now - return HASH_TABLE_INSERT_OVERWRITTEN_DATA; - } - node=node->next; - } - if(!(node=malloc(sizeof(obj_hash_node_t)))) return -1; - node->key=keyP; - node->data=dataP; - if (hashtblP->nodes[hash]) { - node->next=hashtblP->nodes[hash]; - } else { - node->next = NULL; - } - hashtblP->nodes[hash]=node; - return HASH_TABLE_OK; + obj_hash_node_t *node; + hash_size_t hash; + + if (hashtblP == NULL) { + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } + hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size; + node=hashtblP->nodes[hash]; + while(node) { + if(node->key == keyP) { + if (node->data) { + hashtblP->freedatafunc(node->data); + } + node->data=dataP; + // waste of memory here (keyP is lost) we should free it now + return HASH_TABLE_INSERT_OVERWRITTEN_DATA; + } + node=node->next; + } + if(!(node=malloc(sizeof(obj_hash_node_t)))) return -1; + node->key=keyP; + node->data=dataP; + if (hashtblP->nodes[hash]) { + node->next=hashtblP->nodes[hash]; + } else { + node->next = NULL; + } + hashtblP->nodes[hash]=node; + return HASH_TABLE_OK; } //------------------------------------------------------------------------------------------------------------------------------- /* @@ -140,31 +144,31 @@ hashtable_rc_t obj_hashtable_insert(obj_hash_table_t *hashtblP, void* keyP, int */ hashtable_rc_t obj_hashtable_remove(obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP) { - obj_hash_node_t *node, *prevnode=NULL; - hash_size_t hash; - - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - - hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size; - node=hashtblP->nodes[hash]; - while(node) { - if(node->key == keyP) { - if(prevnode) { - prevnode->next=node->next; - } else { - hashtblP->nodes[hash]=node->next; - } - hashtblP->freekeyfunc(node->key); - hashtblP->freedatafunc(node->data); - free(node); - return HASH_TABLE_OK; - } - prevnode=node; - node=node->next; - } - return HASH_TABLE_KEY_NOT_EXISTS; + obj_hash_node_t *node, *prevnode=NULL; + hash_size_t hash; + + if (hashtblP == NULL) { + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } + + hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size; + node=hashtblP->nodes[hash]; + while(node) { + if ((node->key == keyP) || ((node->key_size == key_sizeP) && (memcmp(node->key, keyP, key_sizeP) == 0))){ + if(prevnode) { + prevnode->next=node->next; + } else { + hashtblP->nodes[hash]=node->next; + } + hashtblP->freekeyfunc(node->key); + hashtblP->freedatafunc(node->data); + free(node); + return HASH_TABLE_OK; + } + prevnode=node; + node=node->next; + } + return HASH_TABLE_KEY_NOT_EXISTS; } //------------------------------------------------------------------------------------------------------------------------------- /* @@ -173,24 +177,52 @@ hashtable_rc_t obj_hashtable_remove(obj_hash_table_t *hashtblP, const void* keyP */ hashtable_rc_t obj_hashtable_get(obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP, void** dataP) { - obj_hash_node_t *node; - hash_size_t hash; - - if (hashtblP == NULL) { - *dataP = NULL; - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size; - node=hashtblP->nodes[hash]; - while(node) { - if(node->key == keyP) { - *dataP = node->data; - return HASH_TABLE_OK; - } - node=node->next; - } - *dataP = NULL; - return HASH_TABLE_KEY_NOT_EXISTS; + obj_hash_node_t *node; + hash_size_t hash; + + if (hashtblP == NULL) { + *dataP = NULL; + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } + hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size; + node=hashtblP->nodes[hash]; + while(node) { + if(node->key == keyP) { + *dataP = node->data; + return HASH_TABLE_OK; + } else if (node->key_size == key_sizeP) { + if (memcmp(node->key, keyP, key_sizeP) == 0) { + *dataP = node->data; + return HASH_TABLE_OK; + } + } + node=node->next; + } + *dataP = NULL; + return HASH_TABLE_KEY_NOT_EXISTS; +} +//------------------------------------------------------------------------------------------------------------------------------- +/* + * Function to return all keys of an object hash table + */ +hashtable_rc_t obj_hashtable_get_keys(obj_hash_table_t *hashtblP, void ** keysP, unsigned int *sizeP) +{ + size_t n = 0; + obj_hash_node_t *node = NULL; + obj_hash_node_t *next = NULL; + + *sizeP = 0; + keysP = calloc(hashtblP->num_elements, sizeof(void *)); + if (keysP) { + for(n=0; n<hashtblP->size; ++n) { + for(node=hashtblP->nodes[n]; node; node=next) { + keysP[*sizeP++] = node->key; + next = node->next; + } + } + return HASH_TABLE_OK; + } + return HASH_TABLE_SYSTEM_ERROR; } //------------------------------------------------------------------------------------------------------------------------------- /* @@ -205,33 +237,32 @@ hashtable_rc_t obj_hashtable_get(obj_hash_table_t *hashtblP, const void* keyP, i */ hashtable_rc_t obj_hashtable_resize(obj_hash_table_t *hashtblP, hash_size_t sizeP) { - obj_hash_table_t newtbl; - hash_size_t n; - obj_hash_node_t *node,*next; + obj_hash_table_t newtbl; + hash_size_t n; + obj_hash_node_t *node,*next; - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } + if (hashtblP == NULL) { + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } - newtbl.size = sizeP; - newtbl.hashfunc = hashtblP->hashfunc; + newtbl.size = sizeP; + newtbl.hashfunc = hashtblP->hashfunc; - if(!(newtbl.nodes=calloc(sizeP, sizeof(obj_hash_node_t*)))) return -1; + if(!(newtbl.nodes=calloc(sizeP, sizeof(obj_hash_node_t*)))) return HASH_TABLE_SYSTEM_ERROR; - for(n=0; n<hashtblP->size; ++n) { - for(node=hashtblP->nodes[n]; node; node=next) { - next = node->next; - obj_hashtable_insert(&newtbl, node->key, node->key_size, node->data); - //WARNING Lionel GAUTHIER: BAD CODE TO BE REWRITTEN - obj_hashtable_remove(hashtblP, node->key, node->key_size); - } - } + for(n=0; n<hashtblP->size; ++n) { + for(node=hashtblP->nodes[n]; node; node=next) { + next = node->next; + obj_hashtable_insert(&newtbl, node->key, node->key_size, node->data); + obj_hashtable_remove(hashtblP, node->key, node->key_size); + } + } - free(hashtblP->nodes); - hashtblP->size=newtbl.size; - hashtblP->nodes=newtbl.nodes; + free(hashtblP->nodes); + hashtblP->size=newtbl.size; + hashtblP->nodes=newtbl.nodes; - return HASH_TABLE_OK; + return HASH_TABLE_OK; } diff --git a/common/utils/collection/hashtable/obj_hashtable.h b/common/utils/collection/hashtable/obj_hashtable.h index ff126a3dab90fdfd47fe61938bd07e6b9c3e6022..466f1a5b14b80e06f351da68ab0bdb806a484fe4 100755 --- a/common/utils/collection/hashtable/obj_hashtable.h +++ b/common/utils/collection/hashtable/obj_hashtable.h @@ -10,28 +10,29 @@ typedef size_t hash_size_t; typedef struct obj_hash_node_s { - int key_size; - void *key; - void *data; - struct obj_hash_node_s *next; + int key_size; + void *key; + void *data; + struct obj_hash_node_s *next; } obj_hash_node_t; typedef struct obj_hash_table_s { - hash_size_t size; - hash_size_t num_elements; - struct obj_hash_node_s **nodes; - hash_size_t (*hashfunc)(const void*, int); - void (*freekeyfunc)(void*); - void (*freedatafunc)(void*); + hash_size_t size; + hash_size_t num_elements; + struct obj_hash_node_s **nodes; + hash_size_t (*hashfunc)(const void*, int); + void (*freekeyfunc)(void*); + void (*freedatafunc)(void*); } 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*)); -hashtable_rc_t obj_hashtable_destroy(obj_hash_table_t *hashtblP); +obj_hash_table_t *obj_hashtable_create (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_is_key_exists (obj_hash_table_t *hashtblP, void* keyP, 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_remove (obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP); -hashtable_rc_t obj_hashtable_get (obj_hash_table_t *hashtblP, const void* keyP, 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_insert (obj_hash_table_t *hashtblP, void* keyP, 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_get (obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP, void ** dataP); +hashtable_rc_t obj_hashtable_get_keys(obj_hash_table_t *hashtblP, void ** keysP, unsigned int *sizeP); +hashtable_rc_t obj_hashtable_resize (obj_hash_table_t *hashtblP, hash_size_t sizeP);