From bbd5a3d02e93f5c3ab828f8d37fcfcf610563894 Mon Sep 17 00:00:00 2001 From: murf Date: Mon, 26 Nov 2007 17:26:01 +0000 Subject: 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: http://svn.digium.com/svn/asterisk/trunk@89591 f38db490-d61c-443f-a65b-d21fe96a405b --- main/hashtab.c | 67 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 34 deletions(-) (limited to 'main/hashtab.c') diff --git a/main/hashtab.c b/main/hashtab.c index 4c36bc19b..41e6b2ba7 100644 --- a/main/hashtab.c +++ b/main/hashtab.c @@ -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 */ @@ -208,12 +209,12 @@ unsigned int ast_hashtab_hash_short(const short x) return 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 */ +struct ast_hashtab *ast_hashtab_create(int initial_buckets, + 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; + + 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)) + 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 */ + } } - *bucket = h; - return 0; } -- cgit v1.2.3