Browse Source

H2O: Switch to thread-local caches (#4798)

This change affects mainly the cached queries test.
Anton Kirilov 6 years ago
parent
commit
588882b00b

+ 5 - 2
frameworks/C/h2o/src/handlers/request_handler_data.h

@@ -21,13 +21,16 @@
 
 
 #define REQUEST_HANDLER_DATA_H_
 #define REQUEST_HANDLER_DATA_H_
 
 
-#include "cache.h"
+#include <h2o.h>
 
 
 struct mustache_token_t;
 struct mustache_token_t;
 
 
 typedef struct {
 typedef struct {
 	struct mustache_token_t *fortunes_template;
 	struct mustache_token_t *fortunes_template;
-	cache_t world_cache;
 } request_handler_data_t;
 } request_handler_data_t;
 
 
+typedef struct {
+	h2o_cache_t *world_cache;
+} request_handler_thread_data_t;
+
 #endif // REQUEST_HANDLER_DATA_H_
 #endif // REQUEST_HANDLER_DATA_H_

+ 29 - 22
frameworks/C/h2o/src/handlers/world.c

@@ -113,7 +113,9 @@ static int compare_items(const void *x, const void *y);
 static void complete_multiple_query(multiple_query_ctx_t *query_ctx);
 static void complete_multiple_query(multiple_query_ctx_t *query_ctx);
 static int do_multiple_queries(bool do_update, bool use_cache, h2o_req_t *req);
 static int do_multiple_queries(bool do_update, bool use_cache, h2o_req_t *req);
 static void do_updates(multiple_query_ctx_t *query_ctx);
 static void do_updates(multiple_query_ctx_t *query_ctx);
-static void fetch_from_cache(uint64_t now, cache_t *world_cache, multiple_query_ctx_t *query_ctx);
+static void fetch_from_cache(uint64_t now,
+                             h2o_cache_t *world_cache,
+                             multiple_query_ctx_t *query_ctx);
 static void free_world_cache_entry(h2o_iovec_t value);
 static void free_world_cache_entry(h2o_iovec_t value);
 static size_t get_query_number(h2o_req_t *req);
 static size_t get_query_number(h2o_req_t *req);
 static void initialize_ids(size_t num_query, query_result_t *res, unsigned int *seed);
 static void initialize_ids(size_t num_query, query_result_t *res, unsigned int *seed);
@@ -258,7 +260,7 @@ static int do_multiple_queries(bool do_update, bool use_cache, h2o_req_t *req)
 		if (use_cache) {
 		if (use_cache) {
 			query_ctx->flags |= USE_CACHE;
 			query_ctx->flags |= USE_CACHE;
 			fetch_from_cache(h2o_now(ctx->event_loop.h2o_ctx.loop),
 			fetch_from_cache(h2o_now(ctx->event_loop.h2o_ctx.loop),
-			                 &ctx->global_data->request_handler_data.world_cache,
+			                 ctx->request_handler_data.world_cache,
 			                 query_ctx);
 			                 query_ctx);
 
 
 			if (query_ctx->num_result == query_ctx->num_query) {
 			if (query_ctx->num_result == query_ctx->num_query) {
@@ -366,22 +368,23 @@ error:
 	send_error(INTERNAL_SERVER_ERROR, REQ_ERROR, query_ctx->req);
 	send_error(INTERNAL_SERVER_ERROR, REQ_ERROR, query_ctx->req);
 }
 }
 
 
-static void fetch_from_cache(uint64_t now, cache_t *world_cache, multiple_query_ctx_t *query_ctx)
+static void fetch_from_cache(uint64_t now,
+                             h2o_cache_t *world_cache,
+                             multiple_query_ctx_t *query_ctx)
 {
 {
 	h2o_iovec_t key = {.len = sizeof(query_ctx->res->id)};
 	h2o_iovec_t key = {.len = sizeof(query_ctx->res->id)};
 
 
 	for (size_t i = 0; i < query_ctx->num_query; i++) {
 	for (size_t i = 0; i < query_ctx->num_query; i++) {
 		key.base = (char *) &query_ctx->res[i].id;
 		key.base = (char *) &query_ctx->res[i].id;
 
 
-		const h2o_cache_hashcode_t keyhash = h2o_cache_calchash(key.base, key.len);
-		h2o_cache_ref_t * const r = cache_fetch(world_cache, now, key, keyhash);
+		h2o_cache_ref_t * const r = h2o_cache_fetch(world_cache, now, key, 0);
 
 
 		if (r) {
 		if (r) {
 			query_ctx->res[i].id = query_ctx->res[query_ctx->num_result].id;
 			query_ctx->res[i].id = query_ctx->res[query_ctx->num_result].id;
 			memcpy(query_ctx->res + query_ctx->num_result++,
 			memcpy(query_ctx->res + query_ctx->num_result++,
 			       r->value.base,
 			       r->value.base,
 			       sizeof(*query_ctx->res));
 			       sizeof(*query_ctx->res));
-			cache_release(world_cache, r, keyhash);
+			h2o_cache_release(world_cache, r);
 		}
 		}
 	}
 	}
 }
 }
@@ -476,11 +479,11 @@ static result_return_t on_multiple_query_result(db_query_param_t *param, PGresul
 				const h2o_iovec_t value = {.base = (char *) r, .len = sizeof(*r)};
 				const h2o_iovec_t value = {.base = (char *) r, .len = sizeof(*r)};
 
 
 				*r = query_ctx->res[query_ctx->num_result];
 				*r = query_ctx->res[query_ctx->num_result];
-				cache_set(h2o_now(query_ctx->ctx->event_loop.h2o_ctx.loop),
-				          key,
-				          0,
-				          value,
-				          &query_ctx->ctx->global_data->request_handler_data.world_cache);
+				h2o_cache_set(query_ctx->ctx->request_handler_data.world_cache,
+				              h2o_now(query_ctx->ctx->event_loop.h2o_ctx.loop),
+				              key,
+				              0,
+				              value);
 			}
 			}
 		}
 		}
 
 
