[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