diff options
author | Mark D. Roth <roth@google.com> | 2016-10-19 13:46:38 -0700 |
---|---|---|
committer | Mark D. Roth <roth@google.com> | 2016-10-19 13:46:38 -0700 |
commit | 29a7f40af3d08c70ab8ba23fe33eb073a3da7b7f (patch) | |
tree | 8d2d044852d76f01a040472312d33cc59fc09f2f /src/core/ext/client_config | |
parent | f222593de2ddf4afe9dbcfc4fdb32d03b2692ae7 (diff) |
Convert method config to a struct for use in the fast path.
Diffstat (limited to 'src/core/ext/client_config')
-rw-r--r-- | src/core/ext/client_config/client_channel.c | 6 | ||||
-rw-r--r-- | src/core/ext/client_config/method_config.c | 56 | ||||
-rw-r--r-- | src/core/ext/client_config/method_config.h | 16 |
3 files changed, 66 insertions, 12 deletions
diff --git a/src/core/ext/client_config/client_channel.c b/src/core/ext/client_config/client_channel.c index beaa9637c3..613e98922b 100644 --- a/src/core/ext/client_config/client_channel.c +++ b/src/core/ext/client_config/client_channel.c @@ -855,8 +855,7 @@ static void read_service_config(grpc_exec_ctx *exec_ctx, void *arg, // If the method config table was present, use it. if (method_config_table != NULL) { const grpc_method_config *method_config = - grpc_method_config_table_get_method_config(method_config_table, - calld->path); + grpc_method_config_table_get(method_config_table, calld->path); if (method_config != NULL) { const gpr_timespec *per_method_timeout = grpc_method_config_get_timeout(method_config); @@ -922,8 +921,7 @@ static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx, grpc_method_config_table_ref(chand->method_config_table); gpr_mu_unlock(&chand->mu); grpc_method_config *method_config = - grpc_method_config_table_get_method_config(method_config_table, - args->path); + grpc_method_config_table_get(method_config_table, args->path); if (method_config != NULL) { const gpr_timespec *per_method_timeout = grpc_method_config_get_timeout(method_config); diff --git a/src/core/ext/client_config/method_config.c b/src/core/ext/client_config/method_config.c index f8a82323e7..a42fe2bfd9 100644 --- a/src/core/ext/client_config/method_config.c +++ b/src/core/ext/client_config/method_config.c @@ -254,12 +254,12 @@ int grpc_method_config_table_cmp(const grpc_method_config_table* table1, return grpc_mdstr_hash_table_cmp(table1, table2); } -grpc_method_config* grpc_method_config_table_get_method_config( - const grpc_method_config_table* table, const grpc_mdstr* path) { - grpc_method_config* method_config = grpc_mdstr_hash_table_get(table, path); +void* grpc_method_config_table_get(const grpc_mdstr_hash_table* table, + const grpc_mdstr* path) { + void* value = grpc_mdstr_hash_table_get(table, path); // If we didn't find a match for the path, try looking for a wildcard // entry (i.e., change "/service/method" to "/service/*"). - if (method_config == NULL) { + if (value == NULL) { const char* path_str = grpc_mdstr_as_c_string(path); const char* sep = strrchr(path_str, '/') + 1; const size_t len = (size_t)(sep - path_str); @@ -269,10 +269,10 @@ grpc_method_config* grpc_method_config_table_get_method_config( buf[len + 1] = '\0'; grpc_mdstr* wildcard_path = grpc_mdstr_from_string(buf); gpr_free(buf); - method_config = grpc_mdstr_hash_table_get(table, wildcard_path); + value = grpc_mdstr_hash_table_get(table, wildcard_path); GRPC_MDSTR_UNREF(wildcard_path); } - return method_config; + return value; } static void* copy_arg(void* p) { return grpc_method_config_table_ref(p); } @@ -294,3 +294,47 @@ grpc_arg grpc_method_config_table_create_channel_arg( arg.value.pointer.vtable = &arg_vtable; return arg; } + +// State used by convert_entry() below. +typedef struct conversion_state { + void* (*convert_value)(const grpc_method_config* method_config); + const grpc_mdstr_hash_table_vtable* vtable; + size_t num_entries; + grpc_mdstr_hash_table_entry* entries; +} conversion_state; + +// A function to be passed to grpc_mdstr_hash_table_iterate() to create +// a copy of the entries. +static void convert_entry(const grpc_mdstr_hash_table_entry* entry, + void* user_data) { + conversion_state* state = user_data; + state->entries[state->num_entries].key = GRPC_MDSTR_REF(entry->key); + state->entries[state->num_entries].value = state->convert_value(entry->value); + state->entries[state->num_entries].vtable = state->vtable; + ++state->num_entries; +} + +grpc_mdstr_hash_table* grpc_method_config_table_convert( + const grpc_method_config_table* table, + void* (*convert_value)(const grpc_method_config* method_config), + const grpc_mdstr_hash_table_vtable* vtable) { + // Create an array of the entries in the table with converted values. + conversion_state state; + state.convert_value = convert_value; + state.vtable = vtable; + state.num_entries = 0; + state.entries = gpr_malloc(sizeof(grpc_mdstr_hash_table_entry) * + grpc_mdstr_hash_table_num_entries(table)); + grpc_mdstr_hash_table_iterate(table, convert_entry, &state); + // Create a new table based on the array we just constructed. + grpc_mdstr_hash_table* new_table = + grpc_mdstr_hash_table_create(state.num_entries, state.entries); + // Clean up the array. + for (size_t i = 0; i < state.num_entries; ++i) { + GRPC_MDSTR_UNREF(state.entries[i].key); + vtable->destroy_value(state.entries[i].value); + } + gpr_free(state.entries); + // Return the new table. + return new_table; +} diff --git a/src/core/ext/client_config/method_config.h b/src/core/ext/client_config/method_config.h index 1302ac425d..87c72ec064 100644 --- a/src/core/ext/client_config/method_config.h +++ b/src/core/ext/client_config/method_config.h @@ -106,11 +106,23 @@ int grpc_method_config_table_cmp(const grpc_method_config_table* table1, /// the form "/service/method". /// Returns NULL if the method has no config. /// Caller does NOT own a reference to the result. -grpc_method_config* grpc_method_config_table_get_method_config( - const grpc_method_config_table* table, const grpc_mdstr* path); +/// +/// Note: This returns a void* instead of a grpc_method_config* so that +/// it can also be used for tables constructed via +/// grpc_method_config_table_convert(). +void* grpc_method_config_table_get(const grpc_mdstr_hash_table* table, + const grpc_mdstr* path); /// Returns a channel arg containing \a table. grpc_arg grpc_method_config_table_create_channel_arg( grpc_method_config_table* table); +/// Generates a new table from \a table whose values are converted to a +/// new form via the \a convert_value function. The new table will use +/// \a vtable for its values. +grpc_mdstr_hash_table* grpc_method_config_table_convert( + const grpc_method_config_table* table, + void* (*convert_value)(const grpc_method_config* method_config), + const grpc_mdstr_hash_table_vtable* vtable); + #endif /* GRPC_CORE_EXT_CLIENT_CONFIG_METHOD_CONFIG_H */ |