closes issue #11356; Many thanks to snuffy for his code review and changes to cut down duplication. I tested this against hashtest, and it passes. I reviewed the changes, and they look reasonable. I had to remove a few const decls to make things compile on my workstation,
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@89591 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
parent
b1a8de2d40
commit
d3209e2ef2
|
@ -39,6 +39,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision")
|
|||
#include "asterisk/hashtab.h"
|
||||
|
||||
static void ast_hashtab_resize( struct ast_hashtab *tab);
|
||||
static void *ast_hashtab_lookup_internal(struct ast_hashtab *tab, const void *obj, unsigned int h);
|
||||
|
||||
/* some standard, default routines for general use */
|
||||
|
||||
|
@ -209,11 +210,11 @@ unsigned int ast_hashtab_hash_short(const short x)
|
|||
}
|
||||
|
||||
struct ast_hashtab *ast_hashtab_create(int initial_buckets,
|
||||
int (*compare)(const void *a, const void *b), /* a func to compare two elements in the hash -- cannot be null */
|
||||
int (*resize)(struct ast_hashtab *), /* a func to decide if the table needs to be resized, a NULL ptr here will cause a default to be used */
|
||||
int (*newsize)(struct ast_hashtab *tab), /* a ptr to func that returns a new size of the array. A NULL will cause a default to be used */
|
||||
unsigned int (*hash)(const void *obj), /* a func to do the hashing */
|
||||
int do_locking ) /* use locks to guarantee safety of iterators/insertion/deletion -- real simpleminded right now */
|
||||
int (*compare)(const void *a, const void *b),
|
||||
int (*resize)(struct ast_hashtab *),
|
||||
int (*newsize)(struct ast_hashtab *tab),
|
||||
unsigned int (*hash)(const void *obj),
|
||||
int do_locking)
|
||||
{
|
||||
struct ast_hashtab *ht;
|
||||
|
||||
|
@ -460,12 +461,11 @@ int ast_hashtab_insert_safe(struct ast_hashtab *tab, const void *obj)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void * ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj)
|
||||
void *ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj)
|
||||
{
|
||||
/* lookup this object in the hash table. return a ptr if found, or NULL if not */
|
||||
unsigned int h;
|
||||
const void *ret;
|
||||
struct ast_hashtab_bucket *b;
|
||||
void *ret;
|
||||
|
||||
if (!tab || !obj)
|
||||
return 0;
|
||||
|
@ -474,27 +474,21 @@ void * ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj)
|
|||
ast_rwlock_rdlock(&tab->lock);
|
||||
|
||||
h = (*tab->hash)(obj) % tab->hash_tab_size;
|
||||
for (b = tab->array[h]; b; b = b->next) {
|
||||
if (!(*tab->compare)(obj,b->object)) {
|
||||
ret = b->object;
|
||||
if (tab->do_locking)
|
||||
ast_rwlock_unlock(&tab->lock);
|
||||
return (void*) ret; /* I can't touch obj in this func, but the outside world is welcome to */
|
||||
}
|
||||
}
|
||||
|
||||
ret = ast_hashtab_lookup_internal(tab,obj,h);
|
||||
|
||||
if (tab->do_locking)
|
||||
ast_rwlock_unlock(&tab->lock);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void *ast_hashtab_lookup_with_hash(struct ast_hashtab *tab, const void *obj, unsigned int hashval)
|
||||
{
|
||||
/* lookup this object in the hash table. return a ptr if found, or NULL if not */
|
||||
unsigned int h;
|
||||
const void *ret;
|
||||
struct ast_hashtab_bucket *b;
|
||||
void *ret;
|
||||
|
||||
if (!tab || !obj)
|
||||
return 0;
|
||||
|
@ -503,38 +497,43 @@ void *ast_hashtab_lookup_with_hash(struct ast_hashtab *tab, const void *obj, uns
|
|||
ast_rwlock_rdlock(&tab->lock);
|
||||
|
||||
h = hashval % tab->hash_tab_size;
|
||||
for (b = tab->array[h]; b; b = b->next) {
|
||||
if (!(*tab->compare)(obj,b->object)) {
|
||||
ret = b->object;
|
||||
if (tab->do_locking)
|
||||
ast_rwlock_unlock(&tab->lock);
|
||||
return (void*) ret; /* I can't touch obj in this func, but the outside world is welcome to */
|
||||
}
|
||||
}
|
||||
|
||||
ret = ast_hashtab_lookup_internal(tab,obj,h);
|
||||
|
||||
if (tab->do_locking)
|
||||
ast_rwlock_unlock(&tab->lock);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void * ast_hashtab_lookup_bucket(struct ast_hashtab *tab, const void *obj, unsigned int *bucket)
|
||||
void *ast_hashtab_lookup_bucket(struct ast_hashtab *tab, const void *obj, unsigned int *bucket)
|
||||
{
|
||||
/* lookup this object in the hash table. return a ptr if found, or NULL if not */
|
||||
unsigned int h;
|
||||
struct ast_hashtab_bucket *b;
|
||||
void *ret;
|
||||
|
||||
if (!tab || !obj)
|
||||
return 0;
|
||||
|
||||
h = (*tab->hash)(obj) % tab->hash_tab_size;
|
||||
for (b = tab->array[h]; b; b = b->next) {
|
||||
if (!(*tab->compare)(obj,b->object))
|
||||
return (void*) b->object; /* I can't touch obj in this func, but the outside world is welcome to */
|
||||
}
|
||||
|
||||
ret = ast_hashtab_lookup_internal(tab,obj,h);
|
||||
|
||||
*bucket = h;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *ast_hashtab_lookup_internal(struct ast_hashtab *tab, const void *obj, unsigned int h)
|
||||
{
|
||||
struct ast_hashtab_bucket *b;
|
||||
|
||||
for (b = tab->array[h]; b; b = b->next) {
|
||||
if (!(*tab->compare)(obj,b->object)) {
|
||||
return (void*) b->object; /* I can't touch obj in this func, but the outside world is welcome to */
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue