[asterisk-commits] murf: branch murf/datastructs r80538 - in /team/murf/datastructs: funcs/ incl...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Aug 23 14:11:44 CDT 2007


Author: murf
Date: Thu Aug 23 14:11:43 2007
New Revision: 80538

URL: http://svn.digium.com/view/asterisk?view=rev&rev=80538
Log:
First pass at converting the HASH funcs to use hashtab underneath. On a datastore. Compiles, but not even tried to run it yet. Later.

Modified:
    team/murf/datastructs/funcs/func_hashtab.c
    team/murf/datastructs/funcs/func_strings.c
    team/murf/datastructs/include/asterisk/hashtab.h
    team/murf/datastructs/main/hashtab.c

Modified: team/murf/datastructs/funcs/func_hashtab.c
URL: http://svn.digium.com/view/asterisk/team/murf/datastructs/funcs/func_hashtab.c?view=diff&rev=80538&r1=80537&r2=80538
==============================================================================
--- team/murf/datastructs/funcs/func_hashtab.c (original)
+++ team/murf/datastructs/funcs/func_hashtab.c Thu Aug 23 14:11:43 2007
@@ -322,7 +322,7 @@
 
 	ht = (struct ast_hashtab*)strtoul(args.handle, NULL, 10);
 	
-	ast_hashtab_destroy(ht);
+	ast_hashtab_destroy(ht,0); /* TODO: double check this: are we leaking the objects? */
 	
 	buf[0] = 0;
 	return 0;

Modified: team/murf/datastructs/funcs/func_strings.c
URL: http://svn.digium.com/view/asterisk/team/murf/datastructs/funcs/func_strings.c?view=diff&rev=80538&r1=80537&r2=80538
==============================================================================
--- team/murf/datastructs/funcs/func_strings.c (original)
+++ team/murf/datastructs/funcs/func_strings.c Thu Aug 23 14:11:43 2007
@@ -44,6 +44,7 @@
 #include "asterisk/app.h"
 #include "asterisk/localtime.h"
 #include "asterisk/options.h"
+#include "asterisk/hashtab.h"
 
 static int function_fieldqty(struct ast_channel *chan, const char *cmd,
 			     char *parse, char *buf, size_t len)
@@ -173,9 +174,81 @@
 	.read = regex,
 };
 
-#define HASH_PREFIX	"~HASH~%s~"
-#define HASH_FORMAT	HASH_PREFIX "%s~"
-
+#define HASH_PREFIX	"%s~"
+#define HASH_FORMAT	HASH_PREFIX "%s"
+
+struct hashvar
+{
+	char *name;
+	char *val;
+};
+
+static int func_HASH_COMPARE(const void *a, const void *b)
+{
+	const struct hashvar *aa = a;
+	const struct hashvar *bb = b;
+	return strcmp(aa->name, bb->name);
+}
+
+static int func_HASH_RESIZE(struct ast_hashtab *tab)
+{
+	return ast_hashtab_resize_java(tab);
+}
+
+static int func_HASH_NEWSIZE(struct ast_hashtab *tab)
+{
+	return ast_hashtab_newsize_java(tab);
+}
+
+static int func_HASH_HASH(const void *obj, int modulus)
+{
+	return ast_hashtab_hash_string(obj, modulus); /* the standard, case-sensitive hash */
+}
+
+static void destroy_hashvar(void *vobj)
+{
+	struct hashvar *obj = vobj;
+	if (obj->name)
+		free(obj->name);
+	if (obj->val)
+		free(obj->val);
+	obj->name = obj->val = 0;
+	free (obj);
+}
+
+static void *dup_hashvar(const void *vobj)
+{
+	const struct hashvar *obj = vobj;
+	struct hashvar *hv_found = ast_calloc(sizeof(struct hashvar),1);
+	hv_found->name = ast_malloc(strlen(obj->name)+1);
+	if (hv_found->name)
+		strcpy(hv_found->name, obj->name);
+	if (hv_found->val)
+		hv_found->val = ast_malloc(strlen(obj->val)+1);
+	strcpy(hv_found->val, obj->val);
+	return hv_found;
+}
+
+static void destroy_hashtab(void *data)
+{
+	struct ast_hashtab *tab = data;
+	ast_hashtab_destroy(tab, destroy_hashvar);
+}
+
+static void * dup_hashtab(void *data)
+{
+	return ast_hashtab_dup((struct ast_hashtab *)data, dup_hashvar);
+}
+
+
+struct ast_datastore_info hashtab_info = 
+{
+	.type = "HASH func table",
+	.duplicate = dup_hashtab,
+	.destroy = destroy_hashtab
+};
+
+	
 static char *app_clearhash = "ClearHash";
 static char *syn_clearhash = "Clear the keys from a specified hashname";
 static char *desc_clearhash =
