New configs with libconfig
git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5071 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
char* hashtble_rc_code2string(hashtbl_rc_t rcP)
|
||||
char* hashtable_rc_code2string(hashtable_rc_t rcP)
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
{
|
||||
switch (rcP) {
|
||||
@@ -17,220 +17,226 @@ char* hashtble_rc_code2string(hashtbl_rc_t rcP)
|
||||
case HASH_TABLE_KEY_NOT_EXISTS: return "HASH_TABLE_KEY_NOT_EXISTS";break;
|
||||
case HASH_TABLE_KEY_ALREADY_EXISTS: return "HASH_TABLE_KEY_ALREADY_EXISTS";break;
|
||||
case HASH_TABLE_BAD_PARAMETER_HASHTABLE: return "HASH_TABLE_BAD_PARAMETER_HASHTABLE";break;
|
||||
default: return "UNKNOWN hashtbl_rc_t";
|
||||
|
||||
default: return "UNKNOWN hashtable_rc_t";
|
||||
}
|
||||
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
* free int function
|
||||
* hash_free_int_func() is used when this hashtable is used to store int values as data (pointer = value).
|
||||
*/
|
||||
|
||||
void hash_free_int_func(void* memoryP){}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
* Default hash function
|
||||
* def_hashfunc() is the default used by hashtbl_create() when the user didn't specify one.
|
||||
* def_hashfunc() is the default used by hashtable_create() when the user didn't specify one.
|
||||
* This is a simple/naive hash function which adds the key's ASCII char values. It will probably generate lots of collisions on large hash tables.
|
||||
*/
|
||||
|
||||
static hash_size_t def_hashfunc(const uint64_t keyP)
|
||||
{
|
||||
return (hash_size_t)keyP;
|
||||
return (hash_size_t)keyP;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
* Initialisation
|
||||
* hashtbl_create() sets up the initial structure of the hash table. The user specified size will be allocated and initialized to NULL.
|
||||
* hashtable_create() sets up the initial structure of the hash table. The user specified size will be allocated and initialized to NULL.
|
||||
* The user can also specify a hash function. If the hashfunc argument is NULL, a default hash function is used.
|
||||
* If an error occurred, NULL is returned. All other values in the returned hash_table_t pointer should be released with hashtbl_destroy().
|
||||
* If an error occurred, NULL is returned. All other values in the returned hash_table_t pointer should be released with hashtable_destroy().
|
||||
*/
|
||||
hash_table_t *hashtbl_create(hash_size_t sizeP, hash_size_t (*hashfuncP)(const uint64_t ), void (*freefuncP)(void*))
|
||||
hash_table_t *hashtable_create(hash_size_t sizeP, hash_size_t (*hashfuncP)(const uint64_t ), void (*freefuncP)(void*))
|
||||
{
|
||||
hash_table_t *hashtbl;
|
||||
hash_table_t *hashtbl;
|
||||
|
||||
if(!(hashtbl=malloc(sizeof(hash_table_t)))) return NULL;
|
||||
if(!(hashtbl=malloc(sizeof(hash_table_t)))) return NULL;
|
||||
|
||||
if(!(hashtbl->nodes=calloc(sizeP, sizeof(hash_node_t*)))) {
|
||||
free(hashtbl);
|
||||
return NULL;
|
||||
}
|
||||
if(!(hashtbl->nodes=calloc(sizeP, sizeof(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(freefuncP) hashtbl->freefunc=freefuncP;
|
||||
else hashtbl->freefunc=free;
|
||||
if(freefuncP) hashtbl->freefunc=freefuncP;
|
||||
else hashtbl->freefunc=free;
|
||||
|
||||
return hashtbl;
|
||||
return hashtbl;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
* Cleanup
|
||||
* The hashtbl_destroy() walks through the linked lists for each possible hash value, and releases the elements. It also releases the nodes array and the hash_table_t.
|
||||
* The hashtable_destroy() walks through the linked lists for each possible hash value, and releases the elements. It also releases the nodes array and the hash_table_t.
|
||||
*/
|
||||
hashtbl_rc_t hashtbl_destroy(hash_table_t *hashtblP)
|
||||
hashtable_rc_t hashtable_destroy(hash_table_t *hashtblP)
|
||||
{
|
||||
hash_size_t n;
|
||||
hash_node_t *node, *oldnode;
|
||||
hash_size_t n;
|
||||
hash_node_t *node, *oldnode;
|
||||
|
||||
if (hashtblP == NULL) {
|
||||
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
||||
}
|
||||
if (hashtblP == NULL) {
|
||||
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
||||
}
|
||||
|
||||
for(n=0; n<hashtblP->size; ++n) {
|
||||
node=hashtblP->nodes[n];
|
||||
while(node) {
|
||||
oldnode=node;
|
||||
node=node->next;
|
||||
if (oldnode->data) {
|
||||
hashtblP->freefunc(oldnode->data);
|
||||
}
|
||||
free(oldnode);
|
||||
}
|
||||
}
|
||||
free(hashtblP->nodes);
|
||||
free(hashtblP);
|
||||
return HASH_TABLE_OK;
|
||||
for(n=0; n<hashtblP->size; ++n) {
|
||||
node=hashtblP->nodes[n];
|
||||
while(node) {
|
||||
oldnode=node;
|
||||
node=node->next;
|
||||
if (oldnode->data) {
|
||||
hashtblP->freefunc(oldnode->data);
|
||||
}
|
||||
free(oldnode);
|
||||
}
|
||||
}
|
||||
free(hashtblP->nodes);
|
||||
free(hashtblP);
|
||||
return HASH_TABLE_OK;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
hashtbl_rc_t hashtbl_is_key_exists (hash_table_t *hashtblP, const uint64_t keyP)
|
||||
hashtable_rc_t hashtable_is_key_exists (hash_table_t *hashtblP, const uint64_t keyP)
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
{
|
||||
hash_node_t *node;
|
||||
hash_size_t hash;
|
||||
hash_node_t *node;
|
||||
hash_size_t hash;
|
||||
|
||||
if (hashtblP == NULL) {
|
||||
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
||||
}
|
||||
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) {
|
||||
return HASH_TABLE_OK;
|
||||
}
|
||||
node=node->next;
|
||||
}
|
||||
return HASH_TABLE_KEY_NOT_EXISTS;
|
||||
hash=hashtblP->hashfunc(keyP)%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;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
hashtbl_rc_t hashtbl_apply_funct_on_elements (hash_table_t *hashtblP, void functP(uint64_t keyP, void* dataP, void* parameterP), void* parameterP)
|
||||
hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t *hashtblP, void functP(uint64_t keyP, void* dataP, void* parameterP), void* parameterP)
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
{
|
||||
hash_node_t *node = NULL;
|
||||
unsigned int i = 0;
|
||||
unsigned int num_elements = 0;
|
||||
if (hashtblP == NULL) {
|
||||
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
||||
}
|
||||
while ((num_elements < hashtblP->num_elements) && (i < hashtblP->size)) {
|
||||
if (hashtblP->nodes[i] != NULL) {
|
||||
node=hashtblP->nodes[i];
|
||||
while(node) {
|
||||
num_elements += 1;
|
||||
functP(node->key, node->data, parameterP);
|
||||
node=node->next;
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
return HASH_TABLE_OK;
|
||||
hash_node_t *node = NULL;
|
||||
unsigned int i = 0;
|
||||
unsigned int num_elements = 0;
|
||||
if (hashtblP == NULL) {
|
||||
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
||||
}
|
||||
while ((num_elements < hashtblP->num_elements) && (i < hashtblP->size)) {
|
||||
if (hashtblP->nodes[i] != NULL) {
|
||||
node=hashtblP->nodes[i];
|
||||
while(node) {
|
||||
num_elements += 1;
|
||||
functP(node->key, node->data, parameterP);
|
||||
node=node->next;
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
return HASH_TABLE_OK;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
* Adding a new element
|
||||
* To make sure the hash value is not bigger than size, the result of the user provided hash function is used modulo size.
|
||||
*/
|
||||
hashtbl_rc_t hashtbl_insert(hash_table_t *hashtblP, const uint64_t keyP, void *dataP)
|
||||
hashtable_rc_t hashtable_insert(hash_table_t *hashtblP, const uint64_t keyP, void *dataP)
|
||||
{
|
||||
hash_node_t *node;
|
||||
hash_size_t hash;
|
||||
if (hashtblP == NULL) {
|
||||
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
||||
}
|
||||
hash=hashtblP->hashfunc(keyP)%hashtblP->size;
|
||||
hash_node_t *node;
|
||||
hash_size_t hash;
|
||||
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 (node->data) {
|
||||
hashtblP->freefunc(node->data);
|
||||
}
|
||||
node->data=dataP;
|
||||
return HASH_TABLE_INSERT_OVERWRITTEN_DATA;
|
||||
}
|
||||
node=node->next;
|
||||
}
|
||||
if(!(node=malloc(sizeof(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;
|
||||
hashtblP->num_elements += 1;
|
||||
return HASH_TABLE_OK;
|
||||
node=hashtblP->nodes[hash];
|
||||
while(node) {
|
||||
if(node->key == keyP) {
|
||||
if (node->data) {
|
||||
hashtblP->freefunc(node->data);
|
||||
}
|
||||
node->data=dataP;
|
||||
return HASH_TABLE_INSERT_OVERWRITTEN_DATA;
|
||||
}
|
||||
node=node->next;
|
||||
}
|
||||
if(!(node=malloc(sizeof(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;
|
||||
hashtblP->num_elements += 1;
|
||||
return HASH_TABLE_OK;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
hashtbl_rc_t hashtbl_remove(hash_table_t *hashtblP, const uint64_t keyP)
|
||||
hashtable_rc_t hashtable_remove(hash_table_t *hashtblP, const uint64_t keyP)
|
||||
{
|
||||
hash_node_t *node, *prevnode=NULL;
|
||||
hash_size_t hash;
|
||||
hash_node_t *node, *prevnode=NULL;
|
||||
hash_size_t hash;
|
||||
|
||||
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;
|
||||
if (node->data) {
|
||||
hashtblP->freefunc(node->data);
|
||||
}
|
||||
free(node);
|
||||
hashtblP->num_elements -= 1;
|
||||
return HASH_TABLE_OK;
|
||||
}
|
||||
prevnode=node;
|
||||
node=node->next;
|
||||
}
|
||||
return HASH_TABLE_KEY_NOT_EXISTS;
|
||||
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;
|
||||
if (node->data) {
|
||||
hashtblP->freefunc(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.
|
||||
* NULL is returned if we didn't find it.
|
||||
*/
|
||||
hashtbl_rc_t hashtbl_get(hash_table_t *hashtblP, const uint64_t keyP, void** dataP)
|
||||
hashtable_rc_t hashtable_get(hash_table_t *hashtblP, const uint64_t keyP, void** dataP)
|
||||
{
|
||||
hash_node_t *node;
|
||||
hash_size_t hash;
|
||||
hash_node_t *node;
|
||||
hash_size_t hash;
|
||||
|
||||
if (hashtblP == NULL) {
|
||||
*dataP = NULL;
|
||||
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
||||
}
|
||||
hash=hashtblP->hashfunc(keyP)%hashtblP->size;
|
||||
/* fprintf(stderr, "hashtbl_get() key=%s, hash=%d\n", key, hash);*/
|
||||
if (hashtblP == NULL) {
|
||||
*dataP = NULL;
|
||||
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
||||
}
|
||||
hash=hashtblP->hashfunc(keyP)%hashtblP->size;
|
||||
/* fprintf(stderr, "hashtable_get() key=%s, hash=%d\n", key, hash);*/
|
||||
|
||||
node=hashtblP->nodes[hash];
|
||||
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;
|
||||
while(node) {
|
||||
if(node->key == keyP) {
|
||||
*dataP = node->data;
|
||||
return HASH_TABLE_OK;
|
||||
}
|
||||
node=node->next;
|
||||
}
|
||||
*dataP = NULL;
|
||||
return HASH_TABLE_KEY_NOT_EXISTS;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
@@ -240,40 +246,40 @@ hashtbl_rc_t hashtbl_get(hash_table_t *hashtblP, const uint64_t keyP, void** dat
|
||||
* 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.
|
||||
* We create a temporary hash_table_t object (newtbl) to be used while building the new hashes.
|
||||
* This allows us to reuse hashtbl_insert() and hashtbl_remove(), when moving the elements to the new table.
|
||||
* This allows us to reuse hashtable_insert() and hashtable_remove(), 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.
|
||||
*/
|
||||
|
||||
hashtbl_rc_t hashtbl_resize(hash_table_t *hashtblP, hash_size_t sizeP)
|
||||
hashtable_rc_t hashtable_resize(hash_table_t *hashtblP, hash_size_t sizeP)
|
||||
{
|
||||
hash_table_t newtbl;
|
||||
hash_size_t n;
|
||||
hash_node_t *node,*next;
|
||||
hash_table_t newtbl;
|
||||
hash_size_t n;
|
||||
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(hash_node_t*)))) return -1;
|
||||
if(!(newtbl.nodes=calloc(sizeP, sizeof(hash_node_t*)))) return -1;
|
||||
|
||||
for(n=0; n<hashtblP->size; ++n) {
|
||||
for(node=hashtblP->nodes[n]; node; node=next) {
|
||||
next = node->next;
|
||||
hashtbl_insert(&newtbl, node->key, node->data);
|
||||
// Lionel GAUTHIER: BAD CODE TO BE REWRITTEN
|
||||
hashtbl_remove(hashtblP, node->key);
|
||||
for(n=0; n<hashtblP->size; ++n) {
|
||||
for(node=hashtblP->nodes[n]; node; node=next) {
|
||||
next = node->next;
|
||||
hashtable_insert(&newtbl, node->key, node->data);
|
||||
// Lionel GAUTHIER: BAD CODE TO BE REWRITTEN
|
||||
hashtable_remove(hashtblP, node->key);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,44 +1,46 @@
|
||||
#ifndef _HASH_TABLE_H_
|
||||
#define _HASH_TABLE_H_
|
||||
#ifndef _UTILS_COLLECTION_HASH_TABLE_H_
|
||||
#define _UTILS_COLLECTION_HASH_TABLE_H_
|
||||
#include<stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
typedef size_t hash_size_t;
|
||||
|
||||
typedef enum hashtbl_return_code_e {
|
||||
typedef enum hashtable_return_code_e {
|
||||
HASH_TABLE_OK = 0,
|
||||
HASH_TABLE_INSERT_OVERWRITTEN_DATA = 1,
|
||||
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
|
||||
} hashtbl_rc_t;
|
||||
} hashtable_rc_t;
|
||||
|
||||
|
||||
typedef struct hash_node_s {
|
||||
uint64_t key;
|
||||
void *data;
|
||||
struct hash_node_s *next;
|
||||
uint64_t key;
|
||||
void *data;
|
||||
struct hash_node_s *next;
|
||||
} hash_node_t;
|
||||
|
||||
typedef struct hash_table_s {
|
||||
hash_size_t size;
|
||||
hash_size_t num_elements;
|
||||
struct hash_node_s **nodes;
|
||||
hash_size_t (*hashfunc)(const uint64_t);
|
||||
void (*freefunc)(void*);
|
||||
hash_size_t size;
|
||||
hash_size_t num_elements;
|
||||
struct hash_node_s **nodes;
|
||||
hash_size_t (*hashfunc)(const uint64_t);
|
||||
void (*freefunc)(void*);
|
||||
} hash_table_t;
|
||||
|
||||
char* hashtble_rc_code2string(hashtbl_rc_t rcP);
|
||||
hash_table_t *hashtbl_create (hash_size_t size, hash_size_t (*hashfunc)(const uint64_t ), void (*freefunc)(void*));
|
||||
hashtbl_rc_t hashtbl_destroy(hash_table_t *hashtbl);
|
||||
hashtbl_rc_t hashtbl_is_key_exists (hash_table_t *hashtbl, const uint64_t key);
|
||||
hashtbl_rc_t hashtbl_apply_funct_on_elements (hash_table_t *hashtblP, void funct(uint64_t keyP, void* dataP, void* parameterP), void* parameterP);
|
||||
hashtbl_rc_t hashtbl_insert (hash_table_t *hashtbl, const uint64_t key, void *data);
|
||||
hashtbl_rc_t hashtbl_remove (hash_table_t *hashtbl, const uint64_t key);
|
||||
hashtbl_rc_t hashtbl_get (hash_table_t *hashtbl, const uint64_t key, void **dataP);
|
||||
hashtbl_rc_t hashtbl_resize (hash_table_t *hashtbl, hash_size_t size);
|
||||
char* hashtable_rc_code2string(hashtable_rc_t rcP);
|
||||
void hash_free_int_func(void* memoryP);
|
||||
hash_table_t *hashtable_create (hash_size_t size, hash_size_t (*hashfunc)(const uint64_t ), void (*freefunc)(void*));
|
||||
hashtable_rc_t hashtable_destroy(hash_table_t *hashtbl);
|
||||
hashtable_rc_t hashtable_is_key_exists (hash_table_t *hashtbl, const uint64_t key);
|
||||
hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t *hashtblP, void funct(uint64_t keyP, void* dataP, void* parameterP), void* parameterP);
|
||||
hashtable_rc_t hashtable_insert (hash_table_t *hashtbl, const uint64_t key, void *data);
|
||||
hashtable_rc_t hashtable_remove (hash_table_t *hashtbl, const uint64_t key);
|
||||
hashtable_rc_t hashtable_get (hash_table_t *hashtbl, const uint64_t key, void **dataP);
|
||||
hashtable_rc_t hashtable_resize (hash_table_t *hashtbl, hash_size_t size);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -8,189 +8,221 @@
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
* Default hash function
|
||||
* def_hashfunc() is the default used by hashtbl_create() when the user didn't specify one.
|
||||
* def_hashfunc() is the default used by hashtable_create() when the user didn't specify one.
|
||||
* This is a simple/naive hash function which adds the key's ASCII char values. It will probably generate lots of collisions on large hash tables.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
* Initialisation
|
||||
* hashtbl_create() sets up the initial structure of the hash table. The user specified size will be allocated and initialized to NULL.
|
||||
* hashtable_create() sets up the initial structure of the hash table. The user specified size will be allocated and initialized to NULL.
|
||||
* The user can also specify a hash function. If the hashfunc argument is NULL, a default hash function is used.
|
||||
* If an error occurred, NULL is returned. All other values in the returned obj_hash_table_t pointer should be released with hashtbl_destroy().
|
||||
* If an error occurred, NULL is returned. All other values in the returned obj_hash_table_t pointer should be released with hashtable_destroy().
|
||||
*/
|
||||
obj_hash_table_t *obj_hashtbl_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*)))) {
|
||||
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;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
* Cleanup
|
||||
* The hashtbl_destroy() walks through the linked lists for each possible hash value, and releases the elements. It also releases the nodes array and the obj_hash_table_t.
|
||||
* The hashtable_destroy() walks through the linked lists for each possible hash value, and releases the elements. It also releases the nodes array and the obj_hash_table_t.
|
||||
*/
|
||||
hashtbl_rc_t obj_hashtbl_destroy(obj_hash_table_t *hashtblP)
|
||||
hashtable_rc_t obj_hashtable_destroy(obj_hash_table_t *hashtblP)
|
||||
{
|
||||
hash_size_t n;
|
||||
obj_hash_node_t *node, *oldnode;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
hashtbl_rc_t obj_hashtbl_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;
|
||||
hash_size_t hash;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
* Adding a new element
|
||||
* To make sure the hash value is not bigger than size, the result of the user provided hash function is used modulo size.
|
||||
*/
|
||||
hashtbl_rc_t obj_hashtbl_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;
|
||||
hash_size_t hash;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
hashtbl_rc_t obj_hashtbl_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;
|
||||
hash_size_t hash;
|
||||
obj_hash_node_t *node, *prevnode=NULL;
|
||||
hash_size_t hash;
|
||||
|
||||
if (hashtblP == NULL) {
|
||||
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
* Searching for an element is easy. We just search through the linked list for the corresponding hash value.
|
||||
* NULL is returned if we didn't find it.
|
||||
*/
|
||||
hashtbl_rc_t obj_hashtbl_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;
|
||||
hash_size_t hash;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
/*
|
||||
@@ -200,38 +232,37 @@ hashtbl_rc_t obj_hashtbl_get(obj_hash_table_t *hashtblP, const void* keyP, int k
|
||||
* 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.
|
||||
* We create a temporary obj_hash_table_t object (newtbl) to be used while building the new hashes.
|
||||
* This allows us to reuse hashtbl_insert() and hashtbl_remove(), when moving the elements to the new table.
|
||||
* This allows us to reuse hashtable_insert() and hashtable_remove(), 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.
|
||||
*/
|
||||
hashtbl_rc_t obj_hashtbl_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;
|
||||
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_hashtbl_insert(&newtbl, node->key, node->key_size, node->data);
|
||||
//WARNING Lionel GAUTHIER: BAD CODE TO BE REWRITTEN
|
||||
obj_hashtbl_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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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_hashtbl_create (hash_size_t size, hash_size_t (*hashfunc)(const void*, int ), void (*freekeyfunc)(void*), void (*freedatafunc)(void*));
|
||||
hashtbl_rc_t obj_hashtbl_destroy(obj_hash_table_t *hashtblP);
|
||||
hashtbl_rc_t obj_hashtbl_is_key_exists (obj_hash_table_t *hashtblP, void* keyP, int key_sizeP);
|
||||
hashtbl_rc_t obj_hashtbl_insert (obj_hash_table_t *hashtblP, void* keyP, int key_sizeP, void *dataP);
|
||||
hashtbl_rc_t obj_hashtbl_remove (obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP);
|
||||
hashtbl_rc_t obj_hashtbl_get (obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP, void ** dataP);
|
||||
hashtbl_rc_t obj_hashtbl_resize (obj_hash_table_t *hashtblP, hash_size_t sizeP);
|
||||
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_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