Update
git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4795 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -12,6 +12,7 @@ typedef enum hashtable_return_code_e {
|
|||||||
HASH_TABLE_KEY_NOT_EXISTS = 2,
|
HASH_TABLE_KEY_NOT_EXISTS = 2,
|
||||||
HASH_TABLE_KEY_ALREADY_EXISTS = 3,
|
HASH_TABLE_KEY_ALREADY_EXISTS = 3,
|
||||||
HASH_TABLE_BAD_PARAMETER_HASHTABLE = 4,
|
HASH_TABLE_BAD_PARAMETER_HASHTABLE = 4,
|
||||||
|
HASH_TABLE_SYSTEM_ERROR = 5,
|
||||||
HASH_TABLE_CODE_MAX
|
HASH_TABLE_CODE_MAX
|
||||||
} hashtable_rc_t;
|
} hashtable_rc_t;
|
||||||
|
|
||||||
|
|||||||
@@ -14,11 +14,11 @@
|
|||||||
|
|
||||||
static hash_size_t def_hashfunc(const void *keyP, int key_sizeP)
|
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 *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*)))) {
|
if(!(hashtbl->nodes=calloc(sizeP, sizeof(obj_hash_node_t*)))) {
|
||||||
free(hashtbl);
|
free(hashtbl);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
hashtbl->size=sizeP;
|
hashtbl->size=sizeP;
|
||||||
|
|
||||||
if(hashfuncP) hashtbl->hashfunc=hashfuncP;
|
if(hashfuncP) hashtbl->hashfunc=hashfuncP;
|
||||||
else hashtbl->hashfunc=def_hashfunc;
|
else hashtbl->hashfunc=def_hashfunc;
|
||||||
|
|
||||||
if(freekeyfuncP) hashtbl->freekeyfunc=freekeyfuncP;
|
if(freekeyfuncP) hashtbl->freekeyfunc=freekeyfuncP;
|
||||||
else hashtbl->freekeyfunc=free;
|
else hashtbl->freekeyfunc=free;
|
||||||
|
|
||||||
if(freedatafuncP) hashtbl->freedatafunc=freedatafuncP;
|
if(freedatafuncP) hashtbl->freedatafunc=freedatafuncP;
|
||||||
else hashtbl->freedatafunc=free;
|
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)
|
hashtable_rc_t obj_hashtable_destroy(obj_hash_table_t *hashtblP)
|
||||||
{
|
{
|
||||||
hash_size_t n;
|
hash_size_t n;
|
||||||
obj_hash_node_t *node, *oldnode;
|
obj_hash_node_t *node, *oldnode;
|
||||||
|
|
||||||
for(n=0; n<hashtblP->size; ++n) {
|
for(n=0; n<hashtblP->size; ++n) {
|
||||||
node=hashtblP->nodes[n];
|
node=hashtblP->nodes[n];
|
||||||
while(node) {
|
while(node) {
|
||||||
oldnode=node;
|
oldnode=node;
|
||||||
node=node->next;
|
node=node->next;
|
||||||
hashtblP->freekeyfunc(oldnode->key);
|
hashtblP->freekeyfunc(oldnode->key);
|
||||||
hashtblP->freedatafunc(oldnode->data);
|
hashtblP->freedatafunc(oldnode->data);
|
||||||
free(oldnode);
|
free(oldnode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(hashtblP->nodes);
|
free(hashtblP->nodes);
|
||||||
free(hashtblP);
|
free(hashtblP);
|
||||||
return HASH_TABLE_OK;
|
return HASH_TABLE_OK;
|
||||||
}
|
}
|
||||||
//-------------------------------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------------------------------
|
||||||
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 (obj_hash_table_t *hashtblP, void* keyP, int key_sizeP)
|
||||||
//-------------------------------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------------------------------
|
||||||
{
|
{
|
||||||
obj_hash_node_t *node;
|
obj_hash_node_t *node;
|
||||||
hash_size_t hash;
|
hash_size_t hash;
|
||||||
|
|
||||||
if (hashtblP == NULL) {
|
if (hashtblP == NULL) {
|
||||||
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
||||||
}
|
}
|
||||||
hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
|
hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
|
||||||
node=hashtblP->nodes[hash];
|
node=hashtblP->nodes[hash];
|
||||||
while(node) {
|
while(node) {
|
||||||
if(node->key == keyP) {
|
if(node->key == keyP) {
|
||||||
return HASH_TABLE_OK;
|
return HASH_TABLE_OK;
|
||||||
}
|
} else if (node->key_size == key_sizeP) {
|
||||||
node=node->next;
|
if (memcmp(node->key, keyP, key_sizeP) == 0) {
|
||||||
}
|
return HASH_TABLE_OK;
|
||||||
return HASH_TABLE_KEY_NOT_EXISTS;
|
}
|
||||||
|
}
|
||||||
|
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)
|
hashtable_rc_t obj_hashtable_insert(obj_hash_table_t *hashtblP, void* keyP, int key_sizeP, void *dataP)
|
||||||
{
|
{
|
||||||
obj_hash_node_t *node;
|
obj_hash_node_t *node;
|
||||||
hash_size_t hash;
|
hash_size_t hash;
|
||||||
|
|
||||||
if (hashtblP == NULL) {
|
if (hashtblP == NULL) {
|
||||||
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
||||||
}
|
}
|
||||||
hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
|
hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
|
||||||
node=hashtblP->nodes[hash];
|
node=hashtblP->nodes[hash];
|
||||||
while(node) {
|
while(node) {
|
||||||
if(node->key == keyP) {
|
if(node->key == keyP) {
|
||||||
if (node->data) {
|
if (node->data) {
|
||||||
hashtblP->freedatafunc(node->data);
|
hashtblP->freedatafunc(node->data);
|
||||||
}
|
}
|
||||||
node->data=dataP;
|
node->data=dataP;
|
||||||
// waste of memory here (keyP is lost) we should free it now
|
// waste of memory here (keyP is lost) we should free it now
|
||||||
return HASH_TABLE_INSERT_OVERWRITTEN_DATA;
|
return HASH_TABLE_INSERT_OVERWRITTEN_DATA;
|
||||||
}
|
}
|
||||||
node=node->next;
|
node=node->next;
|
||||||
}
|
}
|
||||||
if(!(node=malloc(sizeof(obj_hash_node_t)))) return -1;
|
if(!(node=malloc(sizeof(obj_hash_node_t)))) return -1;
|
||||||
node->key=keyP;
|
node->key=keyP;
|
||||||
node->data=dataP;
|
node->data=dataP;
|
||||||
if (hashtblP->nodes[hash]) {
|
if (hashtblP->nodes[hash]) {
|
||||||
node->next=hashtblP->nodes[hash];
|
node->next=hashtblP->nodes[hash];
|
||||||
} else {
|
} else {
|
||||||
node->next = NULL;
|
node->next = NULL;
|
||||||
}
|
}
|
||||||
hashtblP->nodes[hash]=node;
|
hashtblP->nodes[hash]=node;
|
||||||
return HASH_TABLE_OK;
|
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)
|
hashtable_rc_t obj_hashtable_remove(obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP)
|
||||||
{
|
{
|
||||||
obj_hash_node_t *node, *prevnode=NULL;
|
obj_hash_node_t *node, *prevnode=NULL;
|
||||||
hash_size_t hash;
|
hash_size_t hash;
|
||||||
|
|
||||||
if (hashtblP == NULL) {
|
if (hashtblP == NULL) {
|
||||||
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
|
hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
|
||||||
node=hashtblP->nodes[hash];
|
node=hashtblP->nodes[hash];
|
||||||
while(node) {
|
while(node) {
|
||||||
if(node->key == keyP) {
|
if ((node->key == keyP) || ((node->key_size == key_sizeP) && (memcmp(node->key, keyP, key_sizeP) == 0))){
|
||||||
if(prevnode) {
|
if(prevnode) {
|
||||||
prevnode->next=node->next;
|
prevnode->next=node->next;
|
||||||
} else {
|
} else {
|
||||||
hashtblP->nodes[hash]=node->next;
|
hashtblP->nodes[hash]=node->next;
|
||||||
}
|
}
|
||||||
hashtblP->freekeyfunc(node->key);
|
hashtblP->freekeyfunc(node->key);
|
||||||
hashtblP->freedatafunc(node->data);
|
hashtblP->freedatafunc(node->data);
|
||||||
free(node);
|
free(node);
|
||||||
return HASH_TABLE_OK;
|
return HASH_TABLE_OK;
|
||||||
}
|
}
|
||||||
prevnode=node;
|
prevnode=node;
|
||||||
node=node->next;
|
node=node->next;
|
||||||
}
|
}
|
||||||
return HASH_TABLE_KEY_NOT_EXISTS;
|
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)
|
hashtable_rc_t obj_hashtable_get(obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP, void** dataP)
|
||||||
{
|
{
|
||||||
obj_hash_node_t *node;
|
obj_hash_node_t *node;
|
||||||
hash_size_t hash;
|
hash_size_t hash;
|
||||||
|
|
||||||
if (hashtblP == NULL) {
|
if (hashtblP == NULL) {
|
||||||
*dataP = NULL;
|
*dataP = NULL;
|
||||||
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
||||||
}
|
}
|
||||||
hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
|
hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
|
||||||
node=hashtblP->nodes[hash];
|
node=hashtblP->nodes[hash];
|
||||||
while(node) {
|
while(node) {
|
||||||
if(node->key == keyP) {
|
if(node->key == keyP) {
|
||||||
*dataP = node->data;
|
*dataP = node->data;
|
||||||
return HASH_TABLE_OK;
|
return HASH_TABLE_OK;
|
||||||
}
|
} else if (node->key_size == key_sizeP) {
|
||||||
node=node->next;
|
if (memcmp(node->key, keyP, key_sizeP) == 0) {
|
||||||
}
|
*dataP = node->data;
|
||||||
*dataP = NULL;
|
return HASH_TABLE_OK;
|
||||||
return HASH_TABLE_KEY_NOT_EXISTS;
|
}
|
||||||
|
}
|
||||||
|
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)
|
hashtable_rc_t obj_hashtable_resize(obj_hash_table_t *hashtblP, hash_size_t sizeP)
|
||||||
{
|
{
|
||||||
obj_hash_table_t newtbl;
|
obj_hash_table_t newtbl;
|
||||||
hash_size_t n;
|
hash_size_t n;
|
||||||
obj_hash_node_t *node,*next;
|
obj_hash_node_t *node,*next;
|
||||||
|
|
||||||
if (hashtblP == NULL) {
|
if (hashtblP == NULL) {
|
||||||
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
newtbl.size = sizeP;
|
newtbl.size = sizeP;
|
||||||
newtbl.hashfunc = hashtblP->hashfunc;
|
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(n=0; n<hashtblP->size; ++n) {
|
||||||
for(node=hashtblP->nodes[n]; node; node=next) {
|
for(node=hashtblP->nodes[n]; node; node=next) {
|
||||||
next = node->next;
|
next = node->next;
|
||||||
obj_hashtable_insert(&newtbl, node->key, node->key_size, node->data);
|
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);
|
||||||
obj_hashtable_remove(hashtblP, node->key, node->key_size);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
free(hashtblP->nodes);
|
free(hashtblP->nodes);
|
||||||
hashtblP->size=newtbl.size;
|
hashtblP->size=newtbl.size;
|
||||||
hashtblP->nodes=newtbl.nodes;
|
hashtblP->nodes=newtbl.nodes;
|
||||||
|
|
||||||
return HASH_TABLE_OK;
|
return HASH_TABLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,28 +10,29 @@ typedef size_t hash_size_t;
|
|||||||
|
|
||||||
|
|
||||||
typedef struct obj_hash_node_s {
|
typedef struct obj_hash_node_s {
|
||||||
int key_size;
|
int key_size;
|
||||||
void *key;
|
void *key;
|
||||||
void *data;
|
void *data;
|
||||||
struct obj_hash_node_s *next;
|
struct obj_hash_node_s *next;
|
||||||
} obj_hash_node_t;
|
} obj_hash_node_t;
|
||||||
|
|
||||||
typedef struct obj_hash_table_s {
|
typedef struct obj_hash_table_s {
|
||||||
hash_size_t size;
|
hash_size_t size;
|
||||||
hash_size_t num_elements;
|
hash_size_t num_elements;
|
||||||
struct obj_hash_node_s **nodes;
|
struct obj_hash_node_s **nodes;
|
||||||
hash_size_t (*hashfunc)(const void*, int);
|
hash_size_t (*hashfunc)(const void*, int);
|
||||||
void (*freekeyfunc)(void*);
|
void (*freekeyfunc)(void*);
|
||||||
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 (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 *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 (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_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_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 (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_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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user