@@ -271,6 +344,7 @@
 	struct ast_var_t *newvar;
 	int plen;
 	char prefix[80];
+
 	snprintf(prefix, sizeof(prefix), HASH_PREFIX, data);
 	plen = strlen(prefix);
 
@@ -291,6 +365,10 @@
 static int hash_write(struct ast_channel *chan, const char *cmd, char *var, const char *value)
 {
 	char varname[256];
+	struct hashvar hv, *hv_found;
+	struct ast_datastore *dstor;
+	struct ast_hashtab *tab;
+	
 	AST_DECLARE_APP_ARGS(arg,
 		AST_APP_ARG(hashname);
 		AST_APP_ARG(hashkey);
@@ -300,11 +378,34 @@
 		/* Single argument version */
 		return array(chan, "HASH", var, value);
 	}
-
+	
 	AST_STANDARD_APP_ARGS(arg, var);
+	
+	dstor = ast_channel_datastore_find(chan, &hashtab_info,NULL);
+	if (!dstor) {
+		dstor = ast_channel_datastore_alloc(&hashtab_info, "uid");
+		dstor->data = ast_hashtab_create(11, func_HASH_COMPARE, func_HASH_RESIZE, func_HASH_NEWSIZE, func_HASH_HASH, 0);
+		ast_channel_datastore_add(chan, dstor);
+	}
+	tab = dstor->data;
 	snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey);
-	pbx_builtin_setvar_helper(chan, varname, value);
-
+
+	hv.name = varname;
+	hv.val = 0;
+	hv_found = ast_hashtab_lookup(tab, &hv);
+	if (hv_found) { /* already in table, just change the value */
+		if (hv_found->val)
+			free(hv_found->val);
+		hv_found->val = ast_malloc(strlen(value)+1);
+		strcpy(hv_found->val, value);
+	} else { /* put it in the table */
+		hv_found = ast_calloc(sizeof(struct hashvar),1);
+		hv_found->name = ast_malloc(strlen(varname)+1);
+		strcpy(hv_found->name, varname);
+		hv_found->val = ast_malloc(strlen(value)+1);
+		strcpy(hv_found->val, value);
+		ast_hashtab_insert_immediate(tab, hv_found);
+	}
 	return 0;
 }
 