@@ -756,27 +759,31 @@ static int updates(struct st_h2o_handler_t *self, h2o_req_t *req)
 	return do_multiple_queries(true, false, req);
 	return do_multiple_queries(true, false, req);
 }
 }
 
 
-void cleanup_world_handlers(global_data_t *global_data)
+void free_world_handler_thread_data(request_handler_thread_data_t *request_handler_thread_data)
 {
 {
-	cache_destroy(&global_data->request_handler_data.world_cache);
+	h2o_cache_destroy(request_handler_thread_data->world_cache);
 }
 }
 
 
-void initialize_world_handlers(const config_t *config,
-                               global_data_t *global_data,
+void initialize_world_handler_thread_data(request_handler_thread_data_t *request_handler_data)
+{
+	request_handler_data->world_cache = h2o_cache_create(0,
+	                                                     CACHE_CAPACITY,
+	                                                     CACHE_DURATION,
+	                                                     free_world_cache_entry);
+
+	if (!request_handler_data->world_cache)
+		abort();
+}
+
+void initialize_world_handlers(global_data_t *global_data,
                                h2o_hostconf_t *hostconf,
                                h2o_hostconf_t *hostconf,
                                h2o_access_log_filehandle_t *log_handle)
                                h2o_access_log_filehandle_t *log_handle)
 {
 {
 	add_prepared_statement(WORLD_TABLE_NAME,
 	add_prepared_statement(WORLD_TABLE_NAME,
 	                       "SELECT * FROM " WORLD_TABLE_NAME " WHERE id = $1::integer;",
 	                       "SELECT * FROM " WORLD_TABLE_NAME " WHERE id = $1::integer;",
 	                       &global_data->prepared_statements);
 	                       &global_data->prepared_statements);
+	register_request_handler("/cached-worlds", cached_queries, hostconf, log_handle);
 	register_request_handler("/db", single_query, hostconf, log_handle);
 	register_request_handler("/db", single_query, hostconf, log_handle);
 	register_request_handler("/queries", multiple_queries, hostconf, log_handle);
 	register_request_handler("/queries", multiple_queries, hostconf, log_handle);
 	register_request_handler("/updates", updates, hostconf, log_handle);
 	register_request_handler("/updates", updates, hostconf, log_handle);
-
-	if (!cache_create(config->thread_num,
-	                  CACHE_CAPACITY,
-	                  CACHE_DURATION,
-	                  free_world_cache_entry,
-	                  &global_data->request_handler_data.world_cache))
-		register_request_handler("/cached-worlds", cached_queries, hostconf, log_handle);
 }
 }

+ 3 - 3
frameworks/C/h2o/src/handlers/world.h

@@ -25,9 +25,9 @@
 
 
 #include "global_data.h"
 #include "global_data.h"
 
 
-void cleanup_world_handlers(global_data_t *global_data);
-void initialize_world_handlers(const config_t *config,
-                               global_data_t *global_data,
+void free_world_handler_thread_data(request_handler_thread_data_t *request_handler_thread_data);
+void initialize_world_handler_thread_data(request_handler_thread_data_t *request_handler_data);
+void initialize_world_handlers(global_data_t *global_data,
                                h2o_hostconf_t *hostconf,
                                h2o_hostconf_t *hostconf,
                                h2o_access_log_filehandle_t *log_handle);
                                h2o_access_log_filehandle_t *log_handle);
 
 

+ 13 - 2
frameworks/C/h2o/src/request_handler.c

