[svn-commits] murf: branch murf/fast-ast r47729 - /team/murf/fast-ast/main/

svn-commits at lists.digium.com svn-commits at lists.digium.com
Thu Nov 16 07:35:09 MST 2006


Author: murf
Date: Thu Nov 16 08:35:09 2006
New Revision: 47729

URL: http://svn.digium.com/view/asterisk?view=rev&rev=47729
Log:
hashtab and strtab now working with rwlocks

Modified:
    team/murf/fast-ast/main/hashtab.c
    team/murf/fast-ast/main/stringtab.c

Modified: team/murf/fast-ast/main/hashtab.c
URL: http://svn.digium.com/view/asterisk/team/murf/fast-ast/main/hashtab.c?view=diff&rev=47729&r1=47728&r2=47729
==============================================================================
--- team/murf/fast-ast/main/hashtab.c (original)
+++ team/murf/fast-ast/main/hashtab.c Thu Nov 16 08:35:09 2006
@@ -212,7 +212,8 @@
 	ht->newsize = newsize;
 	ht->hash = hash;
 	ht->do_locking = do_locking;
-	ast_rwlock_init(&ht->lock);
+	if (do_locking)
+		ast_rwlock_init(&ht->lock);
 	if (!ht->resize)
 		ht->resize = ast_hashtab_resize_java;
 	if (!ht->newsize)
@@ -288,15 +289,50 @@
 	return 1;
 }
 
+int ast_hashtab_insert_immediate_bucket(struct ast_hashtab *tab, const void *obj, int h)
+{
+	/* normally, you'd insert "safely" by checking to see if the element is
+	   already there; in this case, you must already have checked. If an element
+	   is already in the hashtable, that matches this one, most likely this one
+	   will be found first, but.... */
+
+	/* will force a resize if the resize func returns 1 */
+	/* returns 1 on success, 0 if there's a problem */
+	int c;
+	struct ast_hashtab_bucket *b;
+	
+	if (!tab || !obj)
+		return 0;
+	if (tab->do_locking)
+		ast_rwlock_wrlock(&tab->lock);
+	
+	for (c=0,b=tab->array[h];b;b=b->next) {
+		c++;
+	}
+	if (c+1 > tab->largest_bucket_size)
+		tab->largest_bucket_size = c+1;
+	b = ast_malloc(sizeof(struct ast_hashtab_bucket));
+	b->object = obj;
+	b->next = tab->array[h];
+	tab->array[h] = b;
+	tab->hash_tab_elements++;
+	if ((*tab->resize)(tab))
+		ast_hashtab_resize(tab);
+	if (tab->do_locking)
+		ast_rwlock_unlock(&tab->lock);
+	return 1;
+}
+
 int ast_hashtab_insert_safe(struct ast_hashtab *tab, const void *obj)
 {
 	/* check to see if the element is already there; insert only if
 	   it is not there. */
 	/* will force a resize if the resize func returns 1 */
 	/* returns 1 on success, 0 if there's a problem, or it's already there. */
-	if (ast_hashtab_lookup(tab,obj) == 0)
-	{
-		return ast_hashtab_insert_immediate(tab,obj);
+	int bucket;
+	if (ast_hashtab_lookup_bucket(tab,obj,&bucket) == 0)
+	{
+		return ast_hashtab_insert_immediate_bucket(tab,obj,bucket);
 	}
 	return 0;
 }
@@ -312,14 +348,40 @@
 	if (tab->do_locking)
 		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) == 0 )
+	for(b=tab->array[h]; b; b=b->next) {
+		if( (*tab->compare)(obj,b->object) == 0 ) {
+			if (tab->do_locking)
+				ast_rwlock_unlock(&tab->lock);
 			return (void*)b->object; /* I can't touch obj in this func, but the outside world is welcome to */
-	}
-	if (tab->do_locking)
-		ast_rwlock_unlock(&tab->lock);
-
+		}
+	}
+	if (tab->do_locking)
+		ast_rwlock_unlock(&tab->lock);
+
+	return 0;
+}
+
+void * ast_hashtab_lookup_bucket(struct ast_hashtab *tab, const void *obj, int *bucket)
+{
+	/* lookup this object in the hash table. return a ptr if found, or NULL if not */
+	int h;
+	struct ast_hashtab_bucket *b;
+	if (!tab || !obj)
+		return 0;
+	
+	if (tab->do_locking)
+		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) == 0 ) {
+			if (tab->do_locking)
+				ast_rwlock_unlock(&tab->lock);
+			return (void*)b->object; /* I can't touch obj in this func, but the outside world is welcome to */
+		}
+	}
+	if (tab->do_locking)
+		ast_rwlock_unlock(&tab->lock);
+	*bucket = h;
 	return 0;
 }
 
@@ -473,6 +535,8 @@
 			obj2 = b->object;
 			b->object = b->next = 0;
 			free(b); /* free up the hashbucket */
+			if (tab->do_locking)
+				ast_rwlock_unlock(&tab->lock);
 			return (void*)obj2; /* inside this code, the obj's are untouchable, but outside, they aren't */
 		}
 		last = b;
@@ -509,6 +573,8 @@
 			obj2 = b->object;
 			b->object = b->next = 0;
 			free(b); /* free up the hashbucket */
+			if (tab->do_locking)
+				ast_rwlock_unlock(&tab->lock);
 			return (void*)obj2; /* inside this code, the obj's are untouchable, but outside, they aren't */
 		}
 		last = b;

Modified: team/murf/fast-ast/main/stringtab.c
URL: http://svn.digium.com/view/asterisk/team/murf/fast-ast/main/stringtab.c?view=diff&rev=47729&r1=47728&r2=47729
==============================================================================
--- team/murf/fast-ast/main/stringtab.c (original)
+++ team/murf/fast-ast/main/stringtab.c Thu Nov 16 08:35:09 2006
@@ -95,7 +95,7 @@
 const char *st_insert(struct ast_strtab *tab, const char *str)
 {
 	char *newstr;
-	int len;
+	int len,bucket;
 	char *z;
 
 	if (!str)
@@ -105,10 +105,11 @@
 
 	len = strlen(str)+1;
 	ast_rwlock_wrlock(&tab->lock);
-	z = (char*)ast_hashtab_lookup(tab->ht, str);
+	z = (char*)ast_hashtab_lookup_bucket(tab->ht, str, &bucket);
 	tab->lookups++; /* this should probably get locked, but it's not super-critical */
 	
 	if (z) {
+		ast_rwlock_unlock(&tab->lock);
 		return z;
 	} else {
 		/* this string aint in there; lets' put it in the buffer */
@@ -133,7 +134,7 @@
 		/* now that we have it stored away, and have a string we can point to,
 		   let's put it in the hash tab. */
 
-		ast_hashtab_insert_immediate(tab->ht, newstr);
+		ast_hashtab_insert_immediate_bucket(tab->ht, newstr, bucket);
 		ast_rwlock_unlock(&tab->lock);
 		return newstr;
 	}



More information about the svn-commits mailing list