[asterisk-commits] murf: branch murf/fast-ast r47729 -
/team/murf/fast-ast/main/
asterisk-commits at lists.digium.com
asterisk-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 asterisk-commits
mailing list