From 5a13e95c567dc73e5e80bec12ce3afe764aeecec Mon Sep 17 00:00:00 2001
From: Sean Bright <sean.bright@gmail.com>
Date: Thu, 1 Apr 2021 11:38:04 -0400
Subject: [PATCH] loader.c: Speed up deprecation metadata lookup

Only use an XPath query once per module, then just navigate the DOM for
everything else.

Change-Id: Ia0336a7185f9180ccba4b6f631a00f9a22a36e92
---
 main/loader.c | 47 ++++++++++++++++++++++++++---------------------
 1 file changed, 26 insertions(+), 21 deletions(-)

diff --git a/main/loader.c b/main/loader.c
index f06016c9fa..aafcd3ba1f 100644
--- a/main/loader.c
+++ b/main/loader.c
@@ -2422,33 +2422,38 @@ done:
 			continue;
 		}
 
-		results = ast_xmldoc_query("/docs/module[@name='%s']/deprecated_in", mod_name);
-		deprecated_in[0] = '\0';
+		/* Clear out the previous values */
+		deprecated_in[0] = removed_in[0] = replacement[0] = 0;
+
+		results = ast_xmldoc_query("/docs/module[@name='%s']", mod_name);
 		if (results) {
-			const char *result_tmp = ast_xml_get_text(ast_xml_xpath_get_first_result(results));
-			if (!ast_strlen_zero(result_tmp)) {
-				ast_copy_string(deprecated_in, result_tmp, sizeof(deprecated_in));
+			struct ast_xml_node *deprecated_node, *removed_node, *replacement_node;
+			struct ast_xml_node *metadata_nodes = ast_xml_node_get_children(ast_xml_xpath_get_first_result(results));
+
+			deprecated_node = ast_xml_find_element(metadata_nodes, "deprecated_in", NULL, NULL);
+			if (deprecated_node) {
+				const char *result_tmp = ast_xml_get_text(deprecated_node);
+				if (!ast_strlen_zero(result_tmp)) {
+					ast_copy_string(deprecated_in, result_tmp, sizeof(deprecated_in));
+				}
 			}
-			ast_xml_xpath_results_free(results);
-		}
 
-		results = ast_xmldoc_query("/docs/module[@name='%s']/removed_in", mod_name);
-		removed_in[0] = '\0';
-		if (results) {
-			const char *result_tmp = ast_xml_get_text(ast_xml_xpath_get_first_result(results));
-			if (!ast_strlen_zero(result_tmp)) {
-				ast_copy_string(removed_in, result_tmp, sizeof(removed_in));
+			removed_node = ast_xml_find_element(metadata_nodes, "removed_in", NULL, NULL);
+			if (removed_node) {
+				const char *result_tmp = ast_xml_get_text(removed_node);
+				if (!ast_strlen_zero(result_tmp)) {
+					ast_copy_string(removed_in, result_tmp, sizeof(removed_in));
+				}
 			}
-			ast_xml_xpath_results_free(results);
-		}
 
-		results = ast_xmldoc_query("/docs/module[@name='%s']/replacement", mod_name);
-		replacement[0] = '\0';
-		if (results) {
-			const char *result_tmp = ast_xml_get_text(ast_xml_xpath_get_first_result(results));
-			if (!ast_strlen_zero(result_tmp)) {
-				ast_copy_string(replacement, result_tmp, sizeof(replacement));
+			replacement_node = ast_xml_find_element(metadata_nodes, "replacement", NULL, NULL);
+			if (replacement_node) {
+				const char *result_tmp = ast_xml_get_text(replacement_node);
+				if (!ast_strlen_zero(result_tmp)) {
+					ast_copy_string(replacement, result_tmp, sizeof(replacement));
+				}
 			}
+
 			ast_xml_xpath_results_free(results);
 		}
 
-- 
GitLab