@@ -312,6 +413,9 @@
 {
 	char varname[256];
 	const char *varvalue;
+	struct hashvar hv, *hv_found;
+	struct ast_datastore *dstor;
+	struct ast_hashtab *tab;
 	AST_DECLARE_APP_ARGS(arg,
 		AST_APP_ARG(hashname);
 		AST_APP_ARG(hashkey);
@@ -319,12 +423,22 @@
 
 	AST_STANDARD_APP_ARGS(arg, data);
 	if (arg.argc == 2) {
+		dstor = ast_channel_datastore_find(chan, &hashtab_info,NULL);
+		if (!dstor) { /* not even the datastore was found */
+			*buf = 0;
+			return 0;
+		}
+		tab = dstor->data;
 		snprintf(varname, sizeof(varname), HASH_FORMAT, arg.hashname, arg.hashkey);
-		varvalue = pbx_builtin_getvar_helper(chan, varname);
-		if (varvalue)
-			ast_copy_string(buf, varvalue, len);
-		else
-			*buf = '\0';
+		hv.name = varname;
+		hv.val = 0;
+		hv_found = ast_hashtab_lookup(tab, &hv);
+		if (hv_found) { /* in table, just copy the value */
+			if (hv_found->val)
+				ast_copy_string(buf, hv_found->val, len);
+			else
+				*buf = '\0';
+		}
 	} else if (arg.argc == 1) {
 		char colnames[4096];
 		int i;

Modified: team/murf/datastructs/include/asterisk/hashtab.h
URL: http://svn.digium.com/view/asterisk/team/murf/datastructs/include/asterisk/hashtab.h?view=diff&rev=80538&r1=80537&r2=80538
==============================================================================
--- team/murf/datastructs/include/asterisk/hashtab.h (original)
+++ team/murf/datastructs/include/asterisk/hashtab.h Thu Aug 23 14:11:43 2007
@@ -163,7 +163,7 @@
 
 	/* this func will free the hash table and all its memory. It
 	   doesn't touch the objects stored in it */
-void ast_hashtab_destroy( struct ast_hashtab *tab);
+void ast_hashtab_destroy( struct ast_hashtab *tab, void (*objdestroyfunc)(void *obj));
 
 
 	/* normally, you'd insert "safely" by checking to see if the element is
@@ -200,6 +200,9 @@
 	/* this function returns the size of the bucket array in the hashtab */
 int  ast_hashtab_capacity( struct ast_hashtab *tab);
 
+    /* this function will return a copy of the table */
+struct ast_hashtab *ast_hashtab_dup(struct ast_hashtab *tab, void *(*obj_dup_func)(const void *obj));
+
 	/* returns an iterator */
 struct ast_hashtab_iter *ast_hashtab_start_traversal(struct ast_hashtab *tab);
 

Modified: team/murf/datastructs/main/hashtab.c
URL: http://svn.digium.com/view/asterisk/team/murf/datastructs/main/hashtab.c?view=diff&rev=80538&r1=80537&r2=80538
==============================================================================
--- team/murf/datastructs/main/hashtab.c (original)
+++ team/murf/datastructs/main/hashtab.c Thu Aug 23 14:11:43 2007
@@ -243,6 +243,38 @@
 	return ht;
 }
 
+struct ast_hashtab *ast_hashtab_dup(struct ast_hashtab *tab, void *(*obj_dup_func)(const void *obj))
+{
+	struct ast_hashtab *ht = ast_calloc(1,sizeof(struct ast_hashtab));
+	int i;
+	
+	ht->array = ast_calloc(tab->hash_tab_size,sizeof(struct ast_hashtab_bucket*));
+	ht->hash_tab_size = tab->hash_tab_size;
+	ht->compare = tab->compare;
+	ht->resize = tab->resize;
+	ht->newsize = tab->newsize;
+	ht->hash = tab->hash;
+	ht->do_locking = tab->do_locking;
+	if (ht->do_locking)
+		ast_rwlock_init(&ht->lock);
+	/* now, dup the objects in the buckets and get them into the table */
+	/* the fast way is to use the existing array index, and not have to hash
+	   the objects again */
+	for (i=0;i<ht->hash_tab_size;i++)
+	{
+		struct ast_hashtab_bucket *b = tab->array[i];
+		while( b )
+		{
+			void *newobj = (*obj_dup_func)(b->object);
+			if (newobj) {
+				ast_hashtab_insert_immediate_bucket(ht, newobj, i);
+			}
+			b = b->next;
+		}
+	}
+	return ht;
+}
+
 static void tlist_del_item(struct ast_hashtab_bucket **head, struct ast_hashtab_bucket *item)
 {
 	/* item had better be in the list! or suffer the weirdness that occurs, later! */
@@ -302,7 +334,7 @@
 }
 
 
-void ast_hashtab_destroy( struct ast_hashtab *tab)
+void ast_hashtab_destroy( struct ast_hashtab *tab, void (*objdestroyfunc)(void *obj))
 {
 	/* this func will free the hash table and all its memory. It
 	   doesn't touch the objects stored in it */
@@ -318,6 +350,10 @@
 			
 			while (tab->tlist) {
 				t = tab->tlist;
+				if (t->object && objdestroyfunc) {
+					(*objdestroyfunc)((void*)t->object); /* I cast this because I'm not going to MOD it, I'm going to DESTROY it */
+				}
+				
 				tlist_del_item(&(tab->tlist), tab->tlist);
 				free(t);
 			}




More information about the asterisk-commits mailing list