[asterisk-commits] murf: branch murf/fast-ast r47361 - in
/team/murf/fast-ast: include/asterisk/...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Thu Nov 9 06:38:43 MST 2006
Author: murf
Date: Thu Nov 9 07:38:43 2006
New Revision: 47361
URL: http://svn.digium.com/view/asterisk?view=rev&rev=47361
Log:
fixed the small prob last night, committing this so I can merge updates
Modified:
team/murf/fast-ast/include/asterisk/pbx.h
team/murf/fast-ast/main/pbx.c
Modified: team/murf/fast-ast/include/asterisk/pbx.h
URL: http://svn.digium.com/view/asterisk/team/murf/fast-ast/include/asterisk/pbx.h?view=diff&rev=47361&r1=47360&r2=47361
==============================================================================
--- team/murf/fast-ast/include/asterisk/pbx.h (original)
+++ team/murf/fast-ast/include/asterisk/pbx.h Thu Nov 9 07:38:43 2006
@@ -63,7 +63,7 @@
struct ast_sw;
/*! \brief Typedef for devicestate and hint callbacks */
-typedef int (*ast_state_cb_type)(char *context, char* id, enum ast_extension_states state, void *data);
+typedef int (*ast_state_cb_type)(const char *context, char* id, enum ast_extension_states state, void *data);
/*! \brief Data structure associated with a custom dialplan function */
struct ast_custom_function {
Modified: team/murf/fast-ast/main/pbx.c
URL: http://svn.digium.com/view/asterisk/team/murf/fast-ast/main/pbx.c?view=diff&rev=47361&r1=47360&r2=47361
==============================================================================
--- team/murf/fast-ast/main/pbx.c (original)
+++ team/murf/fast-ast/main/pbx.c Thu Nov 9 07:38:43 2006
@@ -62,6 +62,7 @@
#include "asterisk/devicestate.h"
#include "asterisk/stringfields.h"
#include "hashtab.h"
+#include "stringtab.h"
/*!
* \note I M P O R T A N T :
@@ -72,16 +73,24 @@
* of priorities, but a constant search time here would be great ;-)
*
* A new algorithm to do searching based on a 'compiled' pattern tree is introduced
- * here, and shows a fairly flat (constant) search time, even for as many as
- * 1000 patterns. Still needs some work-- doesn't handle matchcid yet, but
- * that's no big problem, it will not be difficult to add...
+ * here, and shows a fairly flat (constant) search time, even for over
+ * 1000 patterns. Still needs some work-- there are some fine points of the matching
+ * spec about tie-breaking based on the characters in character sets, but this
+ * should be do-able via the weight system currently being used.
*
* Also, using a hash table for context/priority name lookup can help prevent
- * the find_extension routines from absorbing exponential cpu cycles. Right now,
- * I'm using red-black balanced binary trees, log(n) search time.
+ * the find_extension routines from absorbing exponential cpu cycles. I've tested
+ * find_extension with red-black trees, which have O(log2(n)) speed.Right now,
+ * I'm using hash tables, which do searches (ideally) in O(1) time.
*
* A simple hack to prevent repetitive calls to find_extension when it isn't
* necessary has been added.
+ *
+ * A stringtable (where a buffer is provided to "intern" unique strings, which
+ * are accessed via a hashtable. When all strings are in a stringtable, you can
+ * test for string equality by just matching pointers. This could help in storage
+ * and speed. Might be a better alternative than stringfields in those situations
+ * where the strings are searched.
*
*/
@@ -207,7 +216,7 @@
const char *registrar; /*!< Registrar */
AST_LIST_HEAD_NOLOCK(, ast_sw) alts; /*!< Alternative switches */
ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
- char name[0]; /*!< Name of the context */
+ const char *name; /*!< Name of the context */
};
@@ -291,12 +300,13 @@
static int hashtab_hash_priority(const void *obj, int mod);
static int hashtab_hash_labels(const void *obj, int mod);
-/* labels, contexts are case sensitive prioritaahhy numbers are ints */
+/* labels, contexts are case sensitive priority numbers are ints */
static int hashtab_compare_contexts(const void *ah_a, const void *ah_b)
{
const struct ast_context *ac = ah_a;
const struct ast_context *bc = ah_b;
- return strcmp(ac->name, bc->name);
+ /* assume context names are registered in a string table! */
+ return ac->name != bc->name;
}
static int hashtab_compare_extens(const void *ah_a, const void *ah_b)
@@ -317,7 +327,7 @@
{
const struct ast_exten *ac = ah_a;
const struct ast_exten *bc = ah_b;
- return strcmp(ac->label, bc->label);
+ return ac->label != bc->label;
}
static int hashtab_hash_contexts(const void *obj, int mod)
@@ -567,6 +577,8 @@
static struct ast_context *contexts = NULL;
static struct ast_hashtab *contexts_tree = NULL;
+static struct ast_strtab *pbx_stringtab = NULL;
+
AST_MUTEX_DEFINE_STATIC(conlock); /*!< Lock for the ast_context list */
@@ -847,7 +859,7 @@
struct match_char *add_pattern_node(struct ast_context *con, struct match_char *current, char *pattern, int is_pattern, int already, int specificity)
{
- struct match_char *m = (struct match_char *)calloc(1,sizeof(struct match_char));
+ struct match_char *m = ast_calloc(1,sizeof(struct match_char));
m->x = strdup(pattern);
m->is_pattern = is_pattern;
if (specificity == 1 && is_pattern && pattern[0] == 'N')
@@ -1257,27 +1269,27 @@
return extension_match_core(pattern, data, needmore);
}
-struct fake_context /* this struct is purely for matching in the RB tree */
-{
- ast_mutex_t lock;
- struct ast_exten *root;
- struct ast_hashtab *root_tree;
- struct match_char *pattern_tree;
- struct ast_context *next;
- struct ast_include *includes;
- struct ast_ignorepat *ignorepats;
- const char *registrar;
- AST_LIST_HEAD_NOLOCK(, ast_sw) alts;
- ast_mutex_t macrolock;
- char name[256];
-};
-
struct ast_context *ast_context_find(const char *name)
{
+ const char *context_name;
struct ast_context *tmp = NULL;
- struct fake_context item;
+ struct ast_context item;
+
+ if (!pbx_stringtab)
+ pbx_stringtab = st_create(2000, 2000, 50, 1); /* case-sensitive hash tree */
+
+ context_name = st_lookup(pbx_stringtab, name);
+ if (!context_name)
+ return NULL;
+
+ item.name = context_name;
+
+#ifdef NOTNOW
strncpy(item.name,name,256);
+ /* the hash tables will lock for themselves on access */
ast_mutex_lock(&conlock);
+#endif
+
if( contexts_tree )
tmp = ast_hashtab_lookup(contexts_tree,&item);
#ifdef NOTNOW
@@ -1285,8 +1297,8 @@
if (!name || !strcasecmp(name, tmp->name))
break;
}
+ ast_mutex_unlock(&conlock);
#endif
- ast_mutex_unlock(&conlock);
return tmp;
}
@@ -1315,7 +1327,7 @@
int priority;
#endif
- char *incstack[AST_PBX_MAX_STACK]; /* filled during the search */
+ const char *incstack[AST_PBX_MAX_STACK]; /* filled during the search */
int stacklen; /* modified during the search */
int status; /* set on return */
struct ast_switch *swo; /* set on return */
@@ -1336,7 +1348,7 @@
struct ast_exten pattern;
struct scoreboard score;
- pattern.label = label;
+ pattern.label = st_insert(pbx_stringtab, label);
pattern.priority = priority;
/* Initialize status if appropriate */
@@ -1359,8 +1371,8 @@
if (bypass) /* bypass means we only look there */
tmp = bypass;
else { /* look in contexts */
- struct fake_context item;
- strncpy(item.name,context,256);
+ struct ast_context item;
+ item.name = st_insert(pbx_stringtab, context);
tmp = ast_hashtab_lookup(contexts_tree,&item);
#ifdef NOTNOW
tmp = NULL;
@@ -1493,6 +1505,10 @@
return NULL;
}
}
+
+ /* if we are exceedingly smart, we will just include all the extensions in included contexts in the base
+ context_match tree, and match in a single pass, and get rid of this code... */
+
q->incstack[q->stacklen++] = tmp->name; /* Setup the stack */
/* Now try any includes we have in this context */
for (i = tmp->includes; i; i = i->next) {
@@ -2964,7 +2980,10 @@
{
if (e->priority == PRIORITY_HINT)
ast_remove_hint(e);
-
+ if (e->peer_tree)
+ ast_hashtab_destroy(e->peer_tree);
+ if (e->peer_label_tree)
+ ast_hashtab_destroy(e->peer_label_tree);
if (e->datad)
e->datad(e->data);
free(e);
@@ -3045,8 +3064,8 @@
static struct ast_context *find_context_locked(const char *context)
{
struct ast_context *c = NULL;
- struct fake_context item;
- strncpy(item.name, context, 256);
+ struct ast_context item;
+ item.name = st_insert(pbx_stringtab, context);
ast_lock_contexts();
c = ast_hashtab_lookup(contexts_tree,&item);
#ifdef NOTNOW
@@ -3273,8 +3292,8 @@
{
struct ast_context *c = NULL;
int ret = -1;
- struct fake_context item;
- strncpy(item.name,context,256);
+ struct ast_context item;
+ item.name = st_insert(pbx_stringtab, context);
ast_lock_contexts();
c = ast_hashtab_lookup(contexts_tree,&item);
if (c)
@@ -3308,8 +3327,8 @@
{
struct ast_context *c = NULL;
int ret = -1;
- struct fake_context item;
- strncpy(item.name, context, 256);
+ struct ast_context item;
+ item.name = st_insert(pbx_stringtab, context);
ast_lock_contexts();
@@ -4293,21 +4312,36 @@
static struct ast_context *__ast_context_create(struct ast_context **extcontexts, const char *name, const char *registrar, int existsokay)
{
struct ast_context *tmp, **local_contexts;
+ struct ast_context search;
int length = sizeof(struct ast_context) + strlen(name) + 1;
+ const char *context_name;
+
+ if (!contexts_tree)
+ contexts_tree = ast_hashtab_create(17,
+ hashtab_compare_contexts,
+ ast_hashtab_resize_java,
+ ast_hashtab_newsize_java,
+ hashtab_hash_contexts,
+ 1);
+ if (!pbx_stringtab)
+ pbx_stringtab = st_create(2000, 2000, 50, 1); /* case-sensitive hash tree */
+
+ context_name = st_insert(pbx_stringtab, name);
+ search.name = context_name;
+ tmp = ast_hashtab_lookup(contexts_tree, &search);
+
+ if (!existsokay && tmp) {
+ ast_log(LOG_WARNING, "Tried to register context '%s', already in use\n", name);
+ return tmp;
+ }
if (!extcontexts) {
ast_mutex_lock(&conlock);
local_contexts = &contexts;
- if (!contexts_tree)
- contexts_tree = ast_hashtab_create(17,
- hashtab_compare_contexts,
- ast_hashtab_resize_java,
- ast_hashtab_newsize_java,
- hashtab_hash_contexts,
- 1);
} else
local_contexts = extcontexts;
+#ifdef NO_MORE
for (tmp = *local_contexts; tmp; tmp = tmp->next) {
if (!strcasecmp(tmp->name, name)) {
if (!existsokay) {
@@ -4319,10 +4353,13 @@
return tmp;
}
}
+#endif
+
if ((tmp = ast_calloc(1, length))) {
ast_mutex_init(&tmp->lock);
ast_mutex_init(&tmp->macrolock);
- strcpy(tmp->name, name);
+ /* strcpy(tmp->name, name); */
+ tmp->name = context_name;
tmp->root = NULL;
tmp->root_tree = NULL;
tmp->registrar = registrar;
@@ -5271,8 +5308,10 @@
length = sizeof(struct ast_exten);
length += strlen(extension) + 1;
length += strlen(application) + 1;
+#ifdef NOMORE
if (label)
length += strlen(label) + 1;
+#endif
if (callerid)
length += strlen(callerid) + 1;
else
@@ -5284,13 +5323,11 @@
if (!(tmp = ast_calloc(1, length)))
return -1;
+ if (label) {
+ tmp->label = st_insert(pbx_stringtab, label);
+ }
/* use p as dst in assignments, as the fields are const char * */
p = tmp->stuff;
- if (label) {
- tmp->label = p;
- strcpy(p, label);
- p += strlen(label) + 1;
- }
tmp->exten = p;
p += ext_strncpy(p, extension, strlen(extension) + 1) + 1;
tmp->priority = priority;
@@ -5840,6 +5877,8 @@
ast_mutex_lock(&tmp->lock);
if (option_debug)
ast_log(LOG_DEBUG, "delete ctx %s %s\n", tmp->name, tmp->registrar);
+ ast_hashtab_remove_this_object(contexts_tree,tmp);
+
next = tmp->next;
if (tmpl)
tmpl->next = next;
More information about the asterisk-commits
mailing list