<p>Sean Bright has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/7408">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">config: Speed up config template lookup<br><br>ast_category_get() has an (undocumented) implementation detail where it<br>tries to match the category name first by an explicit pointer comparison<br>and if that fails falls back to a normal match.<br><br>When initially building an ast_config during ast_config_load, this<br>pointer comparison can never succeed, but we will end up iterating all<br>categories twice. As the number of categories using a template<br>increases, this dual looping becomes quite expensive. So we pass a flag<br>to category_get_sep() indicating if a pointer match is even possible<br>before trying to do so, saving us a full pass over the list of current<br>categories.<br><br>In my tests, loading a file with 3 template categories and 12000<br>additional categories that use those 3 templates (this file configures<br>4000 PJSIP endpoints with AOR & Auth) takes 1.2 seconds. After this<br>change, that drops to 22ms.<br><br>Change-Id: I59b95f288e11eb6bb34f31ce4cc772136b275e4a<br>---<br>M main/config.c<br>1 file changed, 9 insertions(+), 7 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/08/7408/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/main/config.c b/main/config.c<br>index 9be7581..e686c23 100644<br>--- a/main/config.c<br>+++ b/main/config.c<br>@@ -988,13 +988,15 @@<br> }<br> <br> static struct ast_category *category_get_sep(const struct ast_config *config,<br>- const char *category_name, const char *filter, char sep)<br>+ const char *category_name, const char *filter, char sep, char pointer_match_possible)<br> {<br> struct ast_category *cat;<br> <br>- for (cat = config->root; cat; cat = cat->next) {<br>- if (cat->name == category_name && does_category_match(cat, category_name, filter, sep)) {<br>- return cat;<br>+ if (pointer_match_possible) {<br>+ for (cat = config->root; cat; cat = cat->next) {<br>+ if (cat->name == category_name && does_category_match(cat, category_name, filter, sep)) {<br>+ return cat;<br>+ }<br> }<br> }<br> <br>@@ -1010,7 +1012,7 @@<br> struct ast_category *ast_category_get(const struct ast_config *config,<br> const char *category_name, const char *filter)<br> {<br>- return category_get_sep(config, category_name, filter, ',');<br>+ return category_get_sep(config, category_name, filter, ',', 1);<br> }<br> <br> const char *ast_category_get_name(const struct ast_category *category)<br>@@ -1794,7 +1796,7 @@<br> if (cur[1] != ',') {<br> filter = &cur[1];<br> }<br>- *cat = category_get_sep(cfg, catname, filter, '&');<br>+ *cat = category_get_sep(cfg, catname, filter, '&', 0);<br> if (!(*cat)) {<br> if (newcat) {<br> ast_category_destroy(newcat);<br>@@ -1812,7 +1814,7 @@<br> } else {<br> struct ast_category *base;<br> <br>- base = ast_category_get(cfg, cur, "TEMPLATES=include");<br>+ base = category_get_sep(cfg, cur, "TEMPLATES=include", ',', 0);<br> if (!base) {<br> if (newcat) {<br> ast_category_destroy(newcat);<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/7408">change 7408</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/7408"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 13 </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I59b95f288e11eb6bb34f31ce4cc772136b275e4a </div>
<div style="display:none"> Gerrit-Change-Number: 7408 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Sean Bright <sean.bright@gmail.com> </div>