mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	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:
		| @@ -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; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user