Reindented server/core/hashtable.c
This commit is contained in:
@ -105,8 +105,7 @@ hashtable_alloc(int size, int (*hashfn)(), int (*cmpfn)())
|
||||
return hashtable_alloc_real(NULL, size, hashfn, cmpfn);
|
||||
}
|
||||
|
||||
HASHTABLE* hashtable_alloc_flat(
|
||||
HASHTABLE* target,
|
||||
HASHTABLE* hashtable_alloc_flat(HASHTABLE* target,
|
||||
int size,
|
||||
int (*hashfn)(),
|
||||
int (*cmpfn)())
|
||||
@ -115,8 +114,7 @@ HASHTABLE* hashtable_alloc_flat(
|
||||
}
|
||||
|
||||
static HASHTABLE *
|
||||
hashtable_alloc_real(
|
||||
HASHTABLE* target,
|
||||
hashtable_alloc_real(HASHTABLE* target,
|
||||
int size,
|
||||
int (*hashfn)(),
|
||||
int (*cmpfn)())
|
||||
@ -126,7 +124,9 @@ hashtable_alloc_real(
|
||||
if (target == NULL)
|
||||
{
|
||||
if ((rval = malloc(sizeof(HASHTABLE))) == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
rval->ht_isflat = false;
|
||||
}
|
||||
else
|
||||
@ -172,7 +172,9 @@ int i;
|
||||
HASHENTRIES *entry, *ptr;
|
||||
|
||||
if (table == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
hashtable_write_lock(table);
|
||||
for (i = 0; i < table->hashsize; i++)
|
||||
@ -208,22 +210,29 @@ HASHENTRIES *entry, *ptr;
|
||||
* @param vfreefn The free function for the value
|
||||
*/
|
||||
void
|
||||
hashtable_memory_fns(
|
||||
HASHTABLE *table,
|
||||
hashtable_memory_fns(HASHTABLE *table,
|
||||
HASHMEMORYFN kcopyfn,
|
||||
HASHMEMORYFN vcopyfn,
|
||||
HASHMEMORYFN kfreefn,
|
||||
HASHMEMORYFN vfreefn)
|
||||
{
|
||||
if (kcopyfn != NULL)
|
||||
{
|
||||
table->kcopyfn = kcopyfn;
|
||||
}
|
||||
if (vcopyfn != NULL)
|
||||
{
|
||||
table->vcopyfn = vcopyfn;
|
||||
}
|
||||
if (kfreefn != NULL)
|
||||
{
|
||||
table->kfreefn = kfreefn;
|
||||
}
|
||||
if (vfreefn != NULL)
|
||||
{
|
||||
table->vfreefn = vfreefn;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an item to the hash table.
|
||||
@ -240,11 +249,16 @@ hashtable_add(HASHTABLE *table, void *key, void *value)
|
||||
HASHENTRIES *entry;
|
||||
|
||||
if (table == NULL || key == NULL || value == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (table->hashsize <= 0) {
|
||||
if (table->hashsize <= 0)
|
||||
{
|
||||
return 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
hashkey = table->hashfn(key) % table->hashsize;
|
||||
}
|
||||
hashtable_write_lock(table);
|
||||
@ -272,7 +286,8 @@ hashtable_add(HASHTABLE *table, void *key, void *value)
|
||||
ptr->key = table->kcopyfn(key);
|
||||
|
||||
/* check succesfull key copy */
|
||||
if ( ptr->key == NULL) {
|
||||
if (ptr->key == NULL)
|
||||
{
|
||||
free(ptr);
|
||||
hashtable_write_unlock(table);
|
||||
|
||||
@ -283,7 +298,8 @@ hashtable_add(HASHTABLE *table, void *key, void *value)
|
||||
ptr->value = table->vcopyfn(value);
|
||||
|
||||
/* check succesfull value copy */
|
||||
if ( ptr->value == NULL) {
|
||||
if (ptr->value == NULL)
|
||||
{
|
||||
/* remove the key ! */
|
||||
table->kfreefn(ptr->key);
|
||||
free(ptr);
|
||||
@ -317,7 +333,9 @@ unsigned int hashkey;
|
||||
HASHENTRIES *entry, *ptr;
|
||||
|
||||
if (table == NULL || key == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
hashkey = table->hashfn(key) % table->hashsize;
|
||||
hashtable_write_lock(table);
|
||||
@ -340,10 +358,13 @@ HASHENTRIES *entry, *ptr;
|
||||
table->kfreefn(entry->key);
|
||||
table->vfreefn(entry->value);
|
||||
|
||||
if (entry->next != NULL) {
|
||||
if (entry->next != NULL)
|
||||
{
|
||||
entry->key = entry->next->key;
|
||||
entry->value = entry->next->value;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->key = NULL;
|
||||
entry->value = NULL;
|
||||
}
|
||||
@ -353,7 +374,9 @@ HASHENTRIES *entry, *ptr;
|
||||
{
|
||||
ptr = table->entries[hashkey % table->hashsize];
|
||||
while (ptr && ptr->next != entry)
|
||||
{
|
||||
ptr = ptr->next;
|
||||
}
|
||||
if (ptr == NULL)
|
||||
{
|
||||
hashtable_write_unlock(table);
|
||||
@ -384,7 +407,9 @@ unsigned int hashkey;
|
||||
HASHENTRIES *entry;
|
||||
|
||||
if (table == NULL || key == NULL || 0 == table->hashsize)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hashkey = table->hashfn(key) % table->hashsize;
|
||||
hashtable_read_lock(table);
|
||||
@ -417,7 +442,9 @@ int total, longest, i, j;
|
||||
HASHENTRIES *entries;
|
||||
|
||||
if (table == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Hashtable: %p, size %d\n", table, table->hashsize);
|
||||
total = 0;
|
||||
@ -462,8 +489,7 @@ HASHENTRIES *entries;
|
||||
*
|
||||
*
|
||||
*/
|
||||
void hashtable_get_stats(
|
||||
void* table,
|
||||
void hashtable_get_stats(void* table,
|
||||
int* hashsize,
|
||||
int* nelems,
|
||||
int* longest)
|
||||
@ -493,7 +519,8 @@ void hashtable_get_stats(
|
||||
entries = entries->next;
|
||||
}
|
||||
*nelems += j;
|
||||
if (j > *longest) {
|
||||
if (j > *longest)
|
||||
{
|
||||
*longest = j;
|
||||
}
|
||||
}
|
||||
@ -529,7 +556,9 @@ hashtable_read_lock(HASHTABLE *table)
|
||||
{
|
||||
spinlock_release(&table->spin);
|
||||
while (table->writelock)
|
||||
{
|
||||
;
|
||||
}
|
||||
spinlock_acquire(&table->spin);
|
||||
}
|
||||
atomic_add(&table->n_readers, 1);
|
||||
@ -571,13 +600,19 @@ hashtable_write_lock(HASHTABLE *table)
|
||||
int available;
|
||||
|
||||
spinlock_acquire(&table->spin);
|
||||
do {
|
||||
do
|
||||
{
|
||||
while (table->n_readers)
|
||||
{
|
||||
;
|
||||
}
|
||||
available = atomic_add(&table->writelock, 1);
|
||||
if (available != 0)
|
||||
{
|
||||
atomic_add(&table->writelock, -1);
|
||||
} while (available != 0);
|
||||
}
|
||||
}
|
||||
while (available != 0);
|
||||
spinlock_release(&table->spin);
|
||||
}
|
||||
|
||||
@ -625,7 +660,9 @@ int i;
|
||||
HASHENTRIES *entries;
|
||||
|
||||
if (iter == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iter->depth++;
|
||||
while (iter->chain < iter->table->hashsize)
|
||||
|
@ -44,7 +44,8 @@
|
||||
* A NULL value for key indicates an empty entry.
|
||||
* The next pointer is the overflow chain for this hashentry.
|
||||
*/
|
||||
typedef struct hashentry {
|
||||
typedef struct hashentry
|
||||
{
|
||||
void *key; /**< The value of the key or NULL if empty entry */
|
||||
void *value; /**< The value associated with key */
|
||||
struct hashentry *next; /**< The overflow chain */
|
||||
@ -54,9 +55,9 @@ typedef struct hashentry {
|
||||
* HASHTABLE iterator - used to walk the hashtable in a thread safe
|
||||
* way
|
||||
*/
|
||||
typedef struct hashiterator {
|
||||
struct hashtable
|
||||
*table; /**< The hashtable the iterator refers to */
|
||||
typedef struct hashiterator
|
||||
{
|
||||
struct hashtable *table; /**< The hashtable the iterator refers to */
|
||||
int chain; /**< The current chain we are walking */
|
||||
int depth; /**< The current depth down the chain */
|
||||
} HASHITERATOR;
|
||||
@ -69,7 +70,8 @@ typedef void *(*HASHMEMORYFN)(void *);
|
||||
/**
|
||||
* The general purpose hashtable struct.
|
||||
*/
|
||||
typedef struct hashtable {
|
||||
typedef struct hashtable
|
||||
{
|
||||
#if defined(SS_DEBUG)
|
||||
skygw_chk_t ht_chk_top;
|
||||
#endif
|
||||
@ -85,7 +87,7 @@ typedef struct hashtable {
|
||||
int n_readers; /**< Number of clients reading the table */
|
||||
int writelock; /**< The table is locked by a writer */
|
||||
bool ht_isflat; /**< Indicates whether hashtable is in stack or heap */
|
||||
int n_elements; /*< Number of added elements */
|
||||
int n_elements; /**< Number of added elements */
|
||||
#if defined(SS_DEBUG)
|
||||
skygw_chk_t ht_chk_tail;
|
||||
#endif
|
||||
@ -112,8 +114,7 @@ extern int hashtable_delete(HASHTABLE *, void *);
|
||||
extern void *hashtable_fetch(HASHTABLE *, void *);
|
||||
/**< Fetch the data for a given key */
|
||||
extern void hashtable_stats(HASHTABLE *); /**< Print statisitics */
|
||||
void hashtable_get_stats(
|
||||
void* hashtable,
|
||||
void hashtable_get_stats(void* hashtable,
|
||||
int* hashsize,
|
||||
int* nelems,
|
||||
int* longest);
|
||||
|
Reference in New Issue
Block a user