diff options
author | Joshua Colp <jcolp@digium.com> | 2017-12-18 14:41:55 -0600 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2017-12-18 14:41:55 -0600 |
commit | bac31e55bb85ace72cf27155e84e569f6d7f6ada (patch) | |
tree | 08ce0b22b12fd558f535c1dd4ab604ba7b5563b7 /main | |
parent | a853b3bcffb3eaa771cf6f52e6e2e8893a2c657e (diff) | |
parent | 957709e1e824e221254599e4ad8445e3839ce535 (diff) |
Merge changes from topic 'faster-aco' into 15
* changes:
aco: Minimize use of regex.
aco: Create ways to minimize use of regex.
Diffstat (limited to 'main')
-rw-r--r-- | main/cdr.c | 28 | ||||
-rw-r--r-- | main/cel.c | 21 | ||||
-rw-r--r-- | main/config_options.c | 87 | ||||
-rw-r--r-- | main/features_config.c | 22 | ||||
-rw-r--r-- | main/named_acl.c | 4 | ||||
-rw-r--r-- | main/stasis.c | 8 | ||||
-rw-r--r-- | main/udptl.c | 4 |
7 files changed, 139 insertions, 35 deletions
diff --git a/main/cdr.c b/main/cdr.c index 0e0366836..0f6a66517 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -238,8 +238,29 @@ static struct aco_type general_option = { .type = ACO_GLOBAL, .name = "general", .item_offset = offsetof(struct module_config, general), - .category = "^general$", - .category_match = ACO_WHITELIST, + .category = "general", + .category_match = ACO_WHITELIST_EXACT, +}; + +/*! Config sections used by existing modules. Do not add to this list. */ +static const char *ignore_categories[] = { + "csv", + "custom", + "manager", + "odbc", + "pgsql", + "radius", + "sqlite", + "tds", + "mysql", + NULL, +}; + +static struct aco_type ignore_option = { + .type = ACO_IGNORE, + .name = "modules", + .category = (const char*)ignore_categories, + .category_match = ACO_WHITELIST_ARRAY, }; static void *module_config_alloc(void); @@ -249,8 +270,7 @@ static void module_config_post_apply(void); /*! \brief The file definition */ static struct aco_file module_file_conf = { .filename = "cdr.conf", - .skip_category = "(^csv$|^custom$|^manager$|^odbc$|^pgsql$|^radius$|^sqlite$|^tds$|^mysql$)", - .types = ACO_TYPES(&general_option), + .types = ACO_TYPES(&general_option, &ignore_option), }; CONFIG_INFO_CORE("cdr", cfg_info, module_configs, module_config_alloc, diff --git a/main/cel.c b/main/cel.c index faf4fde71..cec0a85e4 100644 --- a/main/cel.c +++ b/main/cel.c @@ -242,15 +242,28 @@ static struct aco_type general_option = { .type = ACO_GLOBAL, .name = "general", .item_offset = offsetof(struct cel_config, general), - .category_match = ACO_WHITELIST, - .category = "^general$", + .category_match = ACO_WHITELIST_EXACT, + .category = "general", +}; + +/*! Config sections used by existing modules. Do not add to this list. */ +static const char *ignore_categories[] = { + "manager", + "radius", + NULL, +}; + +static struct aco_type ignore_option = { + .type = ACO_IGNORE, + .name = "modules", + .category = (const char*)ignore_categories, + .category_match = ACO_WHITELIST_ARRAY, }; /*! \brief The config file to be processed for the module. */ static struct aco_file cel_conf = { .filename = "cel.conf", /*!< The name of the config file */ - .types = ACO_TYPES(&general_option), /*!< The mapping object types to be processed */ - .skip_category = "(^manager$|^radius$)", /*!< Config sections used by existing modules. Do not add to this list. */ + .types = ACO_TYPES(&general_option, &ignore_option), /*!< The mapping object types to be processed */ }; static int cel_pre_apply_config(void); diff --git a/main/config_options.c b/main/config_options.c index a9a145b96..1f4f99b72 100644 --- a/main/config_options.c +++ b/main/config_options.c @@ -131,7 +131,7 @@ static int noop_handler_fn(const struct aco_option *opt, struct ast_variable *va static int chararray_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj); #ifdef AST_XML_DOCS -static int xmldoc_update_config_type(const char *module, const char *name, const char *category, const char *matchfield, const char *matchvalue, unsigned int matches); +static int xmldoc_update_config_type(const char *module, const char *name, const char *category, const char *matchfield, const char *matchvalue, enum aco_category_op category_match); static int xmldoc_update_config_option(struct aco_type **types, const char *module, const char *name, const char *object_name, const char *default_value, unsigned int regex, enum aco_option_type type); #endif @@ -373,6 +373,8 @@ static int find_option_cb(void *obj, void *arg, int flags) switch (match->match_type) { case ACO_EXACT: return strcasecmp(name, match->name) ? 0 : CMP_MATCH | CMP_STOP; + case ACO_PREFIX: + return strncasecmp(name, match->name, strlen(match->name)) ? 0 : CMP_MATCH | CMP_STOP; case ACO_REGEX: return regexec(match->name_regex, name, 0, NULL, 0) ? 0 : CMP_MATCH | CMP_STOP; } @@ -402,6 +404,45 @@ struct ao2_container *aco_option_container_alloc(void) return ao2_container_alloc(CONFIG_OPT_BUCKETS, config_opt_hash, config_opt_cmp); } +static int internal_aco_type_category_check(struct aco_type *match, const char *category) +{ + const char **categories = (const char **)match->category; + + switch (match->category_match) { + case ACO_WHITELIST: + return regexec(match->internal->regex, category, 0, NULL, 0); + + case ACO_BLACKLIST: + return !regexec(match->internal->regex, category, 0, NULL, 0); + + case ACO_WHITELIST_EXACT: + return strcasecmp(match->category, category); + + case ACO_BLACKLIST_EXACT: + return !strcasecmp(match->category, category); + + case ACO_WHITELIST_ARRAY: + while (*categories) { + if (!strcasecmp(*categories, category)) { + return 0; + } + categories++; + } + return -1; + + case ACO_BLACKLIST_ARRAY: + while (*categories) { + if (!strcasecmp(*categories, category)) { + return -1; + } + categories++; + } + return 0; + } + + return -1; +} + static struct aco_type *internal_aco_type_find(struct aco_file *file, struct ast_config *cfg, const char *category) { size_t x; @@ -410,7 +451,7 @@ static struct aco_type *internal_aco_type_find(struct aco_file *file, struct ast for (x = 0, match = file->types[x]; match; match = file->types[++x]) { /* First make sure we are an object that can service this category */ - if (!regexec(match->internal->regex, category, 0, NULL, 0) == !match->category_match) { + if (internal_aco_type_category_check(match, category)) { continue; } @@ -483,6 +524,10 @@ static int process_category(struct ast_config *cfg, struct aco_info *info, struc return -1; } + if (type->type == ACO_IGNORE) { + return 0; + } + field = info->internal->pending + type->item_offset; if (!*field) { ast_log(LOG_ERROR, "In %s: %s - No object to update!\n", file->filename, cat); @@ -631,6 +676,10 @@ enum aco_process_status aco_process_config(struct aco_info *info, int reload) for (i = 0, match = file->types[i]; match; match = file->types[++i]) { void **field = info->internal->pending + match->item_offset; + if (match->type == ACO_IGNORE) { + continue; + } + if (match->type != ACO_GLOBAL || !*field) { continue; } @@ -797,9 +846,19 @@ static int internal_type_init(struct aco_type *type) return -1; } - if (!(type->internal->regex = build_regex(type->category))) { - internal_type_destroy(type); - return -1; + switch (type->category_match) { + case ACO_BLACKLIST: + case ACO_WHITELIST: + if (!(type->internal->regex = build_regex(type->category))) { + internal_type_destroy(type); + return -1; + } + break; + case ACO_BLACKLIST_EXACT: + case ACO_WHITELIST_EXACT: + case ACO_BLACKLIST_ARRAY: + case ACO_WHITELIST_ARRAY: + break; } if (!(type->internal->opts = aco_option_container_alloc())) { @@ -828,7 +887,8 @@ int aco_info_init(struct aco_info *info) #ifdef AST_XML_DOCS if (!info->hidden && !type->hidden && - xmldoc_update_config_type(info->module, type->name, type->category, type->matchfield, type->matchvalue, type->category_match == ACO_WHITELIST)) { + type->type != ACO_IGNORE && + xmldoc_update_config_type(info->module, type->name, type->category, type->matchfield, type->matchvalue, type->category_match)) { goto error; } #endif /* AST_XML_DOCS */ @@ -989,7 +1049,7 @@ static char *complete_config_option(const char *module, const char *option, cons /*! \internal * \brief Update the XML documentation for a config type based on its registration */ -static int xmldoc_update_config_type(const char *module, const char *name, const char *category, const char *matchfield, const char *matchvalue, unsigned int matches) +static int xmldoc_update_config_type(const char *module, const char *name, const char *category, const char *matchfield, const char *matchvalue, enum aco_category_op category_match) { RAII_VAR(struct ast_xml_xpath_results *, results, NULL, ast_xml_xpath_results_free); RAII_VAR(struct ast_xml_doc_item *, config_info, ao2_find(xmldocs, module, OBJ_KEY), ao2_cleanup); @@ -1028,7 +1088,18 @@ static int xmldoc_update_config_type(const char *module, const char *name, const } ast_xml_set_text(tmp, category); - ast_xml_set_attribute(tmp, "match", matches ? "true" : "false"); + switch (category_match) { + case ACO_WHITELIST: + case ACO_WHITELIST_EXACT: + case ACO_WHITELIST_ARRAY: + ast_xml_set_attribute(tmp, "match", "true"); + break; + case ACO_BLACKLIST: + case ACO_BLACKLIST_EXACT: + case ACO_BLACKLIST_ARRAY: + ast_xml_set_attribute(tmp, "match", "false"); + break; + } if (!ast_strlen_zero(matchfield) && !(tmp = ast_xml_new_child(matchinfo, "field"))) { ast_log(LOG_WARNING, "Could not add %s attribute for type '%s' in module '%s'\n", matchfield, name, module); diff --git a/main/features_config.c b/main/features_config.c index 72cd0404f..a773f497f 100644 --- a/main/features_config.c +++ b/main/features_config.c @@ -219,7 +219,7 @@ The <replaceable>DYNAMIC_FEATURES</replaceable> is a <literal>#</literal> separated list of either applicationmap item names or featuregroup names.</para> </description> - <configOption name="^.*$" regex="true"> + <configOption name=""> <synopsis>A custom feature to invoke during a bridged call</synopsis> <description> <para>Each item listed here is a comma-separated list of parameters that determine @@ -272,7 +272,7 @@ DTMF sequence used to invoke an applicationmap item to be overridden with a different sequence.</para> </description> - <configOption name="^.*$" regex="true"> + <configOption name=""> <synopsis>Applicationmap item to place in the feature group</synopsis> <description> <para>Each item here must be a name of an item in the applicationmap. The @@ -578,24 +578,24 @@ struct features_config { static struct aco_type global_option = { .type = ACO_GLOBAL, .name = "globals", - .category_match = ACO_WHITELIST, - .category = "^general$", + .category_match = ACO_WHITELIST_EXACT, + .category = "general", .item_offset = offsetof(struct features_config, global), }; static struct aco_type featuremap_option = { .type = ACO_GLOBAL, .name = "featuremap", - .category_match = ACO_WHITELIST, - .category = "^featuremap$", + .category_match = ACO_WHITELIST_EXACT, + .category = "featuremap", .item_offset = offsetof(struct features_config, featuremap), }; static struct aco_type applicationmap_option = { .type = ACO_GLOBAL, .name = "applicationmap", - .category_match = ACO_WHITELIST, - .category = "^applicationmap$", + .category_match = ACO_WHITELIST_EXACT, + .category = "applicationmap", .item_offset = offsetof(struct features_config, applicationmap), }; @@ -1851,13 +1851,13 @@ static int load_config(void) aco_option_register_custom(&cfg_info, "automixmon", ACO_EXACT, featuremap_options, DEFAULT_FEATUREMAP_AUTOMIXMON, featuremap_handler, 0); - aco_option_register_custom(&cfg_info, "^.*$", ACO_REGEX, applicationmap_options, + aco_option_register_custom(&cfg_info, "", ACO_PREFIX, applicationmap_options, "", applicationmap_handler, 0); - aco_option_register_custom(&cfg_info, "^.*$", ACO_REGEX, featuregroup_options, + aco_option_register_custom(&cfg_info, "", ACO_PREFIX, featuregroup_options, "", featuregroup_handler, 0); - aco_option_register_custom_nodoc(&cfg_info, "^.*$", ACO_REGEX, parkinglot_options, + aco_option_register_custom_nodoc(&cfg_info, "", ACO_PREFIX, parkinglot_options, "", unsupported_handler, 0); if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) { diff --git a/main/named_acl.c b/main/named_acl.c index 8b5aedabb..393532a53 100644 --- a/main/named_acl.c +++ b/main/named_acl.c @@ -80,8 +80,8 @@ static void *named_acl_find(struct ao2_container *container, const char *cat); static struct aco_type named_acl_type = { .type = ACO_ITEM, /*!< named_acls are items stored in containers, not individual global objects */ .name = "named_acl", - .category_match = ACO_BLACKLIST, - .category = "^general$", /*!< Match everything but "general" */ + .category_match = ACO_BLACKLIST_EXACT, + .category = "general", /*!< Match everything but "general" */ .item_alloc = named_acl_alloc, /*!< A callback to allocate a new named_acl based on category */ .item_find = named_acl_find, /*!< A callback to find a named_acl in some container of named_acls */ .item_offset = offsetof(struct named_acl_config, named_acl_list), /*!< Could leave this out since 0 */ diff --git a/main/stasis.c b/main/stasis.c index 186d88fdd..77bf34082 100644 --- a/main/stasis.c +++ b/main/stasis.c @@ -1434,8 +1434,8 @@ static struct aco_type threadpool_option = { .type = ACO_GLOBAL, .name = "threadpool", .item_offset = offsetof(struct stasis_config, threadpool_options), - .category = "^threadpool$", - .category_match = ACO_WHITELIST, + .category = "threadpool", + .category_match = ACO_WHITELIST_EXACT, }; static struct aco_type *threadpool_options[] = ACO_TYPES(&threadpool_option); @@ -1445,8 +1445,8 @@ static struct aco_type declined_option = { .type = ACO_GLOBAL, .name = "declined_message_types", .item_offset = offsetof(struct stasis_config, declined_message_types), - .category_match = ACO_WHITELIST, - .category = "^declined_message_types$", + .category_match = ACO_WHITELIST_EXACT, + .category = "declined_message_types", }; struct aco_type *declined_options[] = ACO_TYPES(&declined_option); diff --git a/main/udptl.c b/main/udptl.c index d982f6bcb..5a491e65c 100644 --- a/main/udptl.c +++ b/main/udptl.c @@ -237,9 +237,9 @@ static int udptl_pre_apply_config(void); static struct aco_type general_option = { .type = ACO_GLOBAL, .name = "global", - .category_match = ACO_WHITELIST, + .category_match = ACO_WHITELIST_EXACT, .item_offset = offsetof(struct udptl_config, general), - .category = "^general$", + .category = "general", }; static struct aco_type *general_options[] = ACO_TYPES(&general_option); |