@@ -61,7 +61,11 @@ static const char *status_code_to_string(http_status_code_t status_code)
 void cleanup_request_handlers(global_data_t *global_data)
 void cleanup_request_handlers(global_data_t *global_data)
 {
 {
 	cleanup_fortunes_handler(global_data);
 	cleanup_fortunes_handler(global_data);
-	cleanup_world_handlers(global_data);
+}
+
+void free_request_handler_thread_data(request_handler_thread_data_t *request_handler_thread_data)
+{
+	free_world_handler_thread_data(request_handler_thread_data);
 }
 }
 
 
 const char *get_query_param(const char *query,
 const char *get_query_param(const char *query,
@@ -89,6 +93,13 @@ const char *get_query_param(const char *query,
 	return ret;
 	return ret;
 }
 }
 
 
+void initialize_request_handler_thread_data(
+		const config_t *config, request_handler_thread_data_t *request_handler_thread_data)
+{
+	IGNORE_FUNCTION_PARAMETER(config);
+	initialize_world_handler_thread_data(request_handler_thread_data);
+}
+
 void initialize_request_handlers(const config_t *config,
 void initialize_request_handlers(const config_t *config,
                                  global_data_t *global_data,
                                  global_data_t *global_data,
                                  h2o_hostconf_t *hostconf,
                                  h2o_hostconf_t *hostconf,
@@ -97,7 +108,7 @@ void initialize_request_handlers(const config_t *config,
 	initialize_fortunes_handler(config, global_data, hostconf, log_handle);
 	initialize_fortunes_handler(config, global_data, hostconf, log_handle);
 	initialize_json_serializer_handler(hostconf, log_handle);
 	initialize_json_serializer_handler(hostconf, log_handle);
 	initialize_plaintext_handler(hostconf, log_handle);
 	initialize_plaintext_handler(hostconf, log_handle);
-	initialize_world_handlers(config, global_data, hostconf, log_handle);
+	initialize_world_handlers(global_data, hostconf, log_handle);
 }
 }
 
 
 void register_request_handler(const char *path,
 void register_request_handler(const char *path,

+ 3 - 0
frameworks/C/h2o/src/request_handler.h

@@ -44,10 +44,13 @@ typedef enum {
 } http_status_code_t;
 } http_status_code_t;
 
 
 void cleanup_request_handlers(global_data_t *global_data);
 void cleanup_request_handlers(global_data_t *global_data);
+void free_request_handler_thread_data(request_handler_thread_data_t *request_handler_thread_data);
 const char *get_query_param(const char *query,
 const char *get_query_param(const char *query,
                             size_t query_len,
                             size_t query_len,
                             const char *param,
                             const char *param,
                             size_t param_len);
                             size_t param_len);
+void initialize_request_handler_thread_data(
+		const config_t *config, request_handler_thread_data_t *request_handler_thread_data);
 void initialize_request_handlers(const config_t *config,
 void initialize_request_handlers(const config_t *config,
                                  global_data_t *global_data,
                                  global_data_t *global_data,
                                  h2o_hostconf_t *hostconf,
                                  h2o_hostconf_t *hostconf,

+ 2 - 0
frameworks/C/h2o/src/thread.c

@@ -89,6 +89,7 @@ void free_thread_context(thread_context_t *ctx)
 {
 {
 	free_database_state(ctx->event_loop.h2o_ctx.loop, &ctx->db_state);
 	free_database_state(ctx->event_loop.h2o_ctx.loop, &ctx->db_state);
 	free_event_loop(&ctx->event_loop, &ctx->global_thread_data->h2o_receiver);
 	free_event_loop(&ctx->event_loop, &ctx->global_thread_data->h2o_receiver);
+	free_request_handler_thread_data(&ctx->request_handler_data);
 
 
 	if (ctx->json_generator)
 	if (ctx->json_generator)
 		do {
 		do {
@@ -135,6 +136,7 @@ void initialize_thread_context(global_thread_data_t *global_thread_data,
 	                      &global_thread_data->h2o_receiver,
 	                      &global_thread_data->h2o_receiver,
 	                      &ctx->event_loop);
 	                      &ctx->event_loop);
 	initialize_database_state(ctx->event_loop.h2o_ctx.loop, &ctx->db_state);
 	initialize_database_state(ctx->event_loop.h2o_ctx.loop, &ctx->db_state);
+	initialize_request_handler_thread_data(ctx->config, &ctx->request_handler_data);
 	global_thread_data->ctx = ctx;
 	global_thread_data->ctx = ctx;
 }
 }
 
 

+ 2 - 0
frameworks/C/h2o/src/thread.h

@@ -30,6 +30,7 @@
 #include "database.h"
 #include "database.h"
 #include "event_loop.h"
 #include "event_loop.h"
 #include "global_data.h"
 #include "global_data.h"
+#include "handlers/request_handler_data.h"
 
 
 typedef struct thread_context_t thread_context_t;
 typedef struct thread_context_t thread_context_t;
 
 
@@ -52,6 +53,7 @@ struct thread_context_t {
 	unsigned random_seed;
 	unsigned random_seed;
 	db_state_t db_state;
 	db_state_t db_state;
 	event_loop_t event_loop;
 	event_loop_t event_loop;
+	request_handler_thread_data_t request_handler_data;
 };
 };
 
 
 void free_thread_context(thread_context_t *ctx);
 void free_thread_context(thread_context_t *ctx);