[icinga-checkins] icinga.org: icinga-core/mfriedrich/workers: core: replace worker response code parsing with a perfect hash #2946

git at icinga.org git at icinga.org
Sun Aug 5 23:32:12 CEST 2012


Module: icinga-core
Branch: mfriedrich/workers
Commit: 1ab765a9d2da7c5d81216ba91b742cbc15070bad
URL:    https://git.icinga.org/?p=icinga-core.git;a=commit;h=1ab765a9d2da7c5d81216ba91b742cbc15070bad

Author: Michael Friedrich <michael.friedrich at univie.ac.at>
Date:   Sun Aug  5 12:16:26 2012 +0200

core: replace worker response code parsing with a perfect hash #2946

previously, we had a list of defined values to be run on every response
call resolving (which happens on every job a worker as processed and now
puts a response to), so this is a good solution. a note should be kept -
this must stay compatible to nagios, in order to stay sane on such
reponse codes (on both sides).

refs #2946

---

 base/workers.c  |   70 ++----------------------------------
 base/wp-phash.c |  107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 111 insertions(+), 66 deletions(-)

diff --git a/base/workers.c b/base/workers.c
index 2381661..a02c0da 100644
--- a/base/workers.c
+++ b/base/workers.c
@@ -37,6 +37,9 @@
 #include "../include/icinga.h"
 #include "../include/workers.h"
 
+/* perfect hash function for wproc response codes */
+#include "wp-phash.c"
+
 extern int service_check_timeout, host_check_timeout;
 extern int notification_timeout;
 
@@ -279,71 +282,6 @@ static int handle_worker_check(wproc_result *wpres, worker_process *wp, worker_j
 	return result;
 }
 
-#define WPRES_job_id 0
-#define WPRES_type 1
-#define WPRES_command 2
-#define WPRES_timeout 3
-#define WPRES_wait_status 4
-#define WPRES_outstd 5
-#define WPRES_outerr 6
-#define WPRES_start 7
-#define WPRES_stop 8
-#define WPRES_runtime 9
-#define WPRES_exited_ok 10
-#define WPRES_ru_utime 11
-#define WPRES_ru_stime 12
-#define WPRES_ru_minflt 13
-#define WPRES_ru_majflt 14
-#define WPRES_ru_nswap 15
-#define WPRES_ru_inblock 16
-#define WPRES_ru_oublock 17
-#define WPRES_ru_nsignals 18
-#define WPRES_error_code 19
-#define WPRES_error_msg 20
-#define WPRES_CODE(str) { #str, sizeof(#str) - 1, WPRES_##str }
-typedef struct strcode {
-	char *str;
-	unsigned int len;
-	int code;
-} strcode;
-static strcode wpres_codes[] = {
-	WPRES_CODE(job_id),
-	WPRES_CODE(type),
-	WPRES_CODE(timeout),
-	WPRES_CODE(start),
-	WPRES_CODE(stop),
-	WPRES_CODE(outstd),
-	WPRES_CODE(outerr),
-	WPRES_CODE(wait_status),
-	WPRES_CODE(command),
-	WPRES_CODE(runtime),
-	WPRES_CODE(ru_utime),
-	WPRES_CODE(ru_stime),
-	WPRES_CODE(ru_minflt),
-	WPRES_CODE(ru_majflt),
-	WPRES_CODE(ru_nswap),
-	WPRES_CODE(ru_inblock),
-	WPRES_CODE(ru_oublock),
-	WPRES_CODE(ru_nsignals),
-	WPRES_CODE(exited_ok),
-	WPRES_CODE(error_msg),
-	WPRES_CODE(error_code),
-};
-
-static int response_code(char *key, unsigned int key_len) {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(wpres_codes); i++) {
-		if (wpres_codes[i].len != key_len)
-			continue;
-		if (!memcmp(wpres_codes[i].str, key, key_len))
-			return wpres_codes[i].code;
-	}
-
-	/* unrecognized key */
-	return -1;
-}
-
 /*
  * parses a worker result. We do no strdup()'s here, so when
  * kvv is destroyed, all references to strings will become
@@ -358,7 +296,7 @@ static int parse_worker_result(wproc_result *wpres, struct kvvec *kvv) {
 		key = kvv->kv[i].key;
 		value = kvv->kv[i].value;
 
-		code = response_code(key, kvv->kv[i].key_len);
+		code = wp_phash(key, kvv->kv[i].key_len);
 		switch (code) {
 		case -1:
 			logit(NSLOG_RUNTIME_WARNING, TRUE, "Unrecognized worker result variable: (i=%d) %s=%s\n", i, key, value);
diff --git a/base/wp-phash.c b/base/wp-phash.c
new file mode 100644
index 0000000..a88d339
--- /dev/null
+++ b/base/wp-phash.c
@@ -0,0 +1,107 @@
+/*****************************************************************************
+ *
+ * WP-PHASH.C - gperf perfect hash for worker responses
+ *
+ * Copyright (c) 2012 Nagios Core Development Team and Community Contributors
+ * Copyright (c) 2012 Icinga Development Team (http://www.icinga.org)
+ *
+ * License:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *****************************************************************************/
+
+
+#define WPRES_type 		4
+#define WPRES_outerr 		6
+#define WPRES_timeout		7
+#define WPRES_ru_nswap 		8
+#define WPRES_error_msg 	9
+#define WPRES_error_code 	10
+#define WPRES_ru_nsignals 	11
+#define WPRES_command 		12
+#define WPRES_ru_majflt 	14
+#define WPRES_start 		15
+#define WPRES_outstd 		16
+#define WPRES_ru_stime 		18
+#define WPRES_exited_ok 	19
+#define WPRES_ru_inblock 	20
+#define WPRES_job_id 		21
+#define WPRES_ru_minflt 	24
+#define WPRES_ru_oublock 	25
+#define WPRES_wait_status 	26
+#define WPRES_runtime 		27
+#define WPRES_stop 		29
+#define WPRES_ru_utime 		33
+
+/* C code produced by gperf version 3.0.4 */
+/* Command-line: gperf -H wp_phash wproc-strings  */
+/* Computed positions: -k'4-5' */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+	  && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+	  && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+	  && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+	  && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+	  && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+	  && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+	  && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+	  && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+	  && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+	  && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+	  && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+	  && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+	  && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+	  && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+	  && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+	  && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+	  && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+	  && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+	  && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+	  && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+	  && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+	  && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646.  */
+error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf at gnu.org>."
+#endif
+
+static inline unsigned int wp_phash(register const char *str, register unsigned int len) {
+	/* the last 136 entries have been cut, as we don't need them */
+	static unsigned char asso_values[] =
+    {
+		34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+		34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+		34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+		34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+		34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+		34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+		34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+		34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+		34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+		34, 34, 34, 34, 34,  5, 34,  0, 34, 34,
+		34,  0, 34, 34, 34, 10, 34, 34, 34,  5,
+		0,  0, 25, 34,  0,  0, 10, 15, 34, 34,
+    };
+	register int hval = len;
+
+	switch (hval) {
+	default:
+        	hval += asso_values[(unsigned char)str[4]];
+		/*FALLTHROUGH*/
+	case 4:
+		hval += asso_values[(unsigned char)str[3]];
+		break;
+	}
+	return hval;
+}





More information about the icinga-checkins mailing list