Browse Source

H2O: Implement an optimized replacement of yajl_gen_integer() (#4401)

This change affects mainly the cached queries test.
Anton Kirilov 6 years ago
parent
commit
f47b842f45
3 changed files with 53 additions and 2 deletions
  1. 48 0
      frameworks/C/h2o/src/utility.c
  2. 1 0
      frameworks/C/h2o/src/utility.h
  3. 4 2
      frameworks/C/h2o/src/world.c

+ 48 - 0
frameworks/C/h2o/src/utility.c

@@ -18,9 +18,11 @@
 */
 
 #include <assert.h>
+#include <inttypes.h>
 #include <limits.h>
 #include <stdbool.h>
 #include <stdint.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <yajl/yajl_gen.h>
 
@@ -46,6 +48,52 @@ void free_json_generator(json_generator_t *gen, list_t **pool, size_t *gen_num,
 	}
 }
 
+yajl_gen_status gen_integer(int64_t number, char *buf, size_t len, yajl_gen gen)
+{
+	if (!len)
+		return yajl_gen_invalid_number;
+	else if (number == INT64_MIN) {
+		const size_t l = snprintf(buf, len, "%" PRId64, number);
+
+		if (l >= len)
+			return yajl_gen_invalid_number;
+
+		len = l;
+	}
+	else {
+		char *iter = buf + len;
+		const bool negative = number < 0;
+
+		if (negative) {
+			number = -number;
+			buf++;
+		}
+
+		do {
+			if (--iter > buf) {
+				*iter = '0' + number % 10;
+				number /= 10;
+			}
+			else if (number < 10) {
+				*iter = '0' + number;
+				number = 0;
+			}
+			else
+				return yajl_gen_invalid_number;
+		} while (number);
+
+		if (negative) {
+			*--iter = '-';
+			buf--;
+		}
+
+		len = buf + len - iter;
+		buf = iter;
+	}
+
+	return yajl_gen_number(gen, buf, len);
+}
+
 json_generator_t *get_json_generator(list_t **pool, size_t *gen_num)
 {
 	json_generator_t *ret;

+ 1 - 0
frameworks/C/h2o/src/utility.h

@@ -82,6 +82,7 @@ typedef struct {
 } json_generator_t;
 
 void free_json_generator(json_generator_t *gen, list_t **pool, size_t *gen_num, size_t max_gen);
+yajl_gen_status gen_integer(int64_t number, char *buf, size_t len, yajl_gen gen);
 json_generator_t *get_json_generator(list_t **pool, size_t *gen_num);
 uint32_t get_random_number(uint32_t max_rand, unsigned int *seed);
 bool is_power_of_2(size_t x);

+ 4 - 2
frameworks/C/h2o/src/world.c

@@ -624,11 +624,13 @@ static void process_result(PGresult *result, query_result_t *out)
 
 static int serialize_item(uint32_t id, uint32_t random_number, yajl_gen gen)
 {
+	char buf[32];
+
 	CHECK_YAJL_STATUS(yajl_gen_map_open, gen);
 	CHECK_YAJL_STATUS(yajl_gen_string, gen, YAJL_STRLIT(ID_KEY));
-	CHECK_YAJL_STATUS(yajl_gen_integer, gen, id);
+	CHECK_YAJL_STATUS(gen_integer, id, buf, sizeof(buf), gen);
 	CHECK_YAJL_STATUS(yajl_gen_string, gen, YAJL_STRLIT(RANDOM_NUM_KEY));
-	CHECK_YAJL_STATUS(yajl_gen_integer, gen, random_number);
+	CHECK_YAJL_STATUS(gen_integer, random_number, buf, sizeof(buf), gen);
 	CHECK_YAJL_STATUS(yajl_gen_map_close, gen);
 	return EXIT_SUCCESS;
 error_yajl: