[icinga-checkins] icinga.org: icinga-core/dev/core: core: enhance illegal macro character processing performance

git at icinga.org git at icinga.org
Sun Mar 10 20:49:56 CET 2013


Module: icinga-core
Branch: dev/core
Commit: f88cb3ced7fe82d0bcd73a647772605a3a830319
URL:    https://git.icinga.org/?p=icinga-core.git;a=commit;h=f88cb3ced7fe82d0bcd73a647772605a3a830319

Author: Michael Friedrich <michael.friedrich at netways.de>
Date:   Sun Mar 10 18:46:55 2013 +0100

core: enhance illegal macro character processing performance

doing the checks on-demand in O(n*m) nested loops costs a heck of
performance when the macro should be cleaned from illegal characters.

by creating a map during initialisation, and only checking against that
will increase performance on macro processing overall.

kudos to Andreas Ericsson for the patch.

refs #3389

---

 Changelog        |    1 +
 base/config.c    |    7 +++++++
 base/icinga.c    |    1 +
 cgi/cgiutils.c   |    5 +++++
 common/macros.c  |   28 ++++++++--------------------
 include/common.h |   19 +++++++++++++++++++
 6 files changed, 41 insertions(+), 20 deletions(-)

diff --git a/Changelog b/Changelog
index 9b42861..a0f4a0e 100644
--- a/Changelog
+++ b/Changelog
@@ -21,6 +21,7 @@ ENHANCEMENTS
 * core: introduce warning level -vv on config verification #3510 - MF
 * core: refuse to start if neb modules fail to load (Andreas Ericsson) #3812 - MF
 * core: keep logfile open, reducing open/close performance decreases (Andreas Ericsson) #3390 - MF
+* core: enhance illegal macro character processing performance (Andreas Ericsson) #3389 - MF
 
 * classic ui: Add "set_expire_ack_by_default" to cgi configuration #3476 - CF
 * classic ui: Add "send_ack_notifications" to cgi configuration (TheCry) #3467 - CF
diff --git a/base/config.c b/base/config.c
index 9e41714..e4ebd7d 100644
--- a/base/config.c
+++ b/base/config.c
@@ -60,6 +60,7 @@ extern command  *ochp_command_ptr;
 
 extern char     *illegal_object_chars;
 extern char     *illegal_output_chars;
+extern char	illegal_output_char_map[256];
 
 extern int      use_regexp_matches;
 extern int      use_true_regexp_matching;
@@ -1830,6 +1831,12 @@ int pre_flight_check(void) {
 		logit(NSLOG_VERIFICATION_WARNING, TRUE, "%s", "Warning: Nothing specified for illegal_macro_output_chars variable!\n");
 		warnings++;
 	}
+	else {
+		char *p;
+		for (p = illegal_output_chars; *p; p++) {
+			illegal_output_char_map[(int)*p] = 1;
+		}
+	}
 
 	/* count number of services associated with each host (we need this for flap detection)... */
 	for (temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {
diff --git a/base/icinga.c b/base/icinga.c
index cc13ad1..84db1f8 100644
--- a/base/icinga.c
+++ b/base/icinga.c
@@ -81,6 +81,7 @@ command         *ochp_command_ptr = NULL;
 
 char            *illegal_object_chars = NULL;
 char            *illegal_output_chars = NULL;
+char		illegal_output_char_map[] = CHAR_MAP_INIT(0);
 
 int             use_regexp_matches = FALSE;
 int             use_true_regexp_matching = FALSE;
diff --git a/cgi/cgiutils.c b/cgi/cgiutils.c
index 98d613f..bf77b8b 100644
--- a/cgi/cgiutils.c
+++ b/cgi/cgiutils.c
@@ -56,6 +56,7 @@ char            *normal_sound = NULL;
 char            *statusmap_background_image = NULL;
 
 char            *illegal_output_chars = NULL;
+char		illegal_output_char_map[] = CHAR_MAP_INIT(0);
 
 char            *http_charset = NULL;
 
@@ -366,6 +367,7 @@ int read_cgi_config_file(char *filename) {
 	mmapfile *thefile;
 	char *var = NULL;
 	char *val = NULL;
+	char *p = NULL;
 
 
 	if ((thefile = mmap_fopen(filename)) == NULL)
@@ -736,6 +738,9 @@ int read_cgi_config_file(char *filename) {
 		}
 	}
 
+	for (p = illegal_output_chars; p && *p; p++)
+		illegal_output_char_map[(int)*p] = 1;
+
 	/* free memory and close the file */
 	free(input);
 	mmap_fclose(thefile);
diff --git a/common/macros.c b/common/macros.c
index 0133178..dfe8eb6 100644
--- a/common/macros.c
+++ b/common/macros.c
@@ -44,6 +44,7 @@ extern int	keep_unknown_macros;
 int dummy;	/* reduce compiler warnings */
 
 extern char     *illegal_output_chars;
+extern char	illegal_output_char_map[256];
 
 extern contact		*contact_list;
 extern contactgroup	*contactgroup_list;
@@ -2563,10 +2564,8 @@ int grab_custom_object_macro(char *macro_name, customvariablesmember *vars, char
 char *clean_macro_chars(char *macro, int options) {
 	register int x = 0;
 	register int y = 0;
-	register int z = 0;
 	register int ch = 0;
 	register int len = 0;
-	register int illegal_char = 0;
 
 	if (macro == NULL)
 		return "";
@@ -2578,26 +2577,10 @@ char *clean_macro_chars(char *macro, int options) {
 
 		for (y = 0, x = 0; x < len; x++) {
 
-			/*ch=(int)macro[x];*/
-			/* allow non-ASCII characters (Japanese, etc) */
 			ch = macro[x] & 0xff;
 
-			/* illegal ASCII characters */
-			if (ch < 32 || ch == 127)
-				continue;
-
-			/* illegal user-specified characters */
-			illegal_char = FALSE;
-			if (illegal_output_chars != NULL) {
-				for (z = 0; illegal_output_chars[z] != '\x0'; z++) {
-					if (ch == (int)illegal_output_chars[z]) {
-						illegal_char = TRUE;
-						break;
-					}
-				}
-			}
-
-			if (illegal_char == FALSE)
+			/* illegal chars are skipped */
+			if (!illegal_output_char_map[ch])
 				macro[y++] = macro[x];
 		}
 
@@ -2684,6 +2667,11 @@ int init_macros(void) {
 
 	init_macrox_names();
 
+	for (x = 0; x < 32; x++)
+		illegal_output_char_map[x] = 1;
+
+	illegal_output_char_map[127] = 1;
+
 	/*
 	 * non-volatile macros are free()'d when they're set.
 	 * We must do this in order to not lose the constant
diff --git a/include/common.h b/include/common.h
index a7709d3..5502065 100644
--- a/include/common.h
+++ b/include/common.h
@@ -437,6 +437,25 @@
 #define FALSE				0
 #endif
 
+/** character map initialization for .bss-allocated char maps */
+#define CHAR_MAP_INIT(k) { \
+        k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \
+        k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \
+        k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \
+        k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \
+        k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \
+        k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \
+        k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \
+        k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \
+        k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \
+        k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \
+        k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \
+        k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \
+        k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \
+        k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \
+        k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \
+        k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \
+        }
 
 /****************** HOST CONFIG FILE READING OPTIONS ********************/
 





More information about the icinga-checkins mailing list