aboutsummaryrefslogtreecommitdiffstats
path: root/main/hashtab.c
diff options
context:
space:
mode:
authormurf <murf@f38db490-d61c-443f-a65b-d21fe96a405b>2007-11-26 17:26:01 +0000
committermurf <murf@f38db490-d61c-443f-a65b-d21fe96a405b>2007-11-26 17:26:01 +0000
commitbbd5a3d02e93f5c3ab828f8d37fcfcf610563894 (patch)
treeeccb6f83186742b9bdbb144dcd7d0df67fca67e9 /main/hashtab.c
parente09e950389351ad49d30a55be2026c443afcca7a (diff)
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
Diffstat (limited to 'main/hashtab.c')
-rw-r--r--main/hashtab.c67
1 files changed, 33 insertions, 34 deletions
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;
}