diff options
Diffstat (limited to 'src/core')
47 files changed, 1257 insertions, 1264 deletions
diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c index 8f0c856afe..011a8411aa 100644 --- a/src/core/ext/client_channel/client_channel.c +++ b/src/core/ext/client_channel/client_channel.c @@ -96,7 +96,7 @@ static void method_parameters_del(grpc_exec_ctx *exec_ctx, void *p) { gpr_free(p); } -static const grpc_mdstr_hash_table_vtable method_parameters_vtable = { +static const grpc_slice_hash_table_vtable method_parameters_vtable = { method_parameters_del, method_parameters_copy, method_parameters_cmp}; static void *method_config_convert_value( @@ -131,7 +131,7 @@ typedef struct client_channel_channel_data { char *lb_policy_name; grpc_lb_policy *lb_policy; /** maps method names to method_parameters structs */ - grpc_mdstr_hash_table *method_params_table; + grpc_slice_hash_table *method_params_table; /** incoming resolver result - set by resolver.next() */ grpc_channel_args *resolver_result; /** a list of closures that are all waiting for config to come in */ @@ -232,7 +232,7 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg, char *lb_policy_name = NULL; grpc_lb_policy *lb_policy = NULL; grpc_lb_policy *old_lb_policy; - grpc_mdstr_hash_table *method_params_table = NULL; + grpc_slice_hash_table *method_params_table = NULL; grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE; bool exit_idle = false; grpc_error *state_error = GRPC_ERROR_CREATE("No load balancing policy"); @@ -316,7 +316,7 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg, old_lb_policy = chand->lb_policy; chand->lb_policy = lb_policy; if (chand->method_params_table != NULL) { - grpc_mdstr_hash_table_unref(exec_ctx, chand->method_params_table); + grpc_slice_hash_table_unref(exec_ctx, chand->method_params_table); } chand->method_params_table = method_params_table; if (lb_policy != NULL) { @@ -494,7 +494,7 @@ static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx, } gpr_free(chand->lb_policy_name); if (chand->method_params_table != NULL) { - grpc_mdstr_hash_table_unref(exec_ctx, chand->method_params_table); + grpc_slice_hash_table_unref(exec_ctx, chand->method_params_table); } grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker); grpc_pollset_set_destroy(chand->interested_parties); @@ -529,7 +529,7 @@ typedef struct client_channel_call_data { // to avoid this without breaking the grpc_deadline_state abstraction. grpc_deadline_state deadline_state; - grpc_mdstr *path; // Request path. + grpc_slice path; // Request path. gpr_timespec call_start_time; gpr_timespec deadline; wait_for_ready_value wait_for_ready_from_service_config; @@ -926,10 +926,10 @@ static void read_service_config(grpc_exec_ctx *exec_ctx, void *arg, if (error == GRPC_ERROR_NONE) { // Get the method config table from channel data. gpr_mu_lock(&chand->mu); - grpc_mdstr_hash_table *method_params_table = NULL; + grpc_slice_hash_table *method_params_table = NULL; if (chand->method_params_table != NULL) { method_params_table = - grpc_mdstr_hash_table_ref(chand->method_params_table); + grpc_slice_hash_table_ref(chand->method_params_table); } gpr_mu_unlock(&chand->mu); // If the method config table was present, use it. @@ -958,7 +958,7 @@ static void read_service_config(grpc_exec_ctx *exec_ctx, void *arg, gpr_mu_unlock(&calld->mu); } } - grpc_mdstr_hash_table_unref(exec_ctx, method_params_table); + grpc_slice_hash_table_unref(exec_ctx, method_params_table); } } GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "read_service_config"); @@ -996,8 +996,8 @@ static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx, if (chand->lb_policy != NULL) { // We already have a resolver result, so check for service config. if (chand->method_params_table != NULL) { - grpc_mdstr_hash_table *method_params_table = - grpc_mdstr_hash_table_ref(chand->method_params_table); + grpc_slice_hash_table *method_params_table = + grpc_slice_hash_table_ref(chand->method_params_table); gpr_mu_unlock(&chand->mu); method_parameters *method_params = grpc_method_config_table_get( exec_ctx, method_params_table, args->path); @@ -1013,7 +1013,7 @@ static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx, method_params->wait_for_ready; } } - grpc_mdstr_hash_table_unref(exec_ctx, method_params_table); + grpc_slice_hash_table_unref(exec_ctx, method_params_table); } else { gpr_mu_unlock(&chand->mu); } diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c index 6ba6254785..063b79cece 100644 --- a/src/core/ext/client_channel/subchannel.c +++ b/src/core/ext/client_channel/subchannel.c @@ -703,7 +703,7 @@ grpc_connected_subchannel *grpc_subchannel_get_connected_subchannel( grpc_error *grpc_connected_subchannel_create_call( grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con, - grpc_polling_entity *pollent, grpc_mdstr *path, gpr_timespec start_time, + grpc_polling_entity *pollent, grpc_slice path, gpr_timespec start_time, gpr_timespec deadline, grpc_subchannel_call **call) { grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con); *call = gpr_malloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size); diff --git a/src/core/ext/client_channel/subchannel.h b/src/core/ext/client_channel/subchannel.h index 10bae620df..e7a5bb4bbd 100644 --- a/src/core/ext/client_channel/subchannel.h +++ b/src/core/ext/client_channel/subchannel.h @@ -111,7 +111,7 @@ void grpc_subchannel_call_unref(grpc_exec_ctx *exec_ctx, /** construct a subchannel call */ grpc_error *grpc_connected_subchannel_create_call( grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *connected_subchannel, - grpc_polling_entity *pollent, grpc_mdstr *path, gpr_timespec start_time, + grpc_polling_entity *pollent, grpc_slice path, gpr_timespec start_time, gpr_timespec deadline, grpc_subchannel_call **subchannel_call); /** process a transport level op */ diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c index 4bca8def39..3e5c039fdd 100644 --- a/src/core/ext/lb_policy/grpclb/grpclb.c +++ b/src/core/ext/lb_policy/grpclb/grpclb.c @@ -447,7 +447,7 @@ static grpc_lb_addresses *process_serverlist( GPR_ARRAY_SIZE(server->load_balance_token); const size_t lb_token_length = strnlen(server->load_balance_token, lb_token_max_length); - grpc_mdstr *lb_token_mdstr = grpc_mdstr_from_buffer( + grpc_slice lb_token_mdstr = grpc_mdstr_from_buffer( (uint8_t *)server->load_balance_token, lb_token_length); user_data = grpc_mdelem_from_metadata_strings( exec_ctx, GRPC_MDSTR_LB_TOKEN, lb_token_mdstr); diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.c b/src/core/ext/transport/chttp2/transport/bin_decoder.c index 8db36e4a7f..1a3637a1e3 100644 --- a/src/core/ext/transport/chttp2/transport/bin_decoder.c +++ b/src/core/ext/transport/chttp2/transport/bin_decoder.c @@ -157,7 +157,7 @@ grpc_slice grpc_chttp2_base64_decode(grpc_exec_ctx *exec_ctx, "grpc_chttp2_base64_decode has a length of %d, which is not a " "multiple of 4.\n", (int)input_length); - return gpr_empty_slice(); + return grpc_empty_slice(); } if (input_length > 0) { @@ -182,7 +182,7 @@ grpc_slice grpc_chttp2_base64_decode(grpc_exec_ctx *exec_ctx, gpr_log(GPR_ERROR, "Base64 decoding failed, input string:\n%s\n", s); gpr_free(s); grpc_slice_unref_internal(exec_ctx, output); - return gpr_empty_slice(); + return grpc_empty_slice(); } GPR_ASSERT(ctx.output_cur == GRPC_SLICE_END_PTR(output)); GPR_ASSERT(ctx.input_cur == GRPC_SLICE_END_PTR(input)); @@ -204,7 +204,7 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx *exec_ctx, "has a tail of 1 byte.\n", (int)input_length); grpc_slice_unref_internal(exec_ctx, output); - return gpr_empty_slice(); + return grpc_empty_slice(); } if (output_length > input_length / 4 * 3 + tail_xtra[input_length % 4]) { @@ -214,7 +214,7 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx *exec_ctx, (int)output_length, (int)(input_length / 4 * 3 + tail_xtra[input_length % 4])); grpc_slice_unref_internal(exec_ctx, output); - return gpr_empty_slice(); + return grpc_empty_slice(); } ctx.input_cur = GRPC_SLICE_START_PTR(input); @@ -228,7 +228,7 @@ grpc_slice grpc_chttp2_base64_decode_with_length(grpc_exec_ctx *exec_ctx, gpr_log(GPR_ERROR, "Base64 decoding failed, input string:\n%s\n", s); gpr_free(s); grpc_slice_unref_internal(exec_ctx, output); - return gpr_empty_slice(); + return grpc_empty_slice(); } GPR_ASSERT(ctx.output_cur == GRPC_SLICE_END_PTR(output)); GPR_ASSERT(ctx.input_cur <= GRPC_SLICE_END_PTR(input)); diff --git a/src/core/ext/transport/chttp2/transport/bin_encoder.c b/src/core/ext/transport/chttp2/transport/bin_encoder.c index af25a4352a..e301c073f3 100644 --- a/src/core/ext/transport/chttp2/transport/bin_encoder.c +++ b/src/core/ext/transport/chttp2/transport/bin_encoder.c @@ -177,8 +177,7 @@ static void enc_add1(huff_out *out, uint8_t a) { enc_flush_some(out); } -grpc_slice grpc_chttp2_base64_encode_and_huffman_compress_impl( - grpc_slice input) { +grpc_slice grpc_chttp2_base64_encode_and_huffman_compress(grpc_slice input) { size_t input_length = GRPC_SLICE_LENGTH(input); size_t input_triplets = input_length / 3; size_t tail_case = input_length % 3; diff --git a/src/core/ext/transport/chttp2/transport/bin_encoder.h b/src/core/ext/transport/chttp2/transport/bin_encoder.h index 477559d0e2..0f899c8e34 100644 --- a/src/core/ext/transport/chttp2/transport/bin_encoder.h +++ b/src/core/ext/transport/chttp2/transport/bin_encoder.h @@ -49,7 +49,6 @@ grpc_slice grpc_chttp2_huffman_compress(grpc_slice input); grpc_slice y = grpc_chttp2_huffman_compress(x); grpc_slice_unref_internal(exec_ctx, x); return y; */ -grpc_slice grpc_chttp2_base64_encode_and_huffman_compress_impl( - grpc_slice input); +grpc_slice grpc_chttp2_base64_encode_and_huffman_compress(grpc_slice input); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_ENCODER_H */ diff --git a/src/core/ext/transport/chttp2/transport/chttp2_plugin.c b/src/core/ext/transport/chttp2/transport/chttp2_plugin.c index bd87253ed3..59b21e3330 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_plugin.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_plugin.c @@ -31,14 +31,11 @@ * */ -#include "src/core/ext/transport/chttp2/transport/bin_encoder.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/transport/metadata.h" void grpc_chttp2_plugin_init(void) { - grpc_chttp2_base64_encode_and_huffman_compress = - grpc_chttp2_base64_encode_and_huffman_compress_impl; grpc_register_tracer("http", &grpc_http_trace); grpc_register_tracer("flowctl", &grpc_flowctl_trace); } diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 7baeddc7b8..fac9a08584 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -876,7 +876,7 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx, static bool contains_non_ok_status(grpc_metadata_batch *batch) { grpc_linked_mdelem *l; for (l = batch->list.head; l; l = l->next) { - if (l->md->key == GRPC_MDSTR_GRPC_STATUS && + if (grpc_slice_cmp(l->md->key, GRPC_MDSTR_GRPC_STATUS) == 0 && l->md != GRPC_MDELEM_GRPC_STATUS_0) { return true; } @@ -1477,16 +1477,14 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, char status_string[GPR_LTOA_MIN_BUFSIZE]; gpr_ltoa(status, status_string); grpc_chttp2_incoming_metadata_buffer_add( - &s->metadata_buffer[1], grpc_mdelem_from_metadata_strings( - exec_ctx, GRPC_MDSTR_GRPC_STATUS, - grpc_mdstr_from_string(status_string))); + &s->metadata_buffer[1], + grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_STATUS, + grpc_slice_from_copied_string(status_string))); if (slice) { grpc_chttp2_incoming_metadata_buffer_add( &s->metadata_buffer[1], - grpc_mdelem_from_metadata_strings( - exec_ctx, GRPC_MDSTR_GRPC_MESSAGE, - grpc_mdstr_from_slice(exec_ctx, - grpc_slice_ref_internal(*slice)))); + grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_MESSAGE, + grpc_slice_ref_internal(*slice))); } s->published_metadata[1] = GRPC_METADATA_SYNTHESIZED_FROM_FAKE; grpc_chttp2_maybe_complete_recv_trailing_metadata(exec_ctx, t, s); diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c index 49a8326f62..9b27071c87 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.c +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.c @@ -64,6 +64,10 @@ /* don't consider adding anything bigger than this to the hpack table */ #define MAX_DECODER_SPACE_USAGE 512 +static grpc_slice_refcount terminal_slice_refcount = {NULL, NULL}; +static const grpc_slice terminal_slice = {&terminal_slice_refcount, + .data.refcounted = {0, 0}}; + extern int grpc_http_trace; typedef struct { @@ -186,8 +190,9 @@ static void evict_entry(grpc_chttp2_hpack_compressor *c) { /* add an element to the decoder table */ static void add_elem(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem) { - uint32_t key_hash = elem->key->hash; - uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, elem->value->hash); + uint32_t key_hash = grpc_slice_hash(elem->key); + uint32_t value_hash = grpc_slice_hash(elem->value); + uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, value_hash); uint32_t new_index = c->tail_remote_index + c->table_elems + 1; size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem); @@ -241,24 +246,34 @@ static void add_elem(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c, /* do exactly the same for the key (so we can find by that again too) */ - if (c->entries_keys[HASH_FRAGMENT_2(key_hash)] == elem->key) { + if (grpc_slice_cmp(c->entries_keys[HASH_FRAGMENT_2(key_hash)], elem->key) == + 0) { c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index; - } else if (c->entries_keys[HASH_FRAGMENT_3(key_hash)] == elem->key) { + } else if (grpc_slice_cmp(c->entries_keys[HASH_FRAGMENT_3(key_hash)], + elem->key) == 0) { c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index; - } else if (c->entries_keys[HASH_FRAGMENT_2(key_hash)] == NULL) { - c->entries_keys[HASH_FRAGMENT_2(key_hash)] = GRPC_MDSTR_REF(elem->key); + } else if (c->entries_keys[HASH_FRAGMENT_2(key_hash)].refcount == + &terminal_slice_refcount) { + c->entries_keys[HASH_FRAGMENT_2(key_hash)] = + grpc_slice_ref_internal(elem->key); c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index; - } else if (c->entries_keys[HASH_FRAGMENT_3(key_hash)] == NULL) { - c->entries_keys[HASH_FRAGMENT_3(key_hash)] = GRPC_MDSTR_REF(elem->key); + } else if (c->entries_keys[HASH_FRAGMENT_3(key_hash)].refcount == + &terminal_slice_refcount) { + c->entries_keys[HASH_FRAGMENT_3(key_hash)] = + grpc_slice_ref_internal(elem->key); c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index; } else if (c->indices_keys[HASH_FRAGMENT_2(key_hash)] < c->indices_keys[HASH_FRAGMENT_3(key_hash)]) { - GRPC_MDSTR_UNREF(exec_ctx, c->entries_keys[HASH_FRAGMENT_2(key_hash)]); - c->entries_keys[HASH_FRAGMENT_2(key_hash)] = GRPC_MDSTR_REF(elem->key); + grpc_slice_unref_internal(exec_ctx, + c->entries_keys[HASH_FRAGMENT_2(key_hash)]); + c->entries_keys[HASH_FRAGMENT_2(key_hash)] = + grpc_slice_ref_internal(elem->key); c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index; } else { - GRPC_MDSTR_UNREF(exec_ctx, c->entries_keys[HASH_FRAGMENT_3(key_hash)]); - c->entries_keys[HASH_FRAGMENT_3(key_hash)] = GRPC_MDSTR_REF(elem->key); + grpc_slice_unref_internal(exec_ctx, + c->entries_keys[HASH_FRAGMENT_3(key_hash)]); + c->entries_keys[HASH_FRAGMENT_3(key_hash)] = + grpc_slice_ref_internal(elem->key); c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index; } } @@ -271,15 +286,13 @@ static void emit_indexed(grpc_chttp2_hpack_compressor *c, uint32_t elem_index, } static grpc_slice get_wire_value(grpc_mdelem *elem, uint8_t *huffman_prefix) { - if (grpc_is_binary_header( - (const char *)GRPC_SLICE_START_PTR(elem->key->slice), - GRPC_SLICE_LENGTH(elem->key->slice))) { + if (grpc_slice_is_binary_header(elem->key)) { *huffman_prefix = 0x80; - return grpc_mdstr_as_base64_encoded_and_huffman_compressed(elem->value); + return grpc_chttp2_base64_encode_and_huffman_compress(elem->value); } /* TODO(ctiller): opportunistically compress non-binary headers */ *huffman_prefix = 0x00; - return elem->value->slice; + return grpc_slice_ref(elem->value); } static void emit_lithdr_incidx(grpc_chttp2_hpack_compressor *c, @@ -296,7 +309,7 @@ static void emit_lithdr_incidx(grpc_chttp2_hpack_compressor *c, add_tiny_header_data(st, len_pfx), len_pfx); GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, huffman_prefix, add_tiny_header_data(st, len_val_len), len_val_len); - add_header_data(st, grpc_slice_ref_internal(value_slice)); + add_header_data(st, value_slice); } static void emit_lithdr_noidx(grpc_chttp2_hpack_compressor *c, @@ -313,12 +326,12 @@ static void emit_lithdr_noidx(grpc_chttp2_hpack_compressor *c, add_tiny_header_data(st, len_pfx), len_pfx); GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, huffman_prefix, add_tiny_header_data(st, len_val_len), len_val_len); - add_header_data(st, grpc_slice_ref_internal(value_slice)); + add_header_data(st, value_slice); } static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem, framer_state *st) { - uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(elem->key->slice); + uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(elem->key); uint8_t huffman_prefix; grpc_slice value_slice = get_wire_value(elem, &huffman_prefix); uint32_t len_val = (uint32_t)GRPC_SLICE_LENGTH(value_slice); @@ -329,15 +342,15 @@ static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor *c, *add_tiny_header_data(st, 1) = 0x40; GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00, add_tiny_header_data(st, len_key_len), len_key_len); - add_header_data(st, grpc_slice_ref_internal(elem->key->slice)); + add_header_data(st, grpc_slice_ref_internal(elem->key)); GRPC_CHTTP2_WRITE_VARINT(len_val, 1, huffman_prefix, add_tiny_header_data(st, len_val_len), len_val_len); - add_header_data(st, grpc_slice_ref_internal(value_slice)); + add_header_data(st, value_slice); } static void emit_lithdr_noidx_v(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem, framer_state *st) { - uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(elem->key->slice); + uint32_t len_key = (uint32_t)GRPC_SLICE_LENGTH(elem->key); uint8_t huffman_prefix; grpc_slice value_slice = get_wire_value(elem, &huffman_prefix); uint32_t len_val = (uint32_t)GRPC_SLICE_LENGTH(value_slice); @@ -348,10 +361,10 @@ static void emit_lithdr_noidx_v(grpc_chttp2_hpack_compressor *c, *add_tiny_header_data(st, 1) = 0x00; GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00, add_tiny_header_data(st, len_key_len), len_key_len); - add_header_data(st, grpc_slice_ref_internal(elem->key->slice)); + add_header_data(st, grpc_slice_ref_internal(elem->key)); GRPC_CHTTP2_WRITE_VARINT(len_val, 1, huffman_prefix, add_tiny_header_data(st, len_val_len), len_val_len); - add_header_data(st, grpc_slice_ref_internal(value_slice)); + add_header_data(st, value_slice); } static void emit_advertise_table_size_change(grpc_chttp2_hpack_compressor *c, @@ -370,14 +383,15 @@ static uint32_t dynidx(grpc_chttp2_hpack_compressor *c, uint32_t elem_index) { /* encode an mdelem */ static void hpack_enc(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem, framer_state *st) { - uint32_t key_hash = elem->key->hash; - uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, elem->value->hash); + uint32_t key_hash = grpc_slice_hash(elem->key); + uint32_t value_hash = grpc_slice_hash(elem->value); + uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, value_hash); size_t decoder_space_usage; uint32_t indices_key; int should_add_elem; - GPR_ASSERT(GRPC_SLICE_LENGTH(elem->key->slice) > 0); - if (GRPC_SLICE_START_PTR(elem->key->slice)[0] != ':') { /* regular header */ + GPR_ASSERT(GRPC_SLICE_LENGTH(elem->key) > 0); + if (GRPC_SLICE_START_PTR(elem->key)[0] != ':') { /* regular header */ st->seen_regular_header = 1; } else { GPR_ASSERT( @@ -414,7 +428,8 @@ static void hpack_enc(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c, /* no hits for the elem... maybe there's a key? */ indices_key = c->indices_keys[HASH_FRAGMENT_2(key_hash)]; - if (c->entries_keys[HASH_FRAGMENT_2(key_hash)] == elem->key && + if (grpc_slice_cmp(c->entries_keys[HASH_FRAGMENT_2(key_hash)], elem->key) == + 0 && indices_key > c->tail_remote_index) { /* HIT: key (first cuckoo hash) */ if (should_add_elem) { @@ -429,7 +444,8 @@ static void hpack_enc(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c, } indices_key = c->indices_keys[HASH_FRAGMENT_3(key_hash)]; - if (c->entries_keys[HASH_FRAGMENT_3(key_hash)] == elem->key && + if (grpc_slice_cmp(c->entries_keys[HASH_FRAGMENT_3(key_hash)], elem->key) == + 0 && indices_key > c->tail_remote_index) { /* HIT: key (first cuckoo hash) */ if (should_add_elem) { @@ -466,8 +482,8 @@ static void deadline_enc(grpc_exec_ctx *exec_ctx, grpc_mdelem *mdelem; grpc_http2_encode_timeout( gpr_time_sub(deadline, gpr_now(deadline.clock_type)), timeout_str); - mdelem = grpc_mdelem_from_metadata_strings( - exec_ctx, GRPC_MDSTR_GRPC_TIMEOUT, grpc_mdstr_from_string(timeout_str)); + mdelem = grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_TIMEOUT, + grpc_slice_from_copied_string(timeout_str)); hpack_enc(exec_ctx, c, mdelem, st); GRPC_MDELEM_UNREF(exec_ctx, mdelem); } @@ -484,14 +500,21 @@ void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c) { gpr_malloc(sizeof(*c->table_elem_size) * c->cap_table_elems); memset(c->table_elem_size, 0, sizeof(*c->table_elem_size) * c->cap_table_elems); + for (size_t i = 0; i < GPR_ARRAY_SIZE(c->entries_keys); i++) { + c->entries_keys[i] = terminal_slice; + } } void grpc_chttp2_hpack_compressor_destroy(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c) { int i; for (i = 0; i < GRPC_CHTTP2_HPACKC_NUM_VALUES; i++) { - if (c->entries_keys[i]) GRPC_MDSTR_UNREF(exec_ctx, c->entries_keys[i]); - if (c->entries_elems[i]) GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[i]); + if (c->entries_keys[i].refcount != &terminal_slice_refcount) { + grpc_slice_unref_internal(exec_ctx, c->entries_keys[i]); + } + if (c->entries_elems[i]) { + GRPC_MDELEM_UNREF(exec_ctx, c->entries_elems[i]); + } } gpr_free(c->table_elem_size); } diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.h b/src/core/ext/transport/chttp2/transport/hpack_encoder.h index 3a35496ec8..82d61a15ec 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.h +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.h @@ -74,7 +74,7 @@ typedef struct { /* entry tables for keys & elems: these tables track values that have been seen and *may* be in the decompressor table */ - grpc_mdstr *entries_keys[GRPC_CHTTP2_HPACKC_NUM_VALUES]; + grpc_slice entries_keys[GRPC_CHTTP2_HPACKC_NUM_VALUES]; grpc_mdelem *entries_elems[GRPC_CHTTP2_HPACKC_NUM_VALUES]; uint32_t indices_keys[GRPC_CHTTP2_HPACKC_NUM_VALUES]; uint32_t indices_elems[GRPC_CHTTP2_HPACKC_NUM_VALUES]; diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c index f4e69df12d..86c65d4b5a 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.c +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c @@ -52,6 +52,7 @@ #include "src/core/ext/transport/chttp2/transport/bin_encoder.h" #include "src/core/ext/transport/chttp2/transport/http2_errors.h" #include "src/core/lib/profiling/timers.h" +#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/support/string.h" extern int grpc_http_trace; @@ -681,9 +682,9 @@ static grpc_error *on_hdr(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_parser *p, return GRPC_ERROR_NONE; } -static grpc_mdstr *take_string(grpc_chttp2_hpack_parser *p, - grpc_chttp2_hpack_parser_string *str) { - grpc_mdstr *s = grpc_mdstr_from_buffer((uint8_t *)str->str, str->length); +static grpc_slice take_string(grpc_chttp2_hpack_parser *p, + grpc_chttp2_hpack_parser_string *str) { + grpc_slice s = grpc_slice_from_copied_buffer(str->str, str->length); str->length = 0; return s; } @@ -815,10 +816,11 @@ static grpc_error *finish_lithdr_incidx(grpc_exec_ctx *exec_ctx, const uint8_t *end) { grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index); GPR_ASSERT(md != NULL); /* handled in string parsing */ - grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings( - exec_ctx, GRPC_MDSTR_REF(md->key), - take_string(p, &p->value)), - 1); + grpc_error *err = + on_hdr(exec_ctx, p, + grpc_mdelem_from_slices(exec_ctx, grpc_slice_ref_internal(md->key), + take_string(p, &p->value)), + 1); if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); return parse_begin(exec_ctx, p, cur, end); } @@ -828,10 +830,10 @@ static grpc_error *finish_lithdr_incidx_v(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { - grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings( - exec_ctx, take_string(p, &p->key), - take_string(p, &p->value)), - 1); + grpc_error *err = on_hdr( + exec_ctx, p, grpc_mdelem_from_slices(exec_ctx, take_string(p, &p->key), + take_string(p, &p->value)), + 1); if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); return parse_begin(exec_ctx, p, cur, end); } @@ -883,10 +885,11 @@ static grpc_error *finish_lithdr_notidx(grpc_exec_ctx *exec_ctx, const uint8_t *end) { grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index); GPR_ASSERT(md != NULL); /* handled in string parsing */ - grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings( - exec_ctx, GRPC_MDSTR_REF(md->key), - take_string(p, &p->value)), - 0); + grpc_error *err = + on_hdr(exec_ctx, p, + grpc_mdelem_from_slices(exec_ctx, grpc_slice_ref_internal(md->key), + take_string(p, &p->value)), + 0); if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); return parse_begin(exec_ctx, p, cur, end); } @@ -896,10 +899,10 @@ static grpc_error *finish_lithdr_notidx_v(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { - grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings( - exec_ctx, take_string(p, &p->key), - take_string(p, &p->value)), - 0); + grpc_error *err = on_hdr( + exec_ctx, p, grpc_mdelem_from_slices(exec_ctx, take_string(p, &p->key), + take_string(p, &p->value)), + 0); if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); return parse_begin(exec_ctx, p, cur, end); } @@ -951,10 +954,11 @@ static grpc_error *finish_lithdr_nvridx(grpc_exec_ctx *exec_ctx, const uint8_t *end) { grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index); GPR_ASSERT(md != NULL); /* handled in string parsing */ - grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings( - exec_ctx, GRPC_MDSTR_REF(md->key), - take_string(p, &p->value)), - 0); + grpc_error *err = + on_hdr(exec_ctx, p, + grpc_mdelem_from_slices(exec_ctx, grpc_slice_ref_internal(md->key), + take_string(p, &p->value)), + 0); if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); return parse_begin(exec_ctx, p, cur, end); } @@ -964,10 +968,10 @@ static grpc_error *finish_lithdr_nvridx_v(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_parser *p, const uint8_t *cur, const uint8_t *end) { - grpc_error *err = on_hdr(exec_ctx, p, grpc_mdelem_from_metadata_strings( - exec_ctx, take_string(p, &p->key), - take_string(p, &p->value)), - 0); + grpc_error *err = on_hdr( + exec_ctx, p, grpc_mdelem_from_slices(exec_ctx, take_string(p, &p->key), + take_string(p, &p->value)), + 0); if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err); return parse_begin(exec_ctx, p, cur, end); } @@ -1502,9 +1506,7 @@ static grpc_error *is_binary_indexed_header(grpc_chttp2_hpack_parser *p, GRPC_ERROR_INT_INDEX, (intptr_t)p->index), GRPC_ERROR_INT_SIZE, (intptr_t)p->table.num_ents); } - *is = grpc_is_binary_header( - (const char *)GRPC_SLICE_START_PTR(elem->key->slice), - GRPC_SLICE_LENGTH(elem->key->slice)); + *is = grpc_slice_is_binary_header(elem->key); return GRPC_ERROR_NONE; } diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.c b/src/core/ext/transport/chttp2/transport/hpack_table.c index 26d4036d49..9124e37c45 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_table.c +++ b/src/core/ext/transport/chttp2/transport/hpack_table.c @@ -190,8 +190,11 @@ void grpc_chttp2_hptbl_init(grpc_exec_ctx *exec_ctx, grpc_chttp2_hptbl *tbl) { tbl->ents = gpr_malloc(sizeof(*tbl->ents) * tbl->cap_entries); memset(tbl->ents, 0, sizeof(*tbl->ents) * tbl->cap_entries); for (i = 1; i <= GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) { - tbl->static_ents[i - 1] = grpc_mdelem_from_strings( - exec_ctx, static_table[i].key, static_table[i].value); + tbl->static_ents[i - 1] = grpc_mdelem_from_slices( + exec_ctx, + grpc_slice_intern(grpc_slice_from_static_string(static_table[i].key)), + grpc_slice_intern( + grpc_slice_from_static_string(static_table[i].value))); } } @@ -228,8 +231,8 @@ grpc_mdelem *grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl *tbl, /* Evict one element from the table */ static void evict1(grpc_exec_ctx *exec_ctx, grpc_chttp2_hptbl *tbl) { grpc_mdelem *first_ent = tbl->ents[tbl->first_ent]; - size_t elem_bytes = GRPC_SLICE_LENGTH(first_ent->key->slice) + - GRPC_SLICE_LENGTH(first_ent->value->slice) + + size_t elem_bytes = GRPC_SLICE_LENGTH(first_ent->key) + + GRPC_SLICE_LENGTH(first_ent->value) + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD; GPR_ASSERT(elem_bytes <= tbl->mem_used); tbl->mem_used -= (uint32_t)elem_bytes; @@ -303,8 +306,8 @@ grpc_error *grpc_chttp2_hptbl_set_current_table_size(grpc_exec_ctx *exec_ctx, grpc_error *grpc_chttp2_hptbl_add(grpc_exec_ctx *exec_ctx, grpc_chttp2_hptbl *tbl, grpc_mdelem *md) { /* determine how many bytes of buffer this entry represents */ - size_t elem_bytes = GRPC_SLICE_LENGTH(md->key->slice) + - GRPC_SLICE_LENGTH(md->value->slice) + + size_t elem_bytes = GRPC_SLICE_LENGTH(md->key) + + GRPC_SLICE_LENGTH(md->value) + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD; if (tbl->current_table_bytes > tbl->max_bytes) { @@ -359,9 +362,9 @@ grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find( /* See if the string is in the static table */ for (i = 0; i < GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) { grpc_mdelem *ent = tbl->static_ents[i]; - if (md->key != ent->key) continue; + if (grpc_slice_cmp(md->key, ent->key) != 0) continue; r.index = i + 1u; - r.has_value = md->value == ent->value; + r.has_value = grpc_slice_cmp(md->value, ent->value) == 0; if (r.has_value) return r; } @@ -370,9 +373,9 @@ grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find( uint32_t idx = (uint32_t)(tbl->num_ents - i + GRPC_CHTTP2_LAST_STATIC_ENTRY); grpc_mdelem *ent = tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]; - if (md->key != ent->key) continue; + if (grpc_slice_cmp(md->key, ent->key) != 0) continue; r.index = idx; - r.has_value = md->value == ent->value; + r.has_value = grpc_slice_cmp(md->value, ent->value) == 0; if (r.has_value) return r; } diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index 4fb5dc7bd2..b8ab987104 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -200,7 +200,7 @@ grpc_error *grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx, return err; } if (t->incoming_frame_size == 0) { - err = parse_frame_slice(exec_ctx, t, gpr_empty_slice(), 1); + err = parse_frame_slice(exec_ctx, t, grpc_empty_slice(), 1); if (err != GRPC_ERROR_NONE) { return err; } diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c index 285ac178af..0f3957d5ac 100644 --- a/src/core/lib/channel/channel_stack.c +++ b/src/core/lib/channel/channel_stack.c @@ -162,7 +162,7 @@ grpc_error *grpc_call_stack_init( grpc_exec_ctx *exec_ctx, grpc_channel_stack *channel_stack, int initial_refs, grpc_iomgr_cb_func destroy, void *destroy_arg, grpc_call_context_element *context, const void *transport_server_data, - grpc_mdstr *path, gpr_timespec start_time, gpr_timespec deadline, + grpc_slice path, gpr_timespec start_time, gpr_timespec deadline, grpc_call_stack *call_stack) { grpc_channel_element *channel_elems = CHANNEL_ELEMS_FROM_STACK(channel_stack); grpc_call_element_args args; diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index 004643d45f..376756533b 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -74,7 +74,7 @@ typedef struct { grpc_call_stack *call_stack; const void *server_transport_data; grpc_call_context_element *context; - grpc_mdstr *path; + grpc_slice path; gpr_timespec start_time; gpr_timespec deadline; } grpc_call_element_args; @@ -231,7 +231,7 @@ grpc_error *grpc_call_stack_init( grpc_exec_ctx *exec_ctx, grpc_channel_stack *channel_stack, int initial_refs, grpc_iomgr_cb_func destroy, void *destroy_arg, grpc_call_context_element *context, const void *transport_server_data, - grpc_mdstr *path, gpr_timespec start_time, gpr_timespec deadline, + grpc_slice path, gpr_timespec start_time, gpr_timespec deadline, grpc_call_stack *call_stack); /* Set a pollset or a pollset_set for a call stack: must occur before the first * op is started */ diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c index 96188f01c4..96564757b4 100644 --- a/src/core/lib/channel/compress_filter.c +++ b/src/core/lib/channel/compress_filter.c @@ -45,6 +45,7 @@ #include "src/core/lib/compression/message_compress.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/support/string.h" #include "src/core/lib/transport/static_metadata.h" @@ -89,21 +90,23 @@ static grpc_mdelem *compression_md_filter(grpc_exec_ctx *exec_ctx, call_data *calld = elem->call_data; channel_data *channeld = elem->channel_data; - if (md->key == GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST) { - const char *md_c_str = grpc_mdstr_as_c_string(md->value); - if (!grpc_compression_algorithm_parse(md_c_str, strlen(md_c_str), + if (grpc_slice_cmp(md->key, GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST) == 0) { + if (!grpc_compression_algorithm_parse(md->value, &calld->compression_algorithm)) { + char *val = grpc_dump_slice(md->value, GPR_DUMP_ASCII); gpr_log(GPR_ERROR, - "Invalid compression algorithm: '%s' (unknown). Ignoring.", - md_c_str); + "Invalid compression algorithm: '%s' (unknown). Ignoring.", val); + gpr_free(val); calld->compression_algorithm = GRPC_COMPRESS_NONE; } if (!GPR_BITGET(channeld->enabled_algorithms_bitset, calld->compression_algorithm)) { + char *val = grpc_dump_slice(md->value, GPR_DUMP_ASCII); gpr_log(GPR_ERROR, "Invalid compression algorithm: '%s' (previously disabled). " "Ignoring.", - md_c_str); + val); + gpr_free(val); calld->compression_algorithm = GRPC_COMPRESS_NONE; } calld->has_compression_algorithm = 1; diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c index 27064e0fb8..4b62a35750 100644 --- a/src/core/lib/channel/http_client_filter.c +++ b/src/core/lib/channel/http_client_filter.c @@ -38,6 +38,7 @@ #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/percent_encoding.h" #include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/support/string.h" #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/transport_impl.h" @@ -98,34 +99,34 @@ static grpc_mdelem *client_recv_filter(grpc_exec_ctx *exec_ctx, void *user_data, grpc_call_element *elem = user_data; if (md == GRPC_MDELEM_STATUS_200) { return NULL; - } else if (md->key == GRPC_MDSTR_STATUS) { + } else if (grpc_slice_cmp(md->key, GRPC_MDSTR_STATUS) == 0) { char *message_string; - gpr_asprintf(&message_string, "Received http2 header with status: %s", - grpc_mdstr_as_c_string(md->value)); + char *val = grpc_dump_slice(md->value, GPR_DUMP_ASCII); + gpr_asprintf(&message_string, "Received http2 header with status: %s", val); grpc_slice message = grpc_slice_from_copied_string(message_string); gpr_free(message_string); + gpr_free(val); grpc_call_element_send_close_with_message(exec_ctx, elem, GRPC_STATUS_CANCELLED, &message); return NULL; - } else if (md->key == GRPC_MDSTR_GRPC_MESSAGE) { + } else if (grpc_slice_cmp(md->key, GRPC_MDSTR_GRPC_MESSAGE) == 0) { grpc_slice pct_decoded_msg = - grpc_permissive_percent_decode_slice(md->value->slice); - if (grpc_slice_is_equivalent(pct_decoded_msg, md->value->slice)) { + grpc_permissive_percent_decode_slice(md->value); + if (grpc_slice_is_equivalent(pct_decoded_msg, md->value)) { grpc_slice_unref(pct_decoded_msg); return md; } else { - return grpc_mdelem_from_metadata_strings( - exec_ctx, GRPC_MDSTR_GRPC_MESSAGE, - grpc_mdstr_from_slice(exec_ctx, pct_decoded_msg)); + return grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_MESSAGE, + pct_decoded_msg); } } else if (md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) { return NULL; - } else if (md->key == GRPC_MDSTR_CONTENT_TYPE) { - const char *value_str = grpc_mdstr_as_c_string(md->value); - if (strncmp(value_str, EXPECTED_CONTENT_TYPE, - EXPECTED_CONTENT_TYPE_LENGTH) == 0 && - (value_str[EXPECTED_CONTENT_TYPE_LENGTH] == '+' || - value_str[EXPECTED_CONTENT_TYPE_LENGTH] == ';')) { + } else if (grpc_slice_cmp(md->key, GRPC_MDSTR_CONTENT_TYPE) == 0) { + if (grpc_slice_buf_start_eq(md->value, EXPECTED_CONTENT_TYPE, + EXPECTED_CONTENT_TYPE_LENGTH) && + (GRPC_SLICE_START_PTR(md->value)[EXPECTED_CONTENT_TYPE_LENGTH] == '+' || + GRPC_SLICE_START_PTR(md->value)[EXPECTED_CONTENT_TYPE_LENGTH] == + ';')) { /* Although the C implementation doesn't (currently) generate them, any custom +-suffix is explicitly valid. */ /* TODO(klempner): We should consider preallocating common values such @@ -134,7 +135,9 @@ static grpc_mdelem *client_recv_filter(grpc_exec_ctx *exec_ctx, void *user_data, } else { /* TODO(klempner): We're currently allowing this, but we shouldn't see it without a proxy so log for now. */ - gpr_log(GPR_INFO, "Unexpected content-type '%s'", value_str); + char *val = grpc_dump_slice(md->value, GPR_DUMP_ASCII); + gpr_log(GPR_INFO, "Unexpected content-type '%s'", val); + gpr_free(val); } return NULL; } @@ -182,11 +185,11 @@ static void send_done(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) { static grpc_mdelem *client_strip_filter(grpc_exec_ctx *exec_ctx, void *user_data, grpc_mdelem *md) { /* eat the things we'd like to set ourselves */ - if (md->key == GRPC_MDSTR_METHOD) return NULL; - if (md->key == GRPC_MDSTR_SCHEME) return NULL; - if (md->key == GRPC_MDSTR_TE) return NULL; - if (md->key == GRPC_MDSTR_CONTENT_TYPE) return NULL; - if (md->key == GRPC_MDSTR_USER_AGENT) return NULL; + if (grpc_slice_cmp(md->key, GRPC_MDSTR_METHOD) == 0) return NULL; + if (grpc_slice_cmp(md->key, GRPC_MDSTR_SCHEME) == 0) return NULL; + if (grpc_slice_cmp(md->key, GRPC_MDSTR_TE) == 0) return NULL; + if (grpc_slice_cmp(md->key, GRPC_MDSTR_CONTENT_TYPE) == 0) return NULL; + if (grpc_slice_cmp(md->key, GRPC_MDSTR_USER_AGENT) == 0) return NULL; return md; } @@ -264,10 +267,10 @@ static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, if (calld->send_message_blocked == false) { /* when all the send_message data is available, then create a MDELEM and append to headers */ - grpc_mdelem *payload_bin = grpc_mdelem_from_metadata_strings( + grpc_mdelem *payload_bin = grpc_mdelem_from_slices( exec_ctx, GRPC_MDSTR_GRPC_PAYLOAD_BIN, - grpc_mdstr_from_buffer(calld->payload_bytes, - op->send_message->length)); + grpc_slice_from_copied_buffer((const char *)calld->payload_bytes, + op->send_message->length)); grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->payload_bin, payload_bin); calld->on_complete = op->on_complete; @@ -369,8 +372,8 @@ static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) { if (args->args[i].type == GRPC_ARG_STRING && strcmp(args->args[i].key, GRPC_ARG_HTTP2_SCHEME) == 0) { for (j = 0; j < GPR_ARRAY_SIZE(valid_schemes); j++) { - if (0 == strcmp(grpc_mdstr_as_c_string(valid_schemes[j]->value), - args->args[i].value.string)) { + if (0 == grpc_slice_str_cmp(valid_schemes[j]->value, + args->args[i].value.string)) { return valid_schemes[j]; } } @@ -396,13 +399,13 @@ static size_t max_payload_size_from_args(const grpc_channel_args *args) { return kMaxPayloadSizeForGet; } -static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args, - const char *transport_name) { +static grpc_slice user_agent_from_args(const grpc_channel_args *args, + const char *transport_name) { gpr_strvec v; size_t i; int is_first = 1; char *tmp; - grpc_mdstr *result; + grpc_slice result; gpr_strvec_init(&v); @@ -440,7 +443,7 @@ static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args, tmp = gpr_strvec_flatten(&v, NULL); gpr_strvec_destroy(&v); - result = grpc_mdstr_from_string(tmp); + result = grpc_slice_intern(grpc_slice_from_static_string(tmp)); gpr_free(tmp); return result; @@ -456,7 +459,7 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx, chand->static_scheme = scheme_from_args(args->channel_args); chand->max_payload_size_for_get = max_payload_size_from_args(args->channel_args); - chand->user_agent = grpc_mdelem_from_metadata_strings( + chand->user_agent = grpc_mdelem_from_slices( exec_ctx, GRPC_MDSTR_USER_AGENT, user_agent_from_args(args->channel_args, args->optional_transport->vtable->name)); diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c index db39020dca..d8393337cd 100644 --- a/src/core/lib/channel/http_server_filter.c +++ b/src/core/lib/channel/http_server_filter.c @@ -39,6 +39,7 @@ #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/percent_encoding.h" #include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/transport/static_metadata.h" #define EXPECTED_CONTENT_TYPE "application/grpc" @@ -86,16 +87,15 @@ typedef struct channel_data { uint8_t unused; } channel_data; static grpc_mdelem *server_filter_outgoing_metadata(grpc_exec_ctx *exec_ctx, void *user_data, grpc_mdelem *md) { - if (md->key == GRPC_MDSTR_GRPC_MESSAGE) { + if (grpc_slice_cmp(md->key, GRPC_MDSTR_GRPC_MESSAGE) == 0) { grpc_slice pct_encoded_msg = grpc_percent_encode_slice( - md->value->slice, grpc_compatible_percent_encoding_unreserved_bytes); - if (grpc_slice_is_equivalent(pct_encoded_msg, md->value->slice)) { + md->value, grpc_compatible_percent_encoding_unreserved_bytes); + if (grpc_slice_is_equivalent(pct_encoded_msg, md->value)) { grpc_slice_unref_internal(exec_ctx, pct_encoded_msg); return md; } else { - return grpc_mdelem_from_metadata_strings( - exec_ctx, GRPC_MDSTR_GRPC_MESSAGE, - grpc_mdstr_from_slice(exec_ctx, pct_encoded_msg)); + return grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_MESSAGE, + pct_encoded_msg); } } else { return md; @@ -123,7 +123,7 @@ static grpc_mdelem *server_filter(grpc_exec_ctx *exec_ctx, void *user_data, } else if (md == GRPC_MDELEM_METHOD_GET) { calld->seen_method = 1; *calld->recv_cacheable_request = true; - } else if (md->key == GRPC_MDSTR_SCHEME) { + } else if (grpc_slice_cmp(md->key, GRPC_MDSTR_SCHEME)) { calld->seen_scheme = 1; } else if (md == GRPC_MDELEM_TE_TRAILERS) { calld->seen_te_trailers = 1; @@ -131,12 +131,12 @@ static grpc_mdelem *server_filter(grpc_exec_ctx *exec_ctx, void *user_data, /* TODO(klempner): Track that we've seen all the headers we should require */ return NULL; - } else if (md->key == GRPC_MDSTR_CONTENT_TYPE) { - const char *value_str = grpc_mdstr_as_c_string(md->value); - if (strncmp(value_str, EXPECTED_CONTENT_TYPE, - EXPECTED_CONTENT_TYPE_LENGTH) == 0 && - (value_str[EXPECTED_CONTENT_TYPE_LENGTH] == '+' || - value_str[EXPECTED_CONTENT_TYPE_LENGTH] == ';')) { + } else if (grpc_slice_cmp(md->key, GRPC_MDSTR_CONTENT_TYPE)) { + if (grpc_slice_buf_start_eq(md->value, EXPECTED_CONTENT_TYPE, + EXPECTED_CONTENT_TYPE_LENGTH) && + (GRPC_SLICE_START_PTR(md->value)[EXPECTED_CONTENT_TYPE_LENGTH] == '+' || + GRPC_SLICE_START_PTR(md->value)[EXPECTED_CONTENT_TYPE_LENGTH] == + ';')) { /* Although the C implementation doesn't (currently) generate them, any custom +-suffix is explicitly valid. */ /* TODO(klempner): We should consider preallocating common values such @@ -145,41 +145,47 @@ static grpc_mdelem *server_filter(grpc_exec_ctx *exec_ctx, void *user_data, } else { /* TODO(klempner): We're currently allowing this, but we shouldn't see it without a proxy so log for now. */ - gpr_log(GPR_INFO, "Unexpected content-type '%s'", value_str); + char *val = grpc_dump_slice(md->value, GPR_DUMP_ASCII); + gpr_log(GPR_INFO, "Unexpected content-type '%s'", val); + gpr_free(val); } return NULL; - } else if (md->key == GRPC_MDSTR_TE || md->key == GRPC_MDSTR_METHOD || - md->key == GRPC_MDSTR_SCHEME) { - gpr_log(GPR_ERROR, "Invalid %s: header: '%s'", - grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value)); + } else if (grpc_slice_cmp(md->key, GRPC_MDSTR_TE) == 0 || + grpc_slice_cmp(md->key, GRPC_MDSTR_METHOD) == 0 || + grpc_slice_cmp(md->key, GRPC_MDSTR_SCHEME) == 0) { + char *key = grpc_dump_slice(md->key, GPR_DUMP_ASCII); + char *value = grpc_dump_slice(md->value, GPR_DUMP_ASCII); + gpr_log(GPR_ERROR, "Invalid %s: header: '%s'", key, value); /* swallow it and error everything out. */ /* TODO(klempner): We ought to generate more descriptive error messages on the wire here. */ + gpr_free(key); + gpr_free(value); grpc_call_element_send_cancel(exec_ctx, elem); return NULL; - } else if (md->key == GRPC_MDSTR_PATH) { + } else if (grpc_slice_cmp(md->key, GRPC_MDSTR_PATH) == 0) { if (calld->seen_path) { gpr_log(GPR_ERROR, "Received :path twice"); return NULL; } calld->seen_path = 1; return md; - } else if (md->key == GRPC_MDSTR_AUTHORITY) { + } else if (grpc_slice_cmp(md->key, GRPC_MDSTR_AUTHORITY) == 0) { calld->seen_authority = 1; return md; - } else if (md->key == GRPC_MDSTR_HOST) { + } else if (grpc_slice_cmp(md->key, GRPC_MDSTR_HOST) == 0) { /* translate host to :authority since :authority may be omitted */ - grpc_mdelem *authority = grpc_mdelem_from_metadata_strings( - exec_ctx, GRPC_MDSTR_AUTHORITY, GRPC_MDSTR_REF(md->value)); + grpc_mdelem *authority = grpc_mdelem_from_slices( + exec_ctx, GRPC_MDSTR_AUTHORITY, grpc_slice_ref(md->value)); calld->seen_authority = 1; return authority; - } else if (md->key == GRPC_MDSTR_GRPC_PAYLOAD_BIN) { + } else if (grpc_slice_cmp(md->key, GRPC_MDSTR_GRPC_PAYLOAD_BIN) == 0) { /* Retrieve the payload from the value of the 'grpc-internal-payload-bin' header field */ calld->seen_payload_bin = 1; grpc_slice_buffer_add(&calld->read_slice_buffer, - grpc_slice_ref_internal(md->value->slice)); + grpc_slice_ref_internal(md->value)); grpc_slice_buffer_stream_init(&calld->read_stream, &calld->read_slice_buffer, 0); return NULL; diff --git a/src/core/lib/channel/message_size_filter.c b/src/core/lib/channel/message_size_filter.c index 1655d843d5..4f61da825e 100644 --- a/src/core/lib/channel/message_size_filter.c +++ b/src/core/lib/channel/message_size_filter.c @@ -68,7 +68,7 @@ static int message_size_limits_cmp(void* value1, void* value2) { static void free_mem(grpc_exec_ctx* exec_ctx, void* p) { gpr_free(p); } -static const grpc_mdstr_hash_table_vtable message_size_limits_vtable = { +static const grpc_slice_hash_table_vtable message_size_limits_vtable = { free_mem, message_size_limits_copy, message_size_limits_cmp}; static void* method_config_convert_value( @@ -102,7 +102,7 @@ typedef struct channel_data { int max_send_size; int max_recv_size; // Maps path names to message_size_limits structs. - grpc_mdstr_hash_table* method_limit_table; + grpc_slice_hash_table* method_limit_table; } channel_data; // Callback invoked when we receive a message. Here we check the max @@ -236,7 +236,7 @@ static void init_channel_elem(grpc_exec_ctx* exec_ctx, static void destroy_channel_elem(grpc_exec_ctx* exec_ctx, grpc_channel_element* elem) { channel_data* chand = elem->channel_data; - grpc_mdstr_hash_table_unref(exec_ctx, chand->method_limit_table); + grpc_slice_hash_table_unref(exec_ctx, chand->method_limit_table); } const grpc_channel_filter grpc_message_size_filter = { diff --git a/src/core/lib/compression/algorithm_metadata.h b/src/core/lib/compression/algorithm_metadata.h index 1f9cc15f23..bc4963059c 100644 --- a/src/core/lib/compression/algorithm_metadata.h +++ b/src/core/lib/compression/algorithm_metadata.h @@ -38,7 +38,7 @@ #include "src/core/lib/transport/metadata.h" /** Return compression algorithm based metadata value */ -grpc_mdstr *grpc_compression_algorithm_mdstr( +grpc_slice grpc_compression_algorithm_slice( grpc_compression_algorithm algorithm); /** Return compression algorithm based metadata element (grpc-encoding: xxx) */ @@ -47,7 +47,7 @@ grpc_mdelem *grpc_compression_encoding_mdelem( /** Find compression algorithm based on passed in mdstr - returns * GRPC_COMPRESS_ALGORITHM_COUNT on failure */ -grpc_compression_algorithm grpc_compression_algorithm_from_mdstr( - grpc_mdstr *str); +grpc_compression_algorithm grpc_compression_algorithm_from_slice( + grpc_slice str); #endif /* GRPC_CORE_LIB_COMPRESSION_ALGORITHM_METADATA_H */ diff --git a/src/core/lib/compression/compression.c b/src/core/lib/compression/compression.c index 54efb5e855..d73353f392 100644 --- a/src/core/lib/compression/compression.c +++ b/src/core/lib/compression/compression.c @@ -41,30 +41,24 @@ #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/transport/static_metadata.h" -int grpc_compression_algorithm_parse(const char *name, size_t name_length, +int grpc_compression_algorithm_parse(grpc_slice name, grpc_compression_algorithm *algorithm) { /* we use strncmp not only because it's safer (even though in this case it * doesn't matter, given that we are comparing against string literals, but * because this way we needn't have "name" nil-terminated (useful for slice * data, for example) */ - GRPC_API_TRACE( - "grpc_compression_algorithm_parse(" - "name=%*.*s, name_length=%lu, algorithm=%p)", - 5, ((int)name_length, (int)name_length, name, (unsigned long)name_length, - algorithm)); - if (name_length == 0) { - return 0; - } - if (strncmp(name, "identity", name_length) == 0) { + if (grpc_slice_cmp(name, GRPC_MDSTR_IDENTITY) == 0) { *algorithm = GRPC_COMPRESS_NONE; - } else if (strncmp(name, "gzip", name_length) == 0) { + return 1; + } else if (grpc_slice_cmp(name, GRPC_MDSTR_GZIP) == 0) { *algorithm = GRPC_COMPRESS_GZIP; - } else if (strncmp(name, "deflate", name_length) == 0) { + return 1; + } else if (grpc_slice_cmp(name, GRPC_MDSTR_DEFLATE) == 0) { *algorithm = GRPC_COMPRESS_DEFLATE; + return 1; } else { return 0; } - return 1; } int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm, @@ -87,15 +81,16 @@ int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm, return 0; } -grpc_compression_algorithm grpc_compression_algorithm_from_mdstr( - grpc_mdstr *str) { - if (str == GRPC_MDSTR_IDENTITY) return GRPC_COMPRESS_NONE; - if (str == GRPC_MDSTR_DEFLATE) return GRPC_COMPRESS_DEFLATE; - if (str == GRPC_MDSTR_GZIP) return GRPC_COMPRESS_GZIP; +grpc_compression_algorithm grpc_compression_algorithm_from_slice( + grpc_slice str) { + if (grpc_slice_cmp(str, GRPC_MDSTR_IDENTITY) == 0) return GRPC_COMPRESS_NONE; + if (grpc_slice_cmp(str, GRPC_MDSTR_DEFLATE) == 0) + return GRPC_COMPRESS_DEFLATE; + if (grpc_slice_cmp(str, GRPC_MDSTR_GZIP) == 0) return GRPC_COMPRESS_GZIP; return GRPC_COMPRESS_ALGORITHMS_COUNT; } -grpc_mdstr *grpc_compression_algorithm_mdstr( +grpc_slice grpc_compression_algorithm_slice( grpc_compression_algorithm algorithm) { switch (algorithm) { case GRPC_COMPRESS_NONE: @@ -105,9 +100,9 @@ grpc_mdstr *grpc_compression_algorithm_mdstr( case GRPC_COMPRESS_GZIP: return GRPC_MDSTR_GZIP; case GRPC_COMPRESS_ALGORITHMS_COUNT: - return NULL; + return grpc_empty_slice(); } - return NULL; + return grpc_empty_slice(); } grpc_mdelem *grpc_compression_encoding_mdelem( diff --git a/src/core/lib/iomgr/load_file.c b/src/core/lib/iomgr/load_file.c index 217bc5da59..f40c8b28cc 100644 --- a/src/core/lib/iomgr/load_file.c +++ b/src/core/lib/iomgr/load_file.c @@ -47,7 +47,7 @@ grpc_error *grpc_load_file(const char *filename, int add_null_terminator, grpc_slice *output) { unsigned char *contents = NULL; size_t contents_size = 0; - grpc_slice result = gpr_empty_slice(); + grpc_slice result = grpc_empty_slice(); FILE *file; size_t bytes_read = 0; grpc_error *error = GRPC_ERROR_NONE; diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.c b/src/core/lib/security/credentials/google_default/google_default_credentials.c index 7bed78daf7..65eb02bbb9 100644 --- a/src/core/lib/security/credentials/google_default/google_default_credentials.c +++ b/src/core/lib/security/credentials/google_default/google_default_credentials.c @@ -174,7 +174,7 @@ static grpc_error *create_default_creds_from_path( grpc_auth_json_key key; grpc_auth_refresh_token token; grpc_call_credentials *result = NULL; - grpc_slice creds_data = gpr_empty_slice(); + grpc_slice creds_data = grpc_empty_slice(); grpc_error *error = GRPC_ERROR_NONE; if (creds_path == NULL) { error = GRPC_ERROR_CREATE("creds_path unset"); diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c index ae40bb499c..e9e77182b6 100644 --- a/src/core/lib/security/transport/client_auth_filter.c +++ b/src/core/lib/security/transport/client_auth_filter.c @@ -54,8 +54,8 @@ /* We can have a per-call credentials. */ typedef struct { grpc_call_credentials *creds; - grpc_mdstr *host; - grpc_mdstr *method; + grpc_slice host; + grpc_slice method; /* pollset{_set} bound to this call; if we need to make external network requests, they should be done under a pollset added to this pollset_set so that work can progress when this call wants work to progress diff --git a/src/core/lib/security/transport/security_connector.c b/src/core/lib/security/transport/security_connector.c index 7192f228cd..53bccb3efb 100644 --- a/src/core/lib/security/transport/security_connector.c +++ b/src/core/lib/security/transport/security_connector.c @@ -649,7 +649,7 @@ static grpc_security_connector_vtable ssl_server_vtable = { ssl_server_destroy, ssl_server_check_peer}; static grpc_slice compute_default_pem_root_certs_once(void) { - grpc_slice result = gpr_empty_slice(); + grpc_slice result = grpc_empty_slice(); /* First try to load the roots from the environment. */ char *default_root_certs_path = diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.c index 7a0069710e..db0d0d6907 100644 --- a/src/core/lib/security/transport/server_auth_filter.c +++ b/src/core/lib/security/transport/server_auth_filter.c @@ -68,8 +68,8 @@ static grpc_metadata_array metadata_batch_to_md_array( for (l = batch->list.head; l != NULL; l = l->next) { grpc_metadata *usr_md = NULL; grpc_mdelem *md = l->md; - grpc_mdstr *key = md->key; - grpc_mdstr *value = md->value; + grpc_slice key = md->key; + grpc_slice value = md->value; if (result.count == result.capacity) { result.capacity = GPR_MAX(result.capacity + 8, result.capacity * 2); result.metadata = diff --git a/src/core/lib/security/util/b64.c b/src/core/lib/security/util/b64.c index bbd7e335a6..09c8213131 100644 --- a/src/core/lib/security/util/b64.c +++ b/src/core/lib/security/util/b64.c @@ -232,5 +232,5 @@ grpc_slice grpc_base64_decode_with_len(grpc_exec_ctx *exec_ctx, const char *b64, fail: grpc_slice_unref_internal(exec_ctx, result); - return gpr_empty_slice(); + return grpc_empty_slice(); } diff --git a/src/core/lib/slice/slice.c b/src/core/lib/slice/slice.c index a85a52b2c6..dc3e6fd93d 100644 --- a/src/core/lib/slice/slice.c +++ b/src/core/lib/slice/slice.c @@ -41,7 +41,7 @@ #include "src/core/lib/iomgr/exec_ctx.h" -grpc_slice gpr_empty_slice(void) { +grpc_slice grpc_empty_slice(void) { grpc_slice out; out.refcount = 0; out.data.inlined.length = 0; diff --git a/src/core/lib/transport/mdstr_hash_table.c b/src/core/lib/slice/slice_hash_table.c index a3f6bde516..7e6f705164 100644 --- a/src/core/lib/transport/mdstr_hash_table.c +++ b/src/core/lib/slice/slice_hash_table.c @@ -29,7 +29,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -#include "src/core/lib/transport/mdstr_hash_table.h" +#include "src/core/lib/slice/slice_hash_table.h" #include <stdbool.h> #include <string.h> @@ -37,72 +37,88 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> +#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" -struct grpc_mdstr_hash_table { +static grpc_slice_refcount terminal_slice_refcount = {NULL, NULL}; +static const grpc_slice terminal_slice = {&terminal_slice_refcount, + .data.refcounted = {0, 0}}; + +struct grpc_slice_hash_table { gpr_refcount refs; size_t num_entries; size_t size; - grpc_mdstr_hash_table_entry* entries; + grpc_slice_hash_table_entry* entries; }; +static bool is_terminal(grpc_slice slice) { + return slice.refcount == &terminal_slice_refcount; +} + // Helper function for insert and get operations that performs quadratic // probing (https://en.wikipedia.org/wiki/Quadratic_probing). -static size_t grpc_mdstr_hash_table_find_index( - const grpc_mdstr_hash_table* table, const grpc_mdstr* key, - bool find_empty) { +static size_t grpc_slice_hash_table_find_index( + const grpc_slice_hash_table* table, const grpc_slice key, bool find_empty) { + size_t hash = grpc_slice_hash(key); for (size_t i = 0; i < table->size; ++i) { - const size_t idx = (key->hash + i * i) % table->size; - if (table->entries[idx].key == NULL) return find_empty ? idx : table->size; - if (table->entries[idx].key == key) return idx; + const size_t idx = (hash + i * i) % table->size; + if (is_terminal(table->entries[idx].key)) { + return find_empty ? idx : table->size; + } + if (grpc_slice_cmp(table->entries[idx].key, key) == 0) { + return idx; + } } return table->size; // Not found. } -static void grpc_mdstr_hash_table_add( - grpc_mdstr_hash_table* table, grpc_mdstr* key, void* value, - const grpc_mdstr_hash_table_vtable* vtable) { +static void grpc_slice_hash_table_add( + grpc_slice_hash_table* table, grpc_slice key, void* value, + const grpc_slice_hash_table_vtable* vtable) { GPR_ASSERT(value != NULL); const size_t idx = - grpc_mdstr_hash_table_find_index(table, key, true /* find_empty */); + grpc_slice_hash_table_find_index(table, key, true /* find_empty */); GPR_ASSERT(idx != table->size); // Table should never be full. - grpc_mdstr_hash_table_entry* entry = &table->entries[idx]; - entry->key = GRPC_MDSTR_REF(key); + grpc_slice_hash_table_entry* entry = &table->entries[idx]; + entry->key = grpc_slice_ref(key); entry->value = vtable->copy_value(value); entry->vtable = vtable; } -grpc_mdstr_hash_table* grpc_mdstr_hash_table_create( - size_t num_entries, grpc_mdstr_hash_table_entry* entries) { - grpc_mdstr_hash_table* table = gpr_malloc(sizeof(*table)); +grpc_slice_hash_table* grpc_slice_hash_table_create( + size_t num_entries, grpc_slice_hash_table_entry* entries) { + grpc_slice_hash_table* table = gpr_malloc(sizeof(*table)); memset(table, 0, sizeof(*table)); gpr_ref_init(&table->refs, 1); table->num_entries = num_entries; // Quadratic probing gets best performance when the table is no more // than half full. table->size = num_entries * 2; - const size_t entry_size = sizeof(grpc_mdstr_hash_table_entry) * table->size; + const size_t entry_size = sizeof(grpc_slice_hash_table_entry) * table->size; table->entries = gpr_malloc(entry_size); memset(table->entries, 0, entry_size); for (size_t i = 0; i < num_entries; ++i) { - grpc_mdstr_hash_table_entry* entry = &entries[i]; - grpc_mdstr_hash_table_add(table, entry->key, entry->value, entry->vtable); + table->entries[i].key = terminal_slice; + } + for (size_t i = 0; i < num_entries; ++i) { + grpc_slice_hash_table_entry* entry = &entries[i]; + grpc_slice_hash_table_add(table, entry->key, entry->value, entry->vtable); } return table; } -grpc_mdstr_hash_table* grpc_mdstr_hash_table_ref(grpc_mdstr_hash_table* table) { +grpc_slice_hash_table* grpc_slice_hash_table_ref(grpc_slice_hash_table* table) { if (table != NULL) gpr_ref(&table->refs); return table; } -int grpc_mdstr_hash_table_unref(grpc_exec_ctx* exec_ctx, - grpc_mdstr_hash_table* table) { +int grpc_slice_hash_table_unref(grpc_exec_ctx* exec_ctx, + grpc_slice_hash_table* table) { if (table != NULL && gpr_unref(&table->refs)) { for (size_t i = 0; i < table->size; ++i) { - grpc_mdstr_hash_table_entry* entry = &table->entries[i]; - if (entry->key != NULL) { - GRPC_MDSTR_UNREF(exec_ctx, entry->key); + grpc_slice_hash_table_entry* entry = &table->entries[i]; + if (!is_terminal(entry->key)) { + grpc_slice_unref_internal(exec_ctx, entry->key); entry->vtable->destroy_value(exec_ctx, entry->value); } } @@ -113,29 +129,29 @@ int grpc_mdstr_hash_table_unref(grpc_exec_ctx* exec_ctx, return 0; } -size_t grpc_mdstr_hash_table_num_entries(const grpc_mdstr_hash_table* table) { +size_t grpc_slice_hash_table_num_entries(const grpc_slice_hash_table* table) { return table->num_entries; } -void* grpc_mdstr_hash_table_get(const grpc_mdstr_hash_table* table, - const grpc_mdstr* key) { +void* grpc_slice_hash_table_get(const grpc_slice_hash_table* table, + const grpc_slice key) { const size_t idx = - grpc_mdstr_hash_table_find_index(table, key, false /* find_empty */); + grpc_slice_hash_table_find_index(table, key, false /* find_empty */); if (idx == table->size) return NULL; // Not found. return table->entries[idx].value; } -int grpc_mdstr_hash_table_cmp(const grpc_mdstr_hash_table* table1, - const grpc_mdstr_hash_table* table2) { +int grpc_slice_hash_table_cmp(const grpc_slice_hash_table* table1, + const grpc_slice_hash_table* table2) { // Compare by num_entries. if (table1->num_entries < table2->num_entries) return -1; if (table1->num_entries > table2->num_entries) return 1; for (size_t i = 0; i < table1->num_entries; ++i) { - grpc_mdstr_hash_table_entry* e1 = &table1->entries[i]; - grpc_mdstr_hash_table_entry* e2 = &table2->entries[i]; + grpc_slice_hash_table_entry* e1 = &table1->entries[i]; + grpc_slice_hash_table_entry* e2 = &table2->entries[i]; // Compare keys by hash value. - if (e1->key->hash < e2->key->hash) return -1; - if (e1->key->hash > e2->key->hash) return 1; + int cmp = grpc_slice_cmp(e1->key, e2->key); + if (cmp != 0) return cmp; // Compare by vtable (pointer equality). if (e1->vtable < e2->vtable) return -1; if (e1->vtable > e2->vtable) return 1; @@ -146,12 +162,12 @@ int grpc_mdstr_hash_table_cmp(const grpc_mdstr_hash_table* table1, return 0; } -void grpc_mdstr_hash_table_iterate( - const grpc_mdstr_hash_table* table, - void (*func)(const grpc_mdstr_hash_table_entry* entry, void* user_data), +void grpc_slice_hash_table_iterate( + const grpc_slice_hash_table* table, + void (*func)(const grpc_slice_hash_table_entry* entry, void* user_data), void* user_data) { for (size_t i = 0; i < table->size; ++i) { - if (table->entries[i].key != NULL) { + if (!is_terminal(table->entries[i].key)) { func(&table->entries[i], user_data); } } diff --git a/src/core/lib/transport/mdstr_hash_table.h b/src/core/lib/slice/slice_hash_table.h index 45e5720063..ac04950cc6 100644 --- a/src/core/lib/transport/mdstr_hash_table.h +++ b/src/core/lib/slice/slice_hash_table.h @@ -40,54 +40,54 @@ * (https://en.wikipedia.org/wiki/Open_addressing) with quadratic * probing (https://en.wikipedia.org/wiki/Quadratic_probing). * - * The keys are \a grpc_mdstr objects. The values are arbitrary pointers + * The keys are \a grpc_slice objects. The values are arbitrary pointers * with a common vtable. * * Hash tables are intentionally immutable, to avoid the need for locking. */ -typedef struct grpc_mdstr_hash_table grpc_mdstr_hash_table; +typedef struct grpc_slice_hash_table grpc_slice_hash_table; -typedef struct grpc_mdstr_hash_table_vtable { - void (*destroy_value)(grpc_exec_ctx* exec_ctx, void* value); - void* (*copy_value)(void* value); - int (*compare_value)(void* value1, void* value2); -} grpc_mdstr_hash_table_vtable; +typedef struct grpc_slice_hash_table_vtable { + void (*destroy_value)(grpc_exec_ctx *exec_ctx, void *value); + void *(*copy_value)(void *value); + int (*compare_value)(void *value1, void *value2); +} grpc_slice_hash_table_vtable; -typedef struct grpc_mdstr_hash_table_entry { - grpc_mdstr* key; - void* value; /* Must not be NULL. */ - const grpc_mdstr_hash_table_vtable* vtable; -} grpc_mdstr_hash_table_entry; +typedef struct grpc_slice_hash_table_entry { + grpc_slice key; + void *value; /* Must not be NULL. */ + const grpc_slice_hash_table_vtable *vtable; +} grpc_slice_hash_table_entry; /** Creates a new hash table of containing \a entries, which is an array of length \a num_entries. Creates its own copy of all keys and values from \a entries. */ -grpc_mdstr_hash_table* grpc_mdstr_hash_table_create( - size_t num_entries, grpc_mdstr_hash_table_entry* entries); +grpc_slice_hash_table *grpc_slice_hash_table_create( + size_t num_entries, grpc_slice_hash_table_entry *entries); -grpc_mdstr_hash_table* grpc_mdstr_hash_table_ref(grpc_mdstr_hash_table* table); +grpc_slice_hash_table *grpc_slice_hash_table_ref(grpc_slice_hash_table *table); /** Returns 1 when \a table is destroyed. */ -int grpc_mdstr_hash_table_unref(grpc_exec_ctx* exec_ctx, - grpc_mdstr_hash_table* table); +int grpc_slice_hash_table_unref(grpc_exec_ctx *exec_ctx, + grpc_slice_hash_table *table); /** Returns the number of entries in \a table. */ -size_t grpc_mdstr_hash_table_num_entries(const grpc_mdstr_hash_table* table); +size_t grpc_slice_hash_table_num_entries(const grpc_slice_hash_table *table); /** Returns the value from \a table associated with \a key. Returns NULL if \a key is not found. */ -void* grpc_mdstr_hash_table_get(const grpc_mdstr_hash_table* table, - const grpc_mdstr* key); +void *grpc_slice_hash_table_get(const grpc_slice_hash_table *table, + const grpc_slice key); /** Compares two hash tables. The sort order is stable but undefined. */ -int grpc_mdstr_hash_table_cmp(const grpc_mdstr_hash_table* table1, - const grpc_mdstr_hash_table* table2); +int grpc_slice_hash_table_cmp(const grpc_slice_hash_table *table1, + const grpc_slice_hash_table *table2); /** Iterates over the entries in \a table, calling \a func for each entry. */ -void grpc_mdstr_hash_table_iterate( - const grpc_mdstr_hash_table* table, - void (*func)(const grpc_mdstr_hash_table_entry* entry, void* user_data), - void* user_data); +void grpc_slice_hash_table_iterate( + const grpc_slice_hash_table *table, + void (*func)(const grpc_slice_hash_table_entry *entry, void *user_data), + void *user_data); #endif /* GRPC_CORE_LIB_TRANSPORT_MDSTR_HASH_TABLE_H */ diff --git a/src/core/lib/slice/slice_string_helpers.h b/src/core/lib/slice/slice_string_helpers.h index c6f4e87c7f..4a4deec6e5 100644 --- a/src/core/lib/slice/slice_string_helpers.h +++ b/src/core/lib/slice/slice_string_helpers.h @@ -34,6 +34,7 @@ #ifndef GRPC_CORE_LIB_SLICE_SLICE_STRING_HELPERS_H #define GRPC_CORE_LIB_SLICE_SLICE_STRING_HELPERS_H +#include <stdbool.h> #include <stddef.h> #include <grpc/slice.h> @@ -53,6 +54,8 @@ char *grpc_dump_slice(grpc_slice slice, uint32_t flags); * should be a properly initialized instance. */ void grpc_slice_split(grpc_slice str, const char *sep, grpc_slice_buffer *dst); +bool grpc_parse_slice_to_uint32(grpc_slice str, uint32_t *result); + #ifdef __cplusplus } #endif diff --git a/src/core/lib/slice/slice_traits.h b/src/core/lib/slice/slice_traits.h new file mode 100644 index 0000000000..facbd0dd81 --- /dev/null +++ b/src/core/lib/slice/slice_traits.h @@ -0,0 +1,44 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef SLICE_TRAITS_H +#define SLICE_TRAITS_H + +#include <grpc/slice.h> +#include <stdbool.h> + +bool grpc_slice_is_legal_header(grpc_slice s); +bool grpc_slice_is_legal_nonbin_header(grpc_slice s); +bool grpc_slice_is_bin_suffixed(grpc_slice s); + +#endif diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 023b0411c7..38aa99372e 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -92,9 +92,10 @@ typedef enum { } status_source; typedef struct { - uint8_t is_set; + bool is_code_set; + bool is_details_set; grpc_status_code code; - grpc_mdstr *details; + grpc_slice details; } received_status; typedef struct batch_control { @@ -196,8 +197,7 @@ struct grpc_call { union { struct { grpc_status_code *status; - char **status_details; - size_t *status_details_capacity; + grpc_slice *status_details; } client; struct { int *cancelled; @@ -246,14 +246,15 @@ grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx, /* Always support no compression */ GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE); call->is_client = args->server_transport_data == NULL; - grpc_mdstr *path = NULL; + grpc_slice path = grpc_empty_slice(); if (call->is_client) { GPR_ASSERT(args->add_initial_metadata_count < MAX_SEND_EXTRA_METADATA_COUNT); for (i = 0; i < args->add_initial_metadata_count; i++) { call->send_extra_metadata[i].md = args->add_initial_metadata[i]; - if (args->add_initial_metadata[i]->key == GRPC_MDSTR_PATH) { - path = GRPC_MDSTR_REF(args->add_initial_metadata[i]->value); + if (grpc_slice_cmp(args->add_initial_metadata[i]->key, GRPC_MDSTR_PATH) == + 0) { + path = grpc_slice_ref_internal(args->add_initial_metadata[i]->value); } } call->send_extra_metadata_count = (int)args->add_initial_metadata_count; @@ -342,7 +343,7 @@ grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx, exec_ctx, CALL_STACK_FROM_CALL(call), &call->pollent); } - if (path != NULL) GRPC_MDSTR_UNREF(exec_ctx, path); + grpc_slice_unref_internal(exec_ctx, path); GPR_TIMER_END("grpc_call_create", 0); return error; @@ -383,7 +384,7 @@ static void get_final_status(grpc_call *call, void *set_value_user_data) { int i; for (i = 0; i < STATUS_SOURCE_COUNT; i++) { - if (call->status[i].is_set) { + if (call->status[i].is_code_set) { set_value(call->status[i].code, set_value_user_data); return; } @@ -411,8 +412,8 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call, } gpr_mu_destroy(&c->mu); for (i = 0; i < STATUS_SOURCE_COUNT; i++) { - if (c->status[i].details) { - GRPC_MDSTR_UNREF(exec_ctx, c->status[i].details); + if (c->status[i].is_details_set) { + grpc_slice_unref_internal(exec_ctx, c->status[i].details); } } for (ii = 0; ii < c->send_extra_metadata_count; ii++) { @@ -440,18 +441,19 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call, static void set_status_code(grpc_call *call, status_source source, uint32_t status) { - if (call->status[source].is_set) return; + if (call->status[source].is_code_set) return; - call->status[source].is_set = 1; + call->status[source].is_code_set = true; call->status[source].code = (grpc_status_code)status; } static void set_status_details(grpc_exec_ctx *exec_ctx, grpc_call *call, - status_source source, grpc_mdstr *status) { - if (call->status[source].details != NULL) { - GRPC_MDSTR_UNREF(exec_ctx, status); + status_source source, grpc_slice status) { + if (call->status[source].is_details_set) { + grpc_slice_unref_internal(exec_ctx, status); } else { call->status[source].details = status; + call->status[source].is_details_set = true; } } @@ -461,7 +463,8 @@ static void set_status_from_error(grpc_exec_ctx *exec_ctx, grpc_call *call, const char *msg; grpc_error_get_status(error, &status, &msg); set_status_code(call, source, (uint32_t)status); - set_status_details(exec_ctx, call, source, grpc_mdstr_from_string(msg)); + set_status_details(exec_ctx, call, source, + grpc_slice_from_copied_string(msg)); } static void set_incoming_compression_algorithm( @@ -511,7 +514,7 @@ static void set_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx, return; } - accept_encoding_slice = mdel->value->slice; + accept_encoding_slice = mdel->value; grpc_slice_buffer_init(&accept_encoding_parts); grpc_slice_split(accept_encoding_slice, ",", &accept_encoding_parts); @@ -520,15 +523,13 @@ static void set_encodings_accepted_by_peer(grpc_exec_ctx *exec_ctx, /* Always support no compression */ GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE); for (i = 0; i < accept_encoding_parts.count; i++) { - const grpc_slice *accept_encoding_entry_slice = - &accept_encoding_parts.slices[i]; - if (grpc_compression_algorithm_parse( - (const char *)GRPC_SLICE_START_PTR(*accept_encoding_entry_slice), - GRPC_SLICE_LENGTH(*accept_encoding_entry_slice), &algorithm)) { + grpc_slice accept_encoding_entry_slice = accept_encoding_parts.slices[i]; + if (grpc_compression_algorithm_parse(accept_encoding_entry_slice, + &algorithm)) { GPR_BITSET(&call->encodings_accepted_by_peer, algorithm); } else { char *accept_encoding_entry_str = - grpc_dump_slice(*accept_encoding_entry_slice, GPR_DUMP_ASCII); + grpc_dump_slice(accept_encoding_entry_slice, GPR_DUMP_ASCII); gpr_log(GPR_ERROR, "Invalid entry in accept encoding metadata: '%s'. Ignoring.", accept_encoding_entry_str); @@ -551,21 +552,12 @@ uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call) { return encodings_accepted_by_peer; } -static void get_final_details(grpc_call *call, char **out_details, - size_t *out_details_capacity) { +static void get_final_details(grpc_call *call, grpc_slice *out_details) { int i; for (i = 0; i < STATUS_SOURCE_COUNT; i++) { - if (call->status[i].is_set) { - if (call->status[i].details) { - grpc_slice details = call->status[i].details->slice; - size_t len = GRPC_SLICE_LENGTH(details); - if (len + 1 > *out_details_capacity) { - *out_details_capacity = - GPR_MAX(len + 1, *out_details_capacity * 3 / 2); - *out_details = gpr_realloc(*out_details, *out_details_capacity); - } - memcpy(*out_details, GRPC_SLICE_START_PTR(details), len); - (*out_details)[len] = 0; + if (call->status[i].is_code_set) { + if (call->status[i].is_details_set) { + *out_details = grpc_slice_ref(call->status[i].details); } else { goto no_details; } @@ -574,11 +566,7 @@ static void get_final_details(grpc_call *call, char **out_details, } no_details: - if (0 == *out_details_capacity) { - *out_details_capacity = 8; - *out_details = gpr_malloc(*out_details_capacity); - } - **out_details = 0; + *out_details = grpc_empty_slice(); } static grpc_linked_mdelem *linked_from_md(grpc_metadata *md) { @@ -607,19 +595,17 @@ static int prepare_application_metadata( get_md_elem(metadata, additional_metadata, i, count); grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data; GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data)); - l->md = grpc_mdelem_from_string_and_buffer( - exec_ctx, md->key, (const uint8_t *)md->value, md->value_length); - if (!grpc_header_key_is_legal(grpc_mdstr_as_c_string(l->md->key), - GRPC_MDSTR_LENGTH(l->md->key))) { - gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s", - grpc_mdstr_as_c_string(l->md->key)); + l->md = grpc_mdelem_from_slices(exec_ctx, md->key, md->value); + if (!grpc_header_key_slice_is_legal(l->md->key)) { + char *str = grpc_dump_slice(md->key, GPR_DUMP_ASCII); + gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s", str); + gpr_free(str); break; - } else if (!grpc_is_binary_header(grpc_mdstr_as_c_string(l->md->key), - GRPC_MDSTR_LENGTH(l->md->key)) && - !grpc_header_nonbin_value_is_legal( - grpc_mdstr_as_c_string(l->md->value), - GRPC_MDSTR_LENGTH(l->md->value))) { - gpr_log(GPR_ERROR, "attempt to send invalid metadata value"); + } else if (!grpc_slice_is_binary_header(l->md->key) && + !grpc_header_nonbin_value_slice_is_legal(l->md->value)) { + char *str = grpc_dump_slice(md->value, GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_ERROR, "attempt to send invalid metadata value: %s", str); + gpr_free(str); break; } } @@ -903,9 +889,7 @@ static uint32_t decode_status(grpc_mdelem *md) { if (user_data != NULL) { status = ((uint32_t)(intptr_t)user_data) - STATUS_OFFSET; } else { - if (!gpr_parse_bytes_to_uint32(grpc_mdstr_as_c_string(md->value), - GRPC_SLICE_LENGTH(md->value->slice), - &status)) { + if (!grpc_parse_slice_to_uint32(md->value, &status)) { status = GRPC_STATUS_UNKNOWN; /* could not parse status code */ } grpc_mdelem_set_user_data(md, destroy_status, @@ -916,13 +900,14 @@ static uint32_t decode_status(grpc_mdelem *md) { static grpc_compression_algorithm decode_compression(grpc_mdelem *md) { grpc_compression_algorithm algorithm = - grpc_compression_algorithm_from_mdstr(md->value); + grpc_compression_algorithm_from_slice(md->value); if (algorithm == GRPC_COMPRESS_ALGORITHMS_COUNT) { - const char *md_c_str = grpc_mdstr_as_c_string(md->value); + char *md_c_str = grpc_dump_slice(md->value, GPR_DUMP_ASCII); gpr_log(GPR_ERROR, "Invalid incoming compression algorithm: '%s'. Interpreting " "incoming data as uncompressed.", md_c_str); + gpr_free(md_c_str); return GRPC_COMPRESS_NONE; } return algorithm; @@ -930,15 +915,15 @@ static grpc_compression_algorithm decode_compression(grpc_mdelem *md) { static grpc_mdelem *recv_common_filter(grpc_exec_ctx *exec_ctx, grpc_call *call, grpc_mdelem *elem) { - if (elem->key == GRPC_MDSTR_GRPC_STATUS) { + if (grpc_slice_cmp(elem->key, GRPC_MDSTR_GRPC_STATUS) == 0) { GPR_TIMER_BEGIN("status", 0); set_status_code(call, STATUS_FROM_WIRE, decode_status(elem)); GPR_TIMER_END("status", 0); return NULL; - } else if (elem->key == GRPC_MDSTR_GRPC_MESSAGE) { + } else if (grpc_slice_cmp(elem->key, GRPC_MDSTR_GRPC_MESSAGE) == 0) { GPR_TIMER_BEGIN("status-details", 0); set_status_details(exec_ctx, call, STATUS_FROM_WIRE, - GRPC_MDSTR_REF(elem->value)); + grpc_slice_ref_internal(elem->value)); GPR_TIMER_END("status-details", 0); return NULL; } @@ -957,9 +942,8 @@ static grpc_mdelem *publish_app_metadata(grpc_call *call, grpc_mdelem *elem, gpr_realloc(dest->metadata, sizeof(grpc_metadata) * dest->capacity); } mdusr = &dest->metadata[dest->count++]; - mdusr->key = grpc_mdstr_as_c_string(elem->key); - mdusr->value = grpc_mdstr_as_c_string(elem->value); - mdusr->value_length = GRPC_SLICE_LENGTH(elem->value->slice); + mdusr->key = grpc_slice_ref(elem->key); + mdusr->value = grpc_slice_ref(elem->value); GPR_TIMER_END("publish_app_metadata", 0); return elem; } @@ -970,12 +954,12 @@ static grpc_mdelem *recv_initial_filter(grpc_exec_ctx *exec_ctx, void *args, elem = recv_common_filter(exec_ctx, call, elem); if (elem == NULL) { return NULL; - } else if (elem->key == GRPC_MDSTR_GRPC_ENCODING) { + } else if (grpc_slice_cmp(elem->key, GRPC_MDSTR_GRPC_ENCODING) == 0) { GPR_TIMER_BEGIN("incoming_compression_algorithm", 0); set_incoming_compression_algorithm(call, decode_compression(elem)); GPR_TIMER_END("incoming_compression_algorithm", 0); return NULL; - } else if (elem->key == GRPC_MDSTR_GRPC_ACCEPT_ENCODING) { + } else if (grpc_slice_cmp(elem->key, GRPC_MDSTR_GRPC_ACCEPT_ENCODING) == 0) { GPR_TIMER_BEGIN("encodings_accepted_by_peer", 0); set_encodings_accepted_by_peer(exec_ctx, call, elem); GPR_TIMER_END("encodings_accepted_by_peer", 0); @@ -1324,8 +1308,7 @@ static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp, if (call->is_client) { get_final_status(call, set_status_value_directly, call->final_op.client.status); - get_final_details(call, call->final_op.client.status_details, - call->final_op.client.status_details_capacity); + get_final_details(call, call->final_op.client.status_details); } else { get_final_status(call, set_cancelled_value, call->final_op.server.cancelled); @@ -1423,13 +1406,10 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, const grpc_compression_algorithm calgo = compression_algorithm_for_level_locked( call, effective_compression_level); - char *calgo_name = NULL; - grpc_compression_algorithm_name(calgo, &calgo_name); // the following will be picked up by the compress filter and used as // the call's compression algorithm. - compression_md.key = GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY; - compression_md.value = calgo_name; - compression_md.value_length = strlen(calgo_name); + compression_md.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST; + compression_md.value = grpc_compression_algorithm_slice(calgo); additional_metadata_count++; } @@ -1523,14 +1503,14 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, call->send_extra_metadata[0].md = grpc_channel_get_reffed_status_elem( exec_ctx, call->channel, op->data.send_status_from_server.status); if (op->data.send_status_from_server.status_details != NULL) { - call->send_extra_metadata[1].md = grpc_mdelem_from_metadata_strings( + call->send_extra_metadata[1].md = grpc_mdelem_from_slices( exec_ctx, GRPC_MDSTR_GRPC_MESSAGE, - grpc_mdstr_from_string( - op->data.send_status_from_server.status_details)); + grpc_slice_ref_internal( + *op->data.send_status_from_server.status_details)); call->send_extra_metadata_count++; set_status_details( exec_ctx, call, STATUS_FROM_API_OVERRIDE, - GRPC_MDSTR_REF(call->send_extra_metadata[1].md->value)); + grpc_slice_ref_internal(call->send_extra_metadata[1].md->value)); } if (op->data.send_status_from_server.status != GRPC_STATUS_OK) { set_status_code(call, STATUS_FROM_API_OVERRIDE, @@ -1607,8 +1587,6 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, call->final_op.client.status = op->data.recv_status_on_client.status; call->final_op.client.status_details = op->data.recv_status_on_client.status_details; - call->final_op.client.status_details_capacity = - op->data.recv_status_on_client.status_details_capacity; bctl->recv_final_op = 1; stream_op->recv_trailing_metadata = &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */]; diff --git a/src/core/lib/surface/call_details.c b/src/core/lib/surface/call_details.c index fe73da3f55..5efa3b0141 100644 --- a/src/core/lib/surface/call_details.c +++ b/src/core/lib/surface/call_details.c @@ -41,10 +41,12 @@ void grpc_call_details_init(grpc_call_details* cd) { GRPC_API_TRACE("grpc_call_details_init(cd=%p)", 1, (cd)); memset(cd, 0, sizeof(*cd)); + cd->method = grpc_empty_slice(); + cd->host = grpc_empty_slice(); } void grpc_call_details_destroy(grpc_call_details* cd) { GRPC_API_TRACE("grpc_call_details_destroy(cd=%p)", 1, (cd)); - gpr_free(cd->method); - gpr_free(cd->host); + grpc_slice_unref(cd->method); + grpc_slice_unref(cd->host); } diff --git a/src/core/lib/surface/call_log_batch.c b/src/core/lib/surface/call_log_batch.c index 31c074f15d..8f6438bc3b 100644 --- a/src/core/lib/surface/call_log_batch.c +++ b/src/core/lib/surface/call_log_batch.c @@ -35,17 +35,18 @@ #include <grpc/support/alloc.h> #include <grpc/support/string_util.h> +#include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/support/string.h" static void add_metadata(gpr_strvec *b, const grpc_metadata *md, size_t count) { size_t i; for (i = 0; i < count; i++) { gpr_strvec_add(b, gpr_strdup("\nkey=")); - gpr_strvec_add(b, gpr_strdup(md[i].key)); + gpr_strvec_add(b, grpc_dump_slice(md[i].key, GPR_DUMP_ASCII)); gpr_strvec_add(b, gpr_strdup(" value=")); - gpr_strvec_add(b, gpr_dump(md[i].value, md[i].value_length, - GPR_DUMP_HEX | GPR_DUMP_ASCII)); + gpr_strvec_add(b, + grpc_dump_slice(md[i].value, GPR_DUMP_HEX | GPR_DUMP_ASCII)); } } @@ -70,10 +71,16 @@ char *grpc_op_string(const grpc_op *op) { gpr_strvec_add(&b, gpr_strdup("SEND_CLOSE_FROM_CLIENT")); break; case GRPC_OP_SEND_STATUS_FROM_SERVER: - gpr_asprintf(&tmp, "SEND_STATUS_FROM_SERVER status=%d details=%s", - op->data.send_status_from_server.status, - op->data.send_status_from_server.status_details); + gpr_asprintf(&tmp, "SEND_STATUS_FROM_SERVER status=%d details=", + op->data.send_status_from_server.status); gpr_strvec_add(&b, tmp); + if (op->data.send_status_from_server.status_details != NULL) { + gpr_strvec_add(&b, grpc_dump_slice( + *op->data.send_status_from_server.status_details, + GPR_DUMP_ASCII)); + } else { + gpr_strvec_add(&b, gpr_strdup("(null)")); + } add_metadata(&b, op->data.send_status_from_server.trailing_metadata, op->data.send_status_from_server.trailing_metadata_count); break; diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c index 7e87f05531..986142a692 100644 --- a/src/core/lib/surface/channel.c +++ b/src/core/lib/surface/channel.c @@ -123,8 +123,9 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target, /* setting this takes precedence over anything else */ GRPC_MDELEM_UNREF(exec_ctx, channel->default_authority); } - channel->default_authority = grpc_mdelem_from_strings( - exec_ctx, ":authority", args->args[i].value.string); + channel->default_authority = grpc_mdelem_from_slices( + exec_ctx, GRPC_MDSTR_AUTHORITY, + grpc_slice_from_copied_string(args->args[i].value.string)); } } else if (0 == strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) { @@ -138,8 +139,9 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target, "%s ignored: default host already set some other way", GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); } else { - channel->default_authority = grpc_mdelem_from_strings( - exec_ctx, ":authority", args->args[i].value.string); + channel->default_authority = grpc_mdelem_from_slices( + exec_ctx, GRPC_MDSTR_AUTHORITY, + grpc_slice_from_copied_string(args->args[i].value.string)); } } } else if (0 == strcmp(args->args[i].key, @@ -224,27 +226,17 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_completion_queue *cq, - const char *method, const char *host, + grpc_slice method, const grpc_slice *host, gpr_timespec deadline, void *reserved) { - GRPC_API_TRACE( - "grpc_channel_create_call(" - "channel=%p, parent_call=%p, propagation_mask=%x, cq=%p, method=%s, " - "host=%s, " - "deadline=gpr_timespec { tv_sec: %" PRId64 - ", tv_nsec: %d, clock_type: %d }, " - "reserved=%p)", - 10, - (channel, parent_call, (unsigned)propagation_mask, cq, method, host, - deadline.tv_sec, deadline.tv_nsec, (int)deadline.clock_type, reserved)); GPR_ASSERT(!reserved); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_call *call = grpc_channel_create_call_internal( &exec_ctx, channel, parent_call, propagation_mask, cq, NULL, - grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_PATH, - grpc_mdstr_from_string(method)), - host ? grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_AUTHORITY, - grpc_mdstr_from_string(host)) - : NULL, + grpc_mdelem_from_slices(&exec_ctx, GRPC_MDSTR_PATH, + grpc_slice_ref(method)), + host != NULL ? grpc_mdelem_from_slices(&exec_ctx, GRPC_MDSTR_AUTHORITY, + grpc_slice_ref(*host)) + : NULL, deadline); grpc_exec_ctx_finish(&exec_ctx); return call; @@ -252,17 +244,16 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel, grpc_call *grpc_channel_create_pollset_set_call( grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call, - uint32_t propagation_mask, grpc_pollset_set *pollset_set, - const char *method, const char *host, gpr_timespec deadline, - void *reserved) { + uint32_t propagation_mask, grpc_pollset_set *pollset_set, grpc_slice method, + const grpc_slice *host, gpr_timespec deadline, void *reserved) { GPR_ASSERT(!reserved); return grpc_channel_create_call_internal( exec_ctx, channel, parent_call, propagation_mask, NULL, pollset_set, - grpc_mdelem_from_metadata_strings(exec_ctx, GRPC_MDSTR_PATH, - grpc_mdstr_from_string(method)), - host ? grpc_mdelem_from_metadata_strings(exec_ctx, GRPC_MDSTR_AUTHORITY, - grpc_mdstr_from_string(host)) - : NULL, + grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_PATH, + grpc_slice_ref(method)), + host != NULL ? grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_AUTHORITY, + grpc_slice_ref(*host)) + : NULL, deadline); } @@ -274,11 +265,14 @@ void *grpc_channel_register_call(grpc_channel *channel, const char *method, 4, (channel, method, host, reserved)); GPR_ASSERT(!reserved); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - rc->path = grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_PATH, - grpc_mdstr_from_string(method)); + + rc->path = grpc_mdelem_from_slices( + &exec_ctx, GRPC_MDSTR_PATH, + grpc_slice_intern(grpc_slice_from_copied_string(method))); rc->authority = - host ? grpc_mdelem_from_metadata_strings(&exec_ctx, GRPC_MDSTR_AUTHORITY, - grpc_mdstr_from_string(host)) + host ? grpc_mdelem_from_slices( + &exec_ctx, GRPC_MDSTR_AUTHORITY, + grpc_slice_intern(grpc_slice_from_copied_string(host))) : NULL; gpr_mu_lock(&channel->registered_call_mu); rc->next = channel->registered_calls; @@ -385,6 +379,6 @@ grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_exec_ctx *exec_ctx, return GRPC_MDELEM_GRPC_STATUS_2; } gpr_ltoa(i, tmp); - return grpc_mdelem_from_metadata_strings(exec_ctx, GRPC_MDSTR_GRPC_STATUS, - grpc_mdstr_from_string(tmp)); + return grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_STATUS, + grpc_slice_from_copied_string(tmp)); } diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h index 2ebadb7a15..cbe48cd6a0 100644 --- a/src/core/lib/surface/channel.h +++ b/src/core/lib/surface/channel.h @@ -52,9 +52,8 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target, value of \a propagation_mask (see propagation_bits.h for possible values) */ grpc_call *grpc_channel_create_pollset_set_call( grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call, - uint32_t propagation_mask, grpc_pollset_set *pollset_set, - const char *method, const char *host, gpr_timespec deadline, - void *reserved); + uint32_t propagation_mask, grpc_pollset_set *pollset_set, grpc_slice method, + const grpc_slice *host, gpr_timespec deadline, void *reserved); /** Get a (borrowed) pointer to this channels underlying channel stack */ grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel); diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c index d606f70c2f..a43969be57 100644 --- a/src/core/lib/surface/lame_client.c +++ b/src/core/lib/surface/lame_client.c @@ -44,6 +44,7 @@ #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/channel.h" +#include "src/core/lib/transport/static_metadata.h" typedef struct { grpc_linked_mdelem status; @@ -61,9 +62,11 @@ static void fill_metadata(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, channel_data *chand = elem->channel_data; char tmp[GPR_LTOA_MIN_BUFSIZE]; gpr_ltoa(chand->error_code, tmp); - calld->status.md = grpc_mdelem_from_strings(exec_ctx, "grpc-status", tmp); - calld->details.md = - grpc_mdelem_from_strings(exec_ctx, "grpc-message", chand->error_message); + calld->status.md = grpc_mdelem_from_slices( + exec_ctx, GRPC_MDSTR_GRPC_STATUS, grpc_slice_from_copied_string(tmp)); + calld->details.md = grpc_mdelem_from_slices( + exec_ctx, GRPC_MDSTR_GRPC_MESSAGE, + grpc_slice_from_copied_string(chand->error_message)); calld->status.prev = calld->details.next = NULL; calld->status.next = &calld->details; calld->details.prev = &calld->status; diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c index 03e0913a91..3973630c85 100644 --- a/src/core/lib/surface/server.c +++ b/src/core/lib/surface/server.c @@ -98,8 +98,9 @@ typedef struct requested_call { typedef struct channel_registered_method { registered_method *server_registered_method; uint32_t flags; - grpc_mdstr *method; - grpc_mdstr *host; + bool has_host; + grpc_slice method; + grpc_slice host; } channel_registered_method; struct channel_data { @@ -144,8 +145,10 @@ struct call_data { /** the current state of a call - see call_state */ call_state state; - grpc_mdstr *path; - grpc_mdstr *host; + bool path_set; + bool host_set; + grpc_slice path; + grpc_slice host; gpr_timespec deadline; grpc_completion_queue *cq_new; @@ -460,17 +463,6 @@ static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand, op); } -static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) { - grpc_slice slice = value->slice; - size_t len = GRPC_SLICE_LENGTH(slice); - - if (len + 1 > *capacity) { - *capacity = GPR_MAX(len + 1, *capacity * 2); - *dest = gpr_realloc(*dest, *capacity); - } - memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1); -} - static void done_request_event(grpc_exec_ctx *exec_ctx, void *req, grpc_cq_completion *c) { requested_call *rc = req; @@ -499,12 +491,10 @@ static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server, GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata); switch (rc->type) { case BATCH_CALL: - GPR_ASSERT(calld->host != NULL); - GPR_ASSERT(calld->path != NULL); - cpstr(&rc->data.batch.details->host, - &rc->data.batch.details->host_capacity, calld->host); - cpstr(&rc->data.batch.details->method, - &rc->data.batch.details->method_capacity, calld->path); + GPR_ASSERT(calld->host_set); + GPR_ASSERT(calld->path_set); + rc->data.batch.details->host = grpc_slice_ref_internal(calld->host); + rc->data.batch.details->method = grpc_slice_ref_internal(calld->path); rc->data.batch.details->deadline = calld->deadline; rc->data.batch.details->flags = (calld->recv_idempotent_request @@ -624,35 +614,39 @@ static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { uint32_t hash; channel_registered_method *rm; - if (chand->registered_methods && calld->path && calld->host) { + if (chand->registered_methods && calld->path_set && calld->host_set) { /* TODO(ctiller): unify these two searches */ /* check for an exact match with host */ - hash = GRPC_MDSTR_KV_HASH(calld->host->hash, calld->path->hash); + hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(calld->host), + grpc_slice_hash(calld->path)); for (i = 0; i <= chand->registered_method_max_probes; i++) { rm = &chand->registered_methods[(hash + i) % chand->registered_method_slots]; if (!rm) break; - if (rm->host != calld->host) continue; - if (rm->method != calld->path) continue; + if (!rm->has_host) continue; + if (grpc_slice_cmp(rm->host, calld->host) != 0) continue; + if (grpc_slice_cmp(rm->method, calld->path) != 0) continue; if ((rm->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) && - !calld->recv_idempotent_request) + !calld->recv_idempotent_request) { continue; + } finish_start_new_rpc(exec_ctx, server, elem, &rm->server_registered_method->request_matcher, rm->server_registered_method->payload_handling); return; } /* check for a wildcard method definition (no host set) */ - hash = GRPC_MDSTR_KV_HASH(0, calld->path->hash); + hash = GRPC_MDSTR_KV_HASH(0, grpc_slice_hash(calld->path)); for (i = 0; i <= chand->registered_method_max_probes; i++) { rm = &chand->registered_methods[(hash + i) % chand->registered_method_slots]; if (!rm) break; - if (rm->host != NULL) continue; - if (rm->method != calld->path) continue; + if (rm->has_host) continue; + if (grpc_slice_cmp(rm->method, calld->path) != 0) continue; if ((rm->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) && - !calld->recv_idempotent_request) + !calld->recv_idempotent_request) { continue; + } finish_start_new_rpc(exec_ctx, server, elem, &rm->server_registered_method->request_matcher, rm->server_registered_method->payload_handling); @@ -745,14 +739,14 @@ static grpc_mdelem *server_filter(grpc_exec_ctx *exec_ctx, void *user_data, grpc_mdelem *md) { grpc_call_element *elem = user_data; call_data *calld = elem->call_data; - if (md->key == GRPC_MDSTR_PATH) { - if (calld->path == NULL) { - calld->path = GRPC_MDSTR_REF(md->value); + if (grpc_slice_cmp(md->key, GRPC_MDSTR_PATH) == 0) { + if (!calld->path_set) { + calld->path = grpc_slice_ref(md->value); } return NULL; - } else if (md->key == GRPC_MDSTR_AUTHORITY) { - if (calld->host == NULL) { - calld->host = GRPC_MDSTR_REF(md->value); + } else if (grpc_slice_cmp(md->key, GRPC_MDSTR_AUTHORITY) == 0) { + if (!calld->host_set) { + calld->host = grpc_slice_ref(md->value); } return NULL; } @@ -772,7 +766,7 @@ static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr, if (0 != gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) { calld->deadline = op_deadline; } - if (calld->host && calld->path) { + if (calld->host_set && calld->path_set) { /* do nothing */ } else { GRPC_ERROR_UNREF(error); @@ -904,11 +898,11 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, GPR_ASSERT(calld->state != PENDING); - if (calld->host) { - GRPC_MDSTR_UNREF(exec_ctx, calld->host); + if (calld->host_set) { + grpc_slice_unref_internal(exec_ctx, calld->host); } - if (calld->path) { - GRPC_MDSTR_UNREF(exec_ctx, calld->path); + if (calld->path_set) { + grpc_slice_unref_internal(exec_ctx, calld->path); } grpc_metadata_array_destroy(&calld->initial_metadata); @@ -938,11 +932,9 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, channel_data *chand = elem->channel_data; if (chand->registered_methods) { for (i = 0; i < chand->registered_method_slots; i++) { - if (chand->registered_methods[i].method) { - GRPC_MDSTR_UNREF(exec_ctx, chand->registered_methods[i].method); - } - if (chand->registered_methods[i].host) { - GRPC_MDSTR_UNREF(exec_ctx, chand->registered_methods[i].host); + grpc_slice_unref_internal(exec_ctx, chand->registered_methods[i].method); + if (chand->registered_methods[i].has_host) { + grpc_slice_unref_internal(exec_ctx, chand->registered_methods[i].host); } } gpr_free(chand->registered_methods); @@ -1140,8 +1132,6 @@ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s, channel_registered_method *crm; grpc_channel *channel; channel_data *chand; - grpc_mdstr *host; - grpc_mdstr *method; uint32_t hash; size_t slots; uint32_t probes; @@ -1180,9 +1170,18 @@ void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s, chand->registered_methods = gpr_malloc(alloc); memset(chand->registered_methods, 0, alloc); for (rm = s->registered_methods; rm; rm = rm->next) { - host = rm->host ? grpc_mdstr_from_string(rm->host) : NULL; - method = grpc_mdstr_from_string(rm->method); - hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash); + grpc_slice host; + bool has_host; + grpc_slice method; + if (rm->host != NULL) { + host = grpc_slice_intern(grpc_slice_from_copied_string(rm->host)); + has_host = true; + } else { + has_host = false; + } + method = grpc_slice_intern(grpc_slice_from_copied_string(rm->method)); + hash = GRPC_MDSTR_KV_HASH(has_host ? grpc_slice_hash(host) : 0, + grpc_slice_hash(method)); for (probes = 0; chand->registered_methods[(hash + probes) % slots] .server_registered_method != NULL; probes++) diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c index 54c39df6a7..cedf9170b7 100644 --- a/src/core/lib/transport/metadata.c +++ b/src/core/lib/transport/metadata.c @@ -52,8 +52,6 @@ #include "src/core/lib/support/string.h" #include "src/core/lib/transport/static_metadata.h" -grpc_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(grpc_slice input); - /* There are two kinds of mdelem and mdstr instances. * Static instances are declared in static_metadata.{h,c} and * are initialized by grpc_mdctx_global_init(). @@ -63,9 +61,6 @@ grpc_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(grpc_slice input); * used to determine which kind of element a pointer refers to. */ -#define INITIAL_STRTAB_CAPACITY 4 -#define INITIAL_MDTAB_CAPACITY 4 - #ifdef GRPC_METADATA_REFCOUNT_DEBUG #define DEBUG_ARGS , const char *file, int line #define FWD_DEBUG_ARGS , file, line @@ -76,37 +71,20 @@ grpc_slice (*grpc_chttp2_base64_encode_and_huffman_compress)(grpc_slice input); #define REF_MD_LOCKED(shard, s) ref_md_locked((shard), (s)) #endif -#define TABLE_IDX(hash, log2_shards, capacity) \ - (((hash) >> (log2_shards)) % (capacity)) -#define SHARD_IDX(hash, log2_shards) ((hash) & ((1 << (log2_shards)) - 1)) - -typedef void (*destroy_user_data_func)(void *user_data); - -#define SIZE_IN_DECODER_TABLE_NOT_SET -1 -/* Shadow structure for grpc_mdstr for non-static values */ -typedef struct internal_string { - /* must be byte compatible with grpc_mdstr */ - grpc_slice slice; - uint32_t hash; +#define INITIAL_SHARD_CAPACITY 8 +#define LOG2_SHARD_COUNT 4 +#define SHARD_COUNT ((size_t)(1 << LOG2_SHARD_COUNT)) - /* private only data */ - gpr_atm refcnt; +#define TABLE_IDX(hash, capacity) (((hash) >> (LOG2_SHARD_COUNT)) % (capacity)) +#define SHARD_IDX(hash) ((hash) & ((1 << (LOG2_SHARD_COUNT)) - 1)) - uint8_t has_base64_and_huffman_encoded; - grpc_slice_refcount refcount; - - grpc_slice base64_and_huffman; - - gpr_atm size_in_decoder_table; - - struct internal_string *bucket_next; -} internal_string; +typedef void (*destroy_user_data_func)(void *user_data); /* Shadow structure for grpc_mdelem for non-static elements */ typedef struct internal_metadata { /* must be byte compatible with grpc_mdelem */ - internal_string *key; - internal_string *value; + grpc_slice key; + grpc_slice value; /* private only data */ gpr_atm refcnt; @@ -118,13 +96,6 @@ typedef struct internal_metadata { struct internal_metadata *bucket_next; } internal_metadata; -typedef struct strtab_shard { - gpr_mu mu; - internal_string **strs; - size_t count; - size_t capacity; -} strtab_shard; - typedef struct mdtab_shard { gpr_mu mu; internal_metadata **elems; @@ -136,23 +107,16 @@ typedef struct mdtab_shard { gpr_atm free_estimate; } mdtab_shard; -#define LOG2_STRTAB_SHARD_COUNT 5 -#define LOG2_MDTAB_SHARD_COUNT 4 -#define STRTAB_SHARD_COUNT ((size_t)(1 << LOG2_STRTAB_SHARD_COUNT)) -#define MDTAB_SHARD_COUNT ((size_t)(1 << LOG2_MDTAB_SHARD_COUNT)) - /* hash seed: decided at initialization time */ static uint32_t g_hash_seed; static int g_forced_hash_seed = 0; /* linearly probed hash tables for static element lookup */ -static grpc_mdstr *g_static_strtab[GRPC_STATIC_MDSTR_COUNT * 2]; static grpc_mdelem *g_static_mdtab[GRPC_STATIC_MDELEM_COUNT * 2]; static size_t g_static_strtab_maxprobe; static size_t g_static_mdtab_maxprobe; -static strtab_shard g_strtab_shard[STRTAB_SHARD_COUNT]; -static mdtab_shard g_mdtab_shard[MDTAB_SHARD_COUNT]; +static mdtab_shard g_shards[SHARD_COUNT]; static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard); @@ -162,17 +126,18 @@ void grpc_test_only_set_metadata_hash_seed(uint32_t seed) { } void grpc_mdctx_global_init(void) { - size_t i, j; + size_t i; if (!g_forced_hash_seed) { g_hash_seed = (uint32_t)gpr_now(GPR_CLOCK_REALTIME).tv_nsec; } g_static_strtab_maxprobe = 0; g_static_mdtab_maxprobe = 0; +#if 0 /* build static tables */ memset(g_static_mdtab, 0, sizeof(g_static_mdtab)); memset(g_static_strtab, 0, sizeof(g_static_strtab)); for (i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) { - grpc_mdstr *elem = &grpc_static_mdstr_table[i]; + grpc_slice elem = &grpc_static_mdstr_table[i]; const char *str = grpc_static_metadata_strings[i]; uint32_t hash = gpr_murmur_hash3(str, strlen(str), g_hash_seed); *(grpc_slice *)&elem->slice = grpc_slice_from_static_string(str); @@ -190,13 +155,13 @@ void grpc_mdctx_global_init(void) { } for (i = 0; i < GRPC_STATIC_MDELEM_COUNT; i++) { grpc_mdelem *elem = &grpc_static_mdelem_table[i]; - grpc_mdstr *key = + grpc_slice key = &grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 0]]; - grpc_mdstr *value = + grpc_slice value = &grpc_static_mdstr_table[grpc_static_metadata_elem_indices[2 * i + 1]]; uint32_t hash = GRPC_MDSTR_KV_HASH(key->hash, value->hash); - *(grpc_mdstr **)&elem->key = key; - *(grpc_mdstr **)&elem->value = value; + *(grpc_slice *)&elem->key = key; + *(grpc_slice *)&elem->value = value; for (j = 0;; j++) { size_t idx = (hash + j) % GPR_ARRAY_SIZE(g_static_mdtab); if (g_static_mdtab[idx] == NULL) { @@ -208,21 +173,14 @@ void grpc_mdctx_global_init(void) { g_static_mdtab_maxprobe = j; } } +#endif /* initialize shards */ - for (i = 0; i < STRTAB_SHARD_COUNT; i++) { - strtab_shard *shard = &g_strtab_shard[i]; - gpr_mu_init(&shard->mu); - shard->count = 0; - shard->capacity = INITIAL_STRTAB_CAPACITY; - shard->strs = gpr_malloc(sizeof(*shard->strs) * shard->capacity); - memset(shard->strs, 0, sizeof(*shard->strs) * shard->capacity); - } - for (i = 0; i < MDTAB_SHARD_COUNT; i++) { - mdtab_shard *shard = &g_mdtab_shard[i]; + for (i = 0; i < SHARD_COUNT; i++) { + mdtab_shard *shard = &g_shards[i]; gpr_mu_init(&shard->mu); shard->count = 0; gpr_atm_no_barrier_store(&shard->free_estimate, 0); - shard->capacity = INITIAL_MDTAB_CAPACITY; + shard->capacity = INITIAL_SHARD_CAPACITY; shard->elems = gpr_malloc(sizeof(*shard->elems) * shard->capacity); memset(shard->elems, 0, sizeof(*shard->elems) * shard->capacity); } @@ -230,8 +188,8 @@ void grpc_mdctx_global_init(void) { void grpc_mdctx_global_shutdown(grpc_exec_ctx *exec_ctx) { size_t i; - for (i = 0; i < MDTAB_SHARD_COUNT; i++) { - mdtab_shard *shard = &g_mdtab_shard[i]; + for (i = 0; i < SHARD_COUNT; i++) { + mdtab_shard *shard = &g_shards[i]; gpr_mu_destroy(&shard->mu); gc_mdtab(exec_ctx, shard); /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */ @@ -244,30 +202,6 @@ void grpc_mdctx_global_shutdown(grpc_exec_ctx *exec_ctx) { } gpr_free(shard->elems); } - for (i = 0; i < STRTAB_SHARD_COUNT; i++) { - strtab_shard *shard = &g_strtab_shard[i]; - gpr_mu_destroy(&shard->mu); - /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */ - if (shard->count != 0) { - gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata strings were leaked", - shard->count); - for (size_t j = 0; j < shard->capacity; j++) { - for (internal_string *s = shard->strs[j]; s; s = s->bucket_next) { - gpr_log(GPR_DEBUG, "LEAKED: %s", - grpc_mdstr_as_c_string((grpc_mdstr *)s)); - } - } - if (grpc_iomgr_abort_on_leaks()) { - abort(); - } - } - gpr_free(shard->strs); - } -} - -static int is_mdstr_static(grpc_mdstr *s) { - return s >= &grpc_static_mdstr_table[0] && - s < &grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT]; } static int is_mdelem_static(grpc_mdelem *e) { @@ -282,170 +216,14 @@ static void ref_md_locked(mdtab_shard *shard, "ELM REF:%p:%zu->%zu: '%s' = '%s'", (void *)md, gpr_atm_no_barrier_load(&md->refcnt), gpr_atm_no_barrier_load(&md->refcnt) + 1, - grpc_mdstr_as_c_string((grpc_mdstr *)md->key), - grpc_mdstr_as_c_string((grpc_mdstr *)md->value)); + grpc_mdstr_as_c_string((grpc_slice)md->key), + grpc_mdstr_as_c_string((grpc_slice)md->value)); #endif if (0 == gpr_atm_no_barrier_fetch_add(&md->refcnt, 1)) { gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -1); } } -static void grow_strtab(strtab_shard *shard) { - size_t capacity = shard->capacity * 2; - size_t i; - internal_string **strtab; - internal_string *s, *next; - - GPR_TIMER_BEGIN("grow_strtab", 0); - - strtab = gpr_malloc(sizeof(internal_string *) * capacity); - memset(strtab, 0, sizeof(internal_string *) * capacity); - - for (i = 0; i < shard->capacity; i++) { - for (s = shard->strs[i]; s; s = next) { - size_t idx = TABLE_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT, capacity); - next = s->bucket_next; - s->bucket_next = strtab[idx]; - strtab[idx] = s; - } - } - - gpr_free(shard->strs); - shard->strs = strtab; - shard->capacity = capacity; - - GPR_TIMER_END("grow_strtab", 0); -} - -static void internal_destroy_string(grpc_exec_ctx *exec_ctx, - strtab_shard *shard, internal_string *is) { - internal_string **prev_next; - internal_string *cur; - GPR_TIMER_BEGIN("internal_destroy_string", 0); - if (is->has_base64_and_huffman_encoded) { - grpc_slice_unref_internal(exec_ctx, is->base64_and_huffman); - } - for (prev_next = &shard->strs[TABLE_IDX(is->hash, LOG2_STRTAB_SHARD_COUNT, - shard->capacity)], - cur = *prev_next; - cur != is; prev_next = &cur->bucket_next, cur = cur->bucket_next) - ; - *prev_next = cur->bucket_next; - shard->count--; - gpr_free(is); - GPR_TIMER_END("internal_destroy_string", 0); -} - -static void slice_ref(void *p) { - internal_string *is = - (internal_string *)((char *)p - offsetof(internal_string, refcount)); - GRPC_MDSTR_REF((grpc_mdstr *)(is)); -} - -static void slice_unref(grpc_exec_ctx *exec_ctx, void *p) { - internal_string *is = - (internal_string *)((char *)p - offsetof(internal_string, refcount)); - GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)(is)); -} - -grpc_mdstr *grpc_mdstr_from_string(const char *str) { - return grpc_mdstr_from_buffer((const uint8_t *)str, strlen(str)); -} - -grpc_mdstr *grpc_mdstr_from_slice(grpc_exec_ctx *exec_ctx, grpc_slice slice) { - grpc_mdstr *result = grpc_mdstr_from_buffer(GRPC_SLICE_START_PTR(slice), - GRPC_SLICE_LENGTH(slice)); - grpc_slice_unref_internal(exec_ctx, slice); - return result; -} - -grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *buf, size_t length) { - uint32_t hash = gpr_murmur_hash3(buf, length, g_hash_seed); - internal_string *s; - strtab_shard *shard = - &g_strtab_shard[SHARD_IDX(hash, LOG2_STRTAB_SHARD_COUNT)]; - size_t i; - size_t idx; - - GPR_TIMER_BEGIN("grpc_mdstr_from_buffer", 0); - - /* search for a static string */ - for (i = 0; i <= g_static_strtab_maxprobe; i++) { - grpc_mdstr *ss; - idx = (hash + i) % GPR_ARRAY_SIZE(g_static_strtab); - ss = g_static_strtab[idx]; - if (ss == NULL) break; - if (ss->hash == hash && GRPC_SLICE_LENGTH(ss->slice) == length && - (length == 0 || - 0 == memcmp(buf, GRPC_SLICE_START_PTR(ss->slice), length))) { - GPR_TIMER_END("grpc_mdstr_from_buffer", 0); - return ss; - } - } - - gpr_mu_lock(&shard->mu); - - /* search for an existing string */ - idx = TABLE_IDX(hash, LOG2_STRTAB_SHARD_COUNT, shard->capacity); - for (s = shard->strs[idx]; s; s = s->bucket_next) { - if (s->hash == hash && GRPC_SLICE_LENGTH(s->slice) == length && - 0 == memcmp(buf, GRPC_SLICE_START_PTR(s->slice), length)) { - if (gpr_atm_full_fetch_add(&s->refcnt, 1) == 0) { - /* If we get here, we've added a ref to something that was about to - * die - drop it immediately. - * The *only* possible path here (given the shard mutex) should be to - * drop from one ref back to zero - assert that with a CAS */ - GPR_ASSERT(gpr_atm_rel_cas(&s->refcnt, 1, 0)); - /* and treat this as if we were never here... sshhh */ - } else { - gpr_mu_unlock(&shard->mu); - GPR_TIMER_END("grpc_mdstr_from_buffer", 0); - return (grpc_mdstr *)s; - } - } - } - - /* not found: create a new string */ - if (length + 1 < GRPC_SLICE_INLINED_SIZE) { - /* string data goes directly into the slice */ - s = gpr_malloc(sizeof(internal_string)); - gpr_atm_rel_store(&s->refcnt, 1); - s->slice.refcount = NULL; - memcpy(s->slice.data.inlined.bytes, buf, length); - s->slice.data.inlined.bytes[length] = 0; - s->slice.data.inlined.length = (uint8_t)length; - } else { - /* string data goes after the internal_string header, and we +1 for null - terminator */ - s = gpr_malloc(sizeof(internal_string) + length + 1); - gpr_atm_rel_store(&s->refcnt, 1); - s->refcount.ref = slice_ref; - s->refcount.unref = slice_unref; - s->slice.refcount = &s->refcount; - s->slice.data.refcounted.bytes = (uint8_t *)(s + 1); - s->slice.data.refcounted.length = length; - memcpy(s->slice.data.refcounted.bytes, buf, length); - /* add a null terminator for cheap c string conversion when desired */ - s->slice.data.refcounted.bytes[length] = 0; - } - s->has_base64_and_huffman_encoded = 0; - s->hash = hash; - s->size_in_decoder_table = SIZE_IN_DECODER_TABLE_NOT_SET; - s->bucket_next = shard->strs[idx]; - shard->strs[idx] = s; - - shard->count++; - - if (shard->count > shard->capacity * 2) { - grow_strtab(shard); - } - - gpr_mu_unlock(&shard->mu); - GPR_TIMER_END("grpc_mdstr_from_buffer", 0); - - return (grpc_mdstr *)s; -} - static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) { size_t i; internal_metadata **prev_next; @@ -459,8 +237,8 @@ static void gc_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) { void *user_data = (void *)gpr_atm_no_barrier_load(&md->user_data); next = md->bucket_next; if (gpr_atm_acq_load(&md->refcnt) == 0) { - GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)md->key); - GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)md->value); + grpc_slice_unref_internal(exec_ctx, md->key); + grpc_slice_unref_internal(exec_ctx, md->value); if (md->user_data) { ((destroy_user_data_func)gpr_atm_no_barrier_load( &md->destroy_user_data))(user_data); @@ -493,9 +271,10 @@ static void grow_mdtab(mdtab_shard *shard) { for (i = 0; i < shard->capacity; i++) { for (md = shard->elems[i]; md; md = next) { size_t idx; - hash = GRPC_MDSTR_KV_HASH(md->key->hash, md->value->hash); + hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(md->key), + grpc_slice_hash(md->value)); next = md->bucket_next; - idx = TABLE_IDX(hash, LOG2_MDTAB_SHARD_COUNT, capacity); + idx = TABLE_IDX(hash, capacity); md->bucket_next = mdtab[idx]; mdtab[idx] = md; } @@ -517,26 +296,26 @@ static void rehash_mdtab(grpc_exec_ctx *exec_ctx, mdtab_shard *shard) { } } -grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_exec_ctx *exec_ctx, - grpc_mdstr *mkey, - grpc_mdstr *mvalue) { - internal_string *key = (internal_string *)mkey; - internal_string *value = (internal_string *)mvalue; - uint32_t hash = GRPC_MDSTR_KV_HASH(mkey->hash, mvalue->hash); +grpc_mdelem *grpc_mdelem_from_slices(grpc_exec_ctx *exec_ctx, grpc_slice key, + grpc_slice value) { + uint32_t hash = + GRPC_MDSTR_KV_HASH(grpc_slice_hash(key), grpc_slice_hash(value)); internal_metadata *md; - mdtab_shard *shard = &g_mdtab_shard[SHARD_IDX(hash, LOG2_MDTAB_SHARD_COUNT)]; + mdtab_shard *shard = &g_shards[SHARD_IDX(hash)]; size_t i; size_t idx; GPR_TIMER_BEGIN("grpc_mdelem_from_metadata_strings", 0); - if (is_mdstr_static(mkey) && is_mdstr_static(mvalue)) { + if (grpc_is_static_metadata_string(key) && + grpc_is_static_metadata_string(value)) { for (i = 0; i <= g_static_mdtab_maxprobe; i++) { grpc_mdelem *smd; idx = (hash + i) % GPR_ARRAY_SIZE(g_static_mdtab); smd = g_static_mdtab[idx]; if (smd == NULL) break; - if (smd->key == mkey && smd->value == mvalue) { + if (grpc_slice_cmp(key, smd->key) == 0 && + grpc_slice_cmp(value, smd->value) == 0) { GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0); return smd; } @@ -545,14 +324,15 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_exec_ctx *exec_ctx, gpr_mu_lock(&shard->mu); - idx = TABLE_IDX(hash, LOG2_MDTAB_SHARD_COUNT, shard->capacity); + idx = TABLE_IDX(hash, shard->capacity); /* search for an existing pair */ for (md = shard->elems[idx]; md; md = md->bucket_next) { - if (md->key == key && md->value == value) { + if (grpc_slice_cmp(key, md->key) == 0 && + grpc_slice_cmp(value, md->value) == 0) { REF_MD_LOCKED(shard, md); - GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)key); - GRPC_MDSTR_UNREF(exec_ctx, (grpc_mdstr *)value); gpr_mu_unlock(&shard->mu); + grpc_slice_unref_internal(exec_ctx, key); + grpc_slice_unref_internal(exec_ctx, value); GPR_TIMER_END("grpc_mdelem_from_metadata_strings", 0); return (grpc_mdelem *)md; } @@ -571,8 +351,8 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_exec_ctx *exec_ctx, #ifdef GRPC_METADATA_REFCOUNT_DEBUG gpr_log(GPR_DEBUG, "ELM NEW:%p:%zu: '%s' = '%s'", (void *)md, gpr_atm_no_barrier_load(&md->refcnt), - grpc_mdstr_as_c_string((grpc_mdstr *)md->key), - grpc_mdstr_as_c_string((grpc_mdstr *)md->value)); + grpc_mdstr_as_c_string((grpc_slice)md->key), + grpc_mdstr_as_c_string((grpc_slice)md->value)); #endif shard->count++; @@ -587,58 +367,19 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_exec_ctx *exec_ctx, return (grpc_mdelem *)md; } -grpc_mdelem *grpc_mdelem_from_strings(grpc_exec_ctx *exec_ctx, const char *key, - const char *value) { - return grpc_mdelem_from_metadata_strings( - exec_ctx, grpc_mdstr_from_string(key), grpc_mdstr_from_string(value)); -} - -grpc_mdelem *grpc_mdelem_from_slices(grpc_exec_ctx *exec_ctx, grpc_slice key, - grpc_slice value) { - return grpc_mdelem_from_metadata_strings( - exec_ctx, grpc_mdstr_from_slice(exec_ctx, key), - grpc_mdstr_from_slice(exec_ctx, value)); -} - -grpc_mdelem *grpc_mdelem_from_string_and_buffer(grpc_exec_ctx *exec_ctx, - const char *key, - const uint8_t *value, - size_t value_length) { - return grpc_mdelem_from_metadata_strings( - exec_ctx, grpc_mdstr_from_string(key), - grpc_mdstr_from_buffer(value, value_length)); -} - static size_t get_base64_encoded_size(size_t raw_length) { static const uint8_t tail_xtra[3] = {0, 2, 3}; return raw_length / 3 * 4 + tail_xtra[raw_length % 3]; } size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem *elem) { - size_t overhead_and_key = 32 + GRPC_SLICE_LENGTH(elem->key->slice); - size_t value_len = GRPC_SLICE_LENGTH(elem->value->slice); - if (is_mdstr_static(elem->value)) { - if (grpc_is_binary_header( - (const char *)GRPC_SLICE_START_PTR(elem->key->slice), - GRPC_SLICE_LENGTH(elem->key->slice))) { - return overhead_and_key + get_base64_encoded_size(value_len); - } else { - return overhead_and_key + value_len; - } + size_t overhead_and_key = 32 + GRPC_SLICE_LENGTH(elem->key); + size_t value_len = GRPC_SLICE_LENGTH(elem->value); + if (grpc_is_binary_header((const char *)GRPC_SLICE_START_PTR(elem->key), + GRPC_SLICE_LENGTH(elem->key))) { + return overhead_and_key + get_base64_encoded_size(value_len); } else { - internal_string *is = (internal_string *)elem->value; - gpr_atm current_size = gpr_atm_acq_load(&is->size_in_decoder_table); - if (current_size == SIZE_IN_DECODER_TABLE_NOT_SET) { - if (grpc_is_binary_header( - (const char *)GRPC_SLICE_START_PTR(elem->key->slice), - GRPC_SLICE_LENGTH(elem->key->slice))) { - current_size = (gpr_atm)get_base64_encoded_size(value_len); - } else { - current_size = (gpr_atm)value_len; - } - gpr_atm_rel_store(&is->size_in_decoder_table, current_size); - } - return overhead_and_key + (size_t)current_size; + return overhead_and_key + value_len; } } @@ -650,8 +391,8 @@ grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *gmd DEBUG_ARGS) { "ELM REF:%p:%zu->%zu: '%s' = '%s'", (void *)md, gpr_atm_no_barrier_load(&md->refcnt), gpr_atm_no_barrier_load(&md->refcnt) + 1, - grpc_mdstr_as_c_string((grpc_mdstr *)md->key), - grpc_mdstr_as_c_string((grpc_mdstr *)md->value)); + grpc_mdstr_as_c_string((grpc_slice)md->key), + grpc_mdstr_as_c_string((grpc_slice)md->value)); #endif /* we can assume the ref count is >= 1 as the application is calling this function - meaning that no adjustment to mdtab_free is necessary, @@ -671,57 +412,21 @@ void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem *gmd DEBUG_ARGS) { "ELM UNREF:%p:%zu->%zu: '%s' = '%s'", (void *)md, gpr_atm_no_barrier_load(&md->refcnt), gpr_atm_no_barrier_load(&md->refcnt) - 1, - grpc_mdstr_as_c_string((grpc_mdstr *)md->key), - grpc_mdstr_as_c_string((grpc_mdstr *)md->value)); + grpc_mdstr_as_c_string((grpc_slice)md->key), + grpc_mdstr_as_c_string((grpc_slice)md->value)); #endif - uint32_t hash = GRPC_MDSTR_KV_HASH(md->key->hash, md->value->hash); + uint32_t hash = + GRPC_MDSTR_KV_HASH(grpc_slice_hash(md->key), grpc_slice_hash(md->value)); const gpr_atm prev_refcount = gpr_atm_full_fetch_add(&md->refcnt, -1); GPR_ASSERT(prev_refcount >= 1); if (1 == prev_refcount) { /* once the refcount hits zero, some other thread can come along and free md at any time: it's unsafe from this point on to access it */ - mdtab_shard *shard = - &g_mdtab_shard[SHARD_IDX(hash, LOG2_MDTAB_SHARD_COUNT)]; + mdtab_shard *shard = &g_shards[SHARD_IDX(hash)]; gpr_atm_no_barrier_fetch_add(&shard->free_estimate, 1); } } -const char *grpc_mdstr_as_c_string(const grpc_mdstr *s) { - return (const char *)GRPC_SLICE_START_PTR(s->slice); -} - -size_t grpc_mdstr_length(const grpc_mdstr *s) { return GRPC_MDSTR_LENGTH(s); } - -grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *gs DEBUG_ARGS) { - internal_string *s = (internal_string *)gs; - if (is_mdstr_static(gs)) return gs; -#ifdef GRPC_METADATA_REFCOUNT_DEBUG - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "STR REF:%p:%zu->%zu: '%s'", - (void *)s, gpr_atm_no_barrier_load(&s->refcnt), - gpr_atm_no_barrier_load(&s->refcnt) + 1, grpc_mdstr_as_c_string(gs)); -#endif - GPR_ASSERT(gpr_atm_full_fetch_add(&s->refcnt, 1) > 0); - return gs; -} - -void grpc_mdstr_unref(grpc_exec_ctx *exec_ctx, grpc_mdstr *gs DEBUG_ARGS) { - internal_string *s = (internal_string *)gs; - if (is_mdstr_static(gs)) return; -#ifdef GRPC_METADATA_REFCOUNT_DEBUG - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "STR UNREF:%p:%zu->%zu: '%s'", - (void *)s, gpr_atm_no_barrier_load(&s->refcnt), - gpr_atm_no_barrier_load(&s->refcnt) - 1, grpc_mdstr_as_c_string(gs)); -#endif - if (1 == gpr_atm_full_fetch_add(&s->refcnt, -1)) { - strtab_shard *shard = - &g_strtab_shard[SHARD_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT)]; - gpr_mu_lock(&shard->mu); - GPR_ASSERT(0 == gpr_atm_no_barrier_load(&s->refcnt)); - internal_destroy_string(exec_ctx, shard, s); - gpr_mu_unlock(&shard->mu); - } -} - void *grpc_mdelem_get_user_data(grpc_mdelem *md, void (*destroy_func)(void *)) { internal_metadata *im = (internal_metadata *)md; void *result; @@ -755,19 +460,3 @@ void *grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *), gpr_mu_unlock(&im->mu_user_data); return user_data; } - -grpc_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *gs) { - internal_string *s = (internal_string *)gs; - grpc_slice slice; - strtab_shard *shard = - &g_strtab_shard[SHARD_IDX(s->hash, LOG2_STRTAB_SHARD_COUNT)]; - gpr_mu_lock(&shard->mu); - if (!s->has_base64_and_huffman_encoded) { - s->base64_and_huffman = - grpc_chttp2_base64_encode_and_huffman_compress(s->slice); - s->has_base64_and_huffman_encoded = 1; - } - slice = s->base64_and_huffman; - gpr_mu_unlock(&shard->mu); - return slice; -} diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 991eee96f1..50c8e1fa91 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -74,51 +74,19 @@ extern "C" { declared here - in which case those functions are effectively no-ops. */ /* Forward declarations */ -typedef struct grpc_mdstr grpc_mdstr; typedef struct grpc_mdelem grpc_mdelem; -/* if changing this, make identical changes in internal_string in metadata.c */ -struct grpc_mdstr { - const grpc_slice slice; - const uint32_t hash; - /* there is a private part to this in metadata.c */ -}; - /* if changing this, make identical changes in internal_metadata in metadata.c */ struct grpc_mdelem { - grpc_mdstr *const key; - grpc_mdstr *const value; + const grpc_slice key; + const grpc_slice value; /* there is a private part to this in metadata.c */ }; -void grpc_test_only_set_metadata_hash_seed(uint32_t seed); - -/* Constructors for grpc_mdstr instances; take a variety of data types that - clients may have handy */ -grpc_mdstr *grpc_mdstr_from_string(const char *str); -/* Unrefs the slice. */ -grpc_mdstr *grpc_mdstr_from_slice(grpc_exec_ctx *exec_ctx, grpc_slice slice); -grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *str, size_t length); - -/* Returns a borrowed slice from the mdstr with its contents base64 encoded - and huffman compressed */ -grpc_slice grpc_mdstr_as_base64_encoded_and_huffman_compressed(grpc_mdstr *str); - -/* Constructors for grpc_mdelem instances; take a variety of data types that - clients may have handy */ -grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_exec_ctx *exec_ctx, - grpc_mdstr *key, - grpc_mdstr *value); -grpc_mdelem *grpc_mdelem_from_strings(grpc_exec_ctx *exec_ctx, const char *key, - const char *value); /* Unrefs the slices. */ grpc_mdelem *grpc_mdelem_from_slices(grpc_exec_ctx *exec_ctx, grpc_slice key, grpc_slice value); -grpc_mdelem *grpc_mdelem_from_string_and_buffer(grpc_exec_ctx *exec_ctx, - const char *key, - const uint8_t *value, - size_t value_length); size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem *elem); @@ -132,52 +100,28 @@ void *grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *), /* Reference counting */ //#define GRPC_METADATA_REFCOUNT_DEBUG #ifdef GRPC_METADATA_REFCOUNT_DEBUG -#define GRPC_MDSTR_REF(s) grpc_mdstr_ref((s), __FILE__, __LINE__) -#define GRPC_MDSTR_UNREF(exec_ctx, s) \ - grpc_mdstr_unref((exec_ctx), (s), __FILE__, __LINE__) #define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s), __FILE__, __LINE__) #define GRPC_MDELEM_UNREF(exec_ctx, s) \ grpc_mdelem_unref((exec_ctx), (s), __FILE__, __LINE__) -grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *s, const char *file, int line); -void grpc_mdstr_unref(grpc_exec_ctx *exec_ctx, grpc_mdstr *s, const char *file, - int line); grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *md, const char *file, int line); void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem *md, const char *file, int line); #else -#define GRPC_MDSTR_REF(s) grpc_mdstr_ref((s)) -#define GRPC_MDSTR_UNREF(exec_ctx, s) grpc_mdstr_unref((exec_ctx), (s)) #define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s)) #define GRPC_MDELEM_UNREF(exec_ctx, s) grpc_mdelem_unref((exec_ctx), (s)) -grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *s); -void grpc_mdstr_unref(grpc_exec_ctx *exec_ctx, grpc_mdstr *s); grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *md); void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem *md); #endif -/* Recover a char* from a grpc_mdstr. The returned string is null terminated. - Does not promise that the returned string has no embedded nulls however. */ -const char *grpc_mdstr_as_c_string(const grpc_mdstr *s); - -#define GRPC_MDSTR_LENGTH(s) (GRPC_SLICE_LENGTH(s->slice)) - /* We add 32 bytes of padding as per RFC-7540 section 6.5.2. */ #define GRPC_MDELEM_LENGTH(e) \ - (GRPC_MDSTR_LENGTH((e)->key) + GRPC_MDSTR_LENGTH((e)->value) + 32) - -int grpc_mdstr_is_legal_header(grpc_mdstr *s); -int grpc_mdstr_is_legal_nonbin_header(grpc_mdstr *s); -int grpc_mdstr_is_bin_suffixed(grpc_mdstr *s); + (GRPC_SLICE_LENGTH((e)->key) + GRPC_SLICE_LENGTH((e)->value) + 32) #define GRPC_MDSTR_KV_HASH(k_hash, v_hash) (GPR_ROTL((k_hash), 2) ^ (v_hash)) void grpc_mdctx_global_init(void); void grpc_mdctx_global_shutdown(grpc_exec_ctx *exec_ctx); -/* Implementation provided by chttp2_transport */ -extern grpc_slice (*grpc_chttp2_base64_encode_and_huffman_compress)( - grpc_slice input); - #ifdef __cplusplus } #endif diff --git a/src/core/lib/transport/method_config.c b/src/core/lib/transport/method_config.c index 25fb54b37d..75317d426d 100644 --- a/src/core/lib/transport/method_config.c +++ b/src/core/lib/transport/method_config.c @@ -39,8 +39,10 @@ #include <grpc/support/string_util.h> #include <grpc/support/time.h> -#include "src/core/lib/transport/mdstr_hash_table.h" +#include "src/core/lib/slice/slice_hash_table.h" +#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" +#include "src/core/lib/transport/static_metadata.h" // // grpc_method_config @@ -48,252 +50,224 @@ // bool vtable -static void* bool_copy(void* valuep) { - bool value = *(bool*)valuep; - bool* new_value = gpr_malloc(sizeof(bool)); +static void *bool_copy(void *valuep) { + bool value = *(bool *)valuep; + bool *new_value = gpr_malloc(sizeof(bool)); *new_value = value; return new_value; } -static int bool_cmp(void* v1, void* v2) { - bool b1 = *(bool*)v1; - bool b2 = *(bool*)v2; +static int bool_cmp(void *v1, void *v2) { + bool b1 = *(bool *)v1; + bool b2 = *(bool *)v2; if (!b1 && b2) return -1; if (b1 && !b2) return 1; return 0; } -static void free_mem(grpc_exec_ctx* exec_ctx, void* p) { gpr_free(p); } +static void free_mem(grpc_exec_ctx *exec_ctx, void *p) { gpr_free(p); } -static grpc_mdstr_hash_table_vtable bool_vtable = {free_mem, bool_copy, +static grpc_slice_hash_table_vtable bool_vtable = {free_mem, bool_copy, bool_cmp}; // timespec vtable -static void* timespec_copy(void* valuep) { - gpr_timespec value = *(gpr_timespec*)valuep; - gpr_timespec* new_value = gpr_malloc(sizeof(gpr_timespec)); +static void *timespec_copy(void *valuep) { + gpr_timespec value = *(gpr_timespec *)valuep; + gpr_timespec *new_value = gpr_malloc(sizeof(gpr_timespec)); *new_value = value; return new_value; } -static int timespec_cmp(void* v1, void* v2) { - return gpr_time_cmp(*(gpr_timespec*)v1, *(gpr_timespec*)v2); +static int timespec_cmp(void *v1, void *v2) { + return gpr_time_cmp(*(gpr_timespec *)v1, *(gpr_timespec *)v2); } -static grpc_mdstr_hash_table_vtable timespec_vtable = {free_mem, timespec_copy, +static grpc_slice_hash_table_vtable timespec_vtable = {free_mem, timespec_copy, timespec_cmp}; // int32 vtable -static void* int32_copy(void* valuep) { - int32_t value = *(int32_t*)valuep; - int32_t* new_value = gpr_malloc(sizeof(int32_t)); +static void *int32_copy(void *valuep) { + int32_t value = *(int32_t *)valuep; + int32_t *new_value = gpr_malloc(sizeof(int32_t)); *new_value = value; return new_value; } -static int int32_cmp(void* v1, void* v2) { - int32_t i1 = *(int32_t*)v1; - int32_t i2 = *(int32_t*)v2; +static int int32_cmp(void *v1, void *v2) { + int32_t i1 = *(int32_t *)v1; + int32_t i2 = *(int32_t *)v2; if (i1 < i2) return -1; if (i1 > i2) return 1; return 0; } -static grpc_mdstr_hash_table_vtable int32_vtable = {free_mem, int32_copy, +static grpc_slice_hash_table_vtable int32_vtable = {free_mem, int32_copy, int32_cmp}; -// Hash table keys. -#define GRPC_METHOD_CONFIG_WAIT_FOR_READY "grpc.wait_for_ready" // bool -#define GRPC_METHOD_CONFIG_TIMEOUT "grpc.timeout" // gpr_timespec -#define GRPC_METHOD_CONFIG_MAX_REQUEST_MESSAGE_BYTES \ - "grpc.max_request_message_bytes" // int32 -#define GRPC_METHOD_CONFIG_MAX_RESPONSE_MESSAGE_BYTES \ - "grpc.max_response_message_bytes" // int32 - struct grpc_method_config { - grpc_mdstr_hash_table* table; - grpc_mdstr* wait_for_ready_key; - grpc_mdstr* timeout_key; - grpc_mdstr* max_request_message_bytes_key; - grpc_mdstr* max_response_message_bytes_key; + grpc_slice_hash_table *table; }; -grpc_method_config* grpc_method_config_create( - bool* wait_for_ready, gpr_timespec* timeout, - int32_t* max_request_message_bytes, int32_t* max_response_message_bytes) { - grpc_method_config* method_config = gpr_malloc(sizeof(grpc_method_config)); +grpc_method_config *grpc_method_config_create( + bool *wait_for_ready, gpr_timespec *timeout, + int32_t *max_request_message_bytes, int32_t *max_response_message_bytes) { + grpc_method_config *method_config = gpr_malloc(sizeof(grpc_method_config)); memset(method_config, 0, sizeof(grpc_method_config)); - method_config->wait_for_ready_key = - grpc_mdstr_from_string(GRPC_METHOD_CONFIG_WAIT_FOR_READY); - method_config->timeout_key = - grpc_mdstr_from_string(GRPC_METHOD_CONFIG_TIMEOUT); - method_config->max_request_message_bytes_key = - grpc_mdstr_from_string(GRPC_METHOD_CONFIG_MAX_REQUEST_MESSAGE_BYTES); - method_config->max_response_message_bytes_key = - grpc_mdstr_from_string(GRPC_METHOD_CONFIG_MAX_RESPONSE_MESSAGE_BYTES); - grpc_mdstr_hash_table_entry entries[4]; + grpc_slice_hash_table_entry entries[4]; size_t num_entries = 0; if (wait_for_ready != NULL) { - entries[num_entries].key = method_config->wait_for_ready_key; + entries[num_entries].key = GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY; entries[num_entries].value = wait_for_ready; entries[num_entries].vtable = &bool_vtable; ++num_entries; } if (timeout != NULL) { - entries[num_entries].key = method_config->timeout_key; + entries[num_entries].key = GRPC_MDSTR_GRPC_DOT_TIMEOUT; entries[num_entries].value = timeout; entries[num_entries].vtable = ×pec_vtable; ++num_entries; } if (max_request_message_bytes != NULL) { - entries[num_entries].key = method_config->max_request_message_bytes_key; + entries[num_entries].key = GRPC_MDSTR_GRPC_DOT_MAX_REQUEST_MESSAGE_BYTES; entries[num_entries].value = max_request_message_bytes; entries[num_entries].vtable = &int32_vtable; ++num_entries; } if (max_response_message_bytes != NULL) { - entries[num_entries].key = method_config->max_response_message_bytes_key; + entries[num_entries].key = GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES; entries[num_entries].value = max_response_message_bytes; entries[num_entries].vtable = &int32_vtable; ++num_entries; } - method_config->table = grpc_mdstr_hash_table_create(num_entries, entries); + method_config->table = grpc_slice_hash_table_create(num_entries, entries); return method_config; } -grpc_method_config* grpc_method_config_ref(grpc_method_config* method_config) { - grpc_mdstr_hash_table_ref(method_config->table); +grpc_method_config *grpc_method_config_ref(grpc_method_config *method_config) { + grpc_slice_hash_table_ref(method_config->table); return method_config; } -void grpc_method_config_unref(grpc_exec_ctx* exec_ctx, - grpc_method_config* method_config) { - if (grpc_mdstr_hash_table_unref(exec_ctx, method_config->table)) { - GRPC_MDSTR_UNREF(exec_ctx, method_config->wait_for_ready_key); - GRPC_MDSTR_UNREF(exec_ctx, method_config->timeout_key); - GRPC_MDSTR_UNREF(exec_ctx, method_config->max_request_message_bytes_key); - GRPC_MDSTR_UNREF(exec_ctx, method_config->max_response_message_bytes_key); +void grpc_method_config_unref(grpc_exec_ctx *exec_ctx, + grpc_method_config *method_config) { + if (grpc_slice_hash_table_unref(exec_ctx, method_config->table)) { gpr_free(method_config); } } -int grpc_method_config_cmp(const grpc_method_config* method_config1, - const grpc_method_config* method_config2) { - return grpc_mdstr_hash_table_cmp(method_config1->table, +int grpc_method_config_cmp(const grpc_method_config *method_config1, + const grpc_method_config *method_config2) { + return grpc_slice_hash_table_cmp(method_config1->table, method_config2->table); } -const bool* grpc_method_config_get_wait_for_ready( - const grpc_method_config* method_config) { - return grpc_mdstr_hash_table_get(method_config->table, - method_config->wait_for_ready_key); +const bool *grpc_method_config_get_wait_for_ready( + const grpc_method_config *method_config) { + return grpc_slice_hash_table_get(method_config->table, + GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY); } -const gpr_timespec* grpc_method_config_get_timeout( - const grpc_method_config* method_config) { - return grpc_mdstr_hash_table_get(method_config->table, - method_config->timeout_key); +const gpr_timespec *grpc_method_config_get_timeout( + const grpc_method_config *method_config) { + return grpc_slice_hash_table_get(method_config->table, + GRPC_MDSTR_GRPC_DOT_TIMEOUT); } -const int32_t* grpc_method_config_get_max_request_message_bytes( - const grpc_method_config* method_config) { - return grpc_mdstr_hash_table_get( - method_config->table, method_config->max_request_message_bytes_key); +const int32_t *grpc_method_config_get_max_request_message_bytes( + const grpc_method_config *method_config) { + return grpc_slice_hash_table_get( + method_config->table, GRPC_MDSTR_GRPC_DOT_MAX_REQUEST_MESSAGE_BYTES); } -const int32_t* grpc_method_config_get_max_response_message_bytes( - const grpc_method_config* method_config) { - return grpc_mdstr_hash_table_get( - method_config->table, method_config->max_response_message_bytes_key); +const int32_t *grpc_method_config_get_max_response_message_bytes( + const grpc_method_config *method_config) { + return grpc_slice_hash_table_get( + method_config->table, GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES); } // // grpc_method_config_table // -static void method_config_unref(grpc_exec_ctx* exec_ctx, void* valuep) { +static void method_config_unref(grpc_exec_ctx *exec_ctx, void *valuep) { grpc_method_config_unref(exec_ctx, valuep); } -static void* method_config_ref(void* valuep) { +static void *method_config_ref(void *valuep) { return grpc_method_config_ref(valuep); } -static int method_config_cmp(void* valuep1, void* valuep2) { +static int method_config_cmp(void *valuep1, void *valuep2) { return grpc_method_config_cmp(valuep1, valuep2); } -static const grpc_mdstr_hash_table_vtable method_config_table_vtable = { +static const grpc_slice_hash_table_vtable method_config_table_vtable = { method_config_unref, method_config_ref, method_config_cmp}; -grpc_method_config_table* grpc_method_config_table_create( - size_t num_entries, grpc_method_config_table_entry* entries) { - grpc_mdstr_hash_table_entry* hash_table_entries = - gpr_malloc(sizeof(grpc_mdstr_hash_table_entry) * num_entries); +grpc_method_config_table *grpc_method_config_table_create( + size_t num_entries, grpc_method_config_table_entry *entries) { + grpc_slice_hash_table_entry *hash_table_entries = + gpr_malloc(sizeof(grpc_slice_hash_table_entry) * num_entries); for (size_t i = 0; i < num_entries; ++i) { hash_table_entries[i].key = entries[i].method_name; hash_table_entries[i].value = entries[i].method_config; hash_table_entries[i].vtable = &method_config_table_vtable; } - grpc_method_config_table* method_config_table = - grpc_mdstr_hash_table_create(num_entries, hash_table_entries); + grpc_method_config_table *method_config_table = + grpc_slice_hash_table_create(num_entries, hash_table_entries); gpr_free(hash_table_entries); return method_config_table; } -grpc_method_config_table* grpc_method_config_table_ref( - grpc_method_config_table* table) { - return grpc_mdstr_hash_table_ref(table); +grpc_method_config_table *grpc_method_config_table_ref( + grpc_method_config_table *table) { + return grpc_slice_hash_table_ref(table); } -void grpc_method_config_table_unref(grpc_exec_ctx* exec_ctx, - grpc_method_config_table* table) { - grpc_mdstr_hash_table_unref(exec_ctx, table); +void grpc_method_config_table_unref(grpc_exec_ctx *exec_ctx, + grpc_method_config_table *table) { + grpc_slice_hash_table_unref(exec_ctx, table); } -int grpc_method_config_table_cmp(const grpc_method_config_table* table1, - const grpc_method_config_table* table2) { - return grpc_mdstr_hash_table_cmp(table1, table2); +int grpc_method_config_table_cmp(const grpc_method_config_table *table1, + const grpc_method_config_table *table2) { + return grpc_slice_hash_table_cmp(table1, table2); } -void* grpc_method_config_table_get(grpc_exec_ctx* exec_ctx, - const grpc_mdstr_hash_table* table, - const grpc_mdstr* path) { - void* value = grpc_mdstr_hash_table_get(table, path); +void *grpc_method_config_table_get(grpc_exec_ctx *exec_ctx, + const grpc_slice_hash_table *table, + const grpc_slice path) { + void *value = grpc_slice_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 (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); - char* buf = gpr_malloc(len + 2); // '*' and NUL - memcpy(buf, path_str, len); - buf[len] = '*'; - buf[len + 1] = '\0'; - grpc_mdstr* wildcard_path = grpc_mdstr_from_string(buf); - gpr_free(buf); - value = grpc_mdstr_hash_table_get(table, wildcard_path); - GRPC_MDSTR_UNREF(exec_ctx, wildcard_path); + int sep_pos = grpc_slice_rchr(path, '/') + 1; + grpc_slice search = grpc_slice_malloc((size_t)(sep_pos + 1)); + memcpy(GRPC_SLICE_START_PTR(search), GRPC_SLICE_START_PTR(path), + (size_t)sep_pos); + GRPC_SLICE_START_PTR(search)[sep_pos] = '*'; + value = grpc_slice_hash_table_get(table, search); + grpc_slice_unref_internal(exec_ctx, search); } return value; } -static void* copy_arg(void* p) { return grpc_method_config_table_ref(p); } +static void *copy_arg(void *p) { return grpc_method_config_table_ref(p); } -static void destroy_arg(grpc_exec_ctx* exec_ctx, void* p) { +static void destroy_arg(grpc_exec_ctx *exec_ctx, void *p) { grpc_method_config_table_unref(exec_ctx, p); } -static int cmp_arg(void* p1, void* p2) { +static int cmp_arg(void *p1, void *p2) { return grpc_method_config_table_cmp(p1, p2); } static grpc_arg_pointer_vtable arg_vtable = {copy_arg, destroy_arg, cmp_arg}; grpc_arg grpc_method_config_table_create_channel_arg( - grpc_method_config_table* table) { + grpc_method_config_table *table) { grpc_arg arg; arg.type = GRPC_ARG_POINTER; arg.key = GRPC_ARG_SERVICE_CONFIG; @@ -304,41 +278,41 @@ grpc_arg grpc_method_config_table_create_channel_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; + void *(*convert_value)(const grpc_method_config *method_config); + const grpc_slice_hash_table_vtable *vtable; size_t num_entries; - grpc_mdstr_hash_table_entry* entries; + grpc_slice_hash_table_entry *entries; } conversion_state; -// A function to be passed to grpc_mdstr_hash_table_iterate() to create +// A function to be passed to grpc_slice_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); +static void convert_entry(const grpc_slice_hash_table_entry *entry, + void *user_data) { + conversion_state *state = user_data; + state->entries[state->num_entries].key = grpc_slice_ref_internal(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( - grpc_exec_ctx* exec_ctx, const grpc_method_config_table* table, - void* (*convert_value)(const grpc_method_config* method_config), - const grpc_mdstr_hash_table_vtable* vtable) { +grpc_slice_hash_table *grpc_method_config_table_convert( + grpc_exec_ctx *exec_ctx, const grpc_method_config_table *table, + void *(*convert_value)(const grpc_method_config *method_config), + const grpc_slice_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); + state.entries = gpr_malloc(sizeof(grpc_slice_hash_table_entry) * + grpc_slice_hash_table_num_entries(table)); + grpc_slice_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); + grpc_slice_hash_table *new_table = + grpc_slice_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(exec_ctx, state.entries[i].key); + grpc_slice_unref_internal(exec_ctx, state.entries[i].key); vtable->destroy_value(exec_ctx, state.entries[i].value); } gpr_free(state.entries); diff --git a/src/core/lib/transport/method_config.h b/src/core/lib/transport/method_config.h index d17a493fd4..3e266a6ecd 100644 --- a/src/core/lib/transport/method_config.h +++ b/src/core/lib/transport/method_config.h @@ -37,7 +37,7 @@ #include <grpc/impl/codegen/gpr_types.h> #include <grpc/impl/codegen/grpc_types.h> -#include "src/core/lib/transport/mdstr_hash_table.h" +#include "src/core/lib/slice/slice_hash_table.h" #include "src/core/lib/transport/metadata.h" /// Per-method configuration. @@ -55,70 +55,70 @@ typedef struct grpc_method_config grpc_method_config; /// \a max_request_message_bytes and \a max_response_message_bytes /// indicate the maximum sizes of the request (checked when sending) and /// response (checked when receiving) messages. -grpc_method_config* grpc_method_config_create( - bool* wait_for_ready, gpr_timespec* timeout, - int32_t* max_request_message_bytes, int32_t* max_response_message_bytes); +grpc_method_config *grpc_method_config_create( + bool *wait_for_ready, gpr_timespec *timeout, + int32_t *max_request_message_bytes, int32_t *max_response_message_bytes); -grpc_method_config* grpc_method_config_ref(grpc_method_config* method_config); -void grpc_method_config_unref(grpc_exec_ctx* exec_ctx, - grpc_method_config* method_config); +grpc_method_config *grpc_method_config_ref(grpc_method_config *method_config); +void grpc_method_config_unref(grpc_exec_ctx *exec_ctx, + grpc_method_config *method_config); /// Compares two grpc_method_configs. /// The sort order is stable but undefined. -int grpc_method_config_cmp(const grpc_method_config* method_config1, - const grpc_method_config* method_config2); +int grpc_method_config_cmp(const grpc_method_config *method_config1, + const grpc_method_config *method_config2); /// These methods return NULL if the requested field is unset. /// The caller does NOT take ownership of the result. -const bool* grpc_method_config_get_wait_for_ready( - const grpc_method_config* method_config); -const gpr_timespec* grpc_method_config_get_timeout( - const grpc_method_config* method_config); -const int32_t* grpc_method_config_get_max_request_message_bytes( - const grpc_method_config* method_config); -const int32_t* grpc_method_config_get_max_response_message_bytes( - const grpc_method_config* method_config); +const bool *grpc_method_config_get_wait_for_ready( + const grpc_method_config *method_config); +const gpr_timespec *grpc_method_config_get_timeout( + const grpc_method_config *method_config); +const int32_t *grpc_method_config_get_max_request_message_bytes( + const grpc_method_config *method_config); +const int32_t *grpc_method_config_get_max_response_message_bytes( + const grpc_method_config *method_config); /// A table of method configs. -typedef grpc_mdstr_hash_table grpc_method_config_table; +typedef grpc_slice_hash_table grpc_method_config_table; typedef struct grpc_method_config_table_entry { /// The name is of one of the following forms: /// service/method -- specifies exact service and method name /// service/* -- matches all methods for the specified service - grpc_mdstr* method_name; - grpc_method_config* method_config; + grpc_slice method_name; + grpc_method_config *method_config; } grpc_method_config_table_entry; /// Takes new references to all keys and values in \a entries. -grpc_method_config_table* grpc_method_config_table_create( - size_t num_entries, grpc_method_config_table_entry* entries); +grpc_method_config_table *grpc_method_config_table_create( + size_t num_entries, grpc_method_config_table_entry *entries); -grpc_method_config_table* grpc_method_config_table_ref( - grpc_method_config_table* table); -void grpc_method_config_table_unref(grpc_exec_ctx* exec_ctx, - grpc_method_config_table* table); +grpc_method_config_table *grpc_method_config_table_ref( + grpc_method_config_table *table); +void grpc_method_config_table_unref(grpc_exec_ctx *exec_ctx, + grpc_method_config_table *table); /// Compares two grpc_method_config_tables. /// The sort order is stable but undefined. -int grpc_method_config_table_cmp(const grpc_method_config_table* table1, - const grpc_method_config_table* table2); +int grpc_method_config_table_cmp(const grpc_method_config_table *table1, + const grpc_method_config_table *table2); /// Gets the method config for the specified \a path, which should be of /// the form "/service/method". /// Returns NULL if the method has no config. /// Caller does NOT own a reference to the result. /// -/// Note: This returns a void* instead of a grpc_method_config* so that +/// 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(grpc_exec_ctx* exec_ctx, - const grpc_mdstr_hash_table* table, - const grpc_mdstr* path); +void *grpc_method_config_table_get(grpc_exec_ctx *exec_ctx, + const grpc_slice_hash_table *table, + const grpc_slice path); /// Returns a channel arg containing \a table. grpc_arg grpc_method_config_table_create_channel_arg( - grpc_method_config_table* table); + 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 @@ -131,9 +131,9 @@ grpc_arg grpc_method_config_table_create_channel_arg( /// will return a new instance of the struct containing the values from /// the grpc_method_config, and \a vtable provides the methods for /// operating on the struct type. -grpc_mdstr_hash_table* grpc_method_config_table_convert( - grpc_exec_ctx* exec_ctx, const grpc_method_config_table* table, - void* (*convert_value)(const grpc_method_config* method_config), - const grpc_mdstr_hash_table_vtable* vtable); +grpc_slice_hash_table *grpc_method_config_table_convert( + grpc_exec_ctx *exec_ctx, const grpc_method_config_table *table, + void *(*convert_value)(const grpc_method_config *method_config), + const grpc_slice_hash_table_vtable *vtable); #endif /* GRPC_CORE_LIB_TRANSPORT_METHOD_CONFIG_H */ diff --git a/src/core/lib/transport/static_metadata.c b/src/core/lib/transport/static_metadata.c index 8b22592b45..e24f3fa55e 100644 --- a/src/core/lib/transport/static_metadata.c +++ b/src/core/lib/transport/static_metadata.c @@ -41,7 +41,356 @@ #include "src/core/lib/transport/static_metadata.h" -grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT]; +static uint8_t g_raw_bytes[] = { + 48, 49, 50, 50, 48, 48, 50, 48, 52, 50, 48, 54, 51, 48, 52, + 52, 48, 48, 52, 48, 52, 53, 48, 48, 97, 99, 99, 101, 112, 116, + 97, 99, 99, 101, 112, 116, 45, 99, 104, 97, 114, 115, 101, 116, 97, + 99, 99, 101, 112, 116, 45, 101, 110, 99, 111, 100, 105, 110, 103, 97, + 99, 99, 101, 112, 116, 45, 108, 97, 110, 103, 117, 97, 103, 101, 97, + 99, 99, 101, 112, 116, 45, 114, 97, 110, 103, 101, 115, 97, 99, 99, + 101, 115, 115, 45, 99, 111, 110, 116, 114, 111, 108, 45, 97, 108, 108, + 111, 119, 45, 111, 114, 105, 103, 105, 110, 97, 103, 101, 97, 108, 108, + 111, 119, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 103, + 114, 112, 99, 58, 97, 117, 116, 104, 111, 114, 105, 116, 121, 97, 117, + 116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, 99, 97, 99, 104, + 101, 45, 99, 111, 110, 116, 114, 111, 108, 99, 111, 110, 116, 101, 110, + 116, 45, 100, 105, 115, 112, 111, 115, 105, 116, 105, 111, 110, 99, 111, + 110, 116, 101, 110, 116, 45, 101, 110, 99, 111, 100, 105, 110, 103, 99, + 111, 110, 116, 101, 110, 116, 45, 108, 97, 110, 103, 117, 97, 103, 101, + 99, 111, 110, 116, 101, 110, 116, 45, 108, 101, 110, 103, 116, 104, 99, + 111, 110, 116, 101, 110, 116, 45, 108, 111, 99, 97, 116, 105, 111, 110, + 99, 111, 110, 116, 101, 110, 116, 45, 114, 97, 110, 103, 101, 99, 111, + 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 99, 111, 111, 107, 105, + 101, 100, 97, 116, 101, 100, 101, 102, 108, 97, 116, 101, 100, 101, 102, + 108, 97, 116, 101, 44, 103, 122, 105, 112, 101, 116, 97, 103, 101, 120, + 112, 101, 99, 116, 101, 120, 112, 105, 114, 101, 115, 102, 114, 111, 109, + 71, 69, 84, 103, 114, 112, 99, 103, 114, 112, 99, 45, 97, 99, 99, + 101, 112, 116, 45, 101, 110, 99, 111, 100, 105, 110, 103, 103, 114, 112, + 99, 46, 109, 97, 120, 95, 114, 101, 113, 117, 101, 115, 116, 95, 109, + 101, 115, 115, 97, 103, 101, 95, 98, 121, 116, 101, 115, 103, 114, 112, + 99, 46, 109, 97, 120, 95, 114, 101, 115, 112, 111, 110, 115, 101, 95, + 109, 101, 115, 115, 97, 103, 101, 95, 98, 121, 116, 101, 115, 103, 114, + 112, 99, 46, 116, 105, 109, 101, 111, 117, 116, 103, 114, 112, 99, 46, + 119, 97, 105, 116, 95, 102, 111, 114, 95, 114, 101, 97, 100, 121, 103, + 114, 112, 99, 45, 101, 110, 99, 111, 100, 105, 110, 103, 103, 114, 112, + 99, 45, 105, 110, 116, 101, 114, 110, 97, 108, 45, 101, 110, 99, 111, + 100, 105, 110, 103, 45, 114, 101, 113, 117, 101, 115, 116, 103, 114, 112, + 99, 45, 109, 101, 115, 115, 97, 103, 101, 103, 114, 112, 99, 45, 112, + 97, 121, 108, 111, 97, 100, 45, 98, 105, 110, 103, 114, 112, 99, 45, + 115, 116, 97, 116, 115, 45, 98, 105, 110, 103, 114, 112, 99, 45, 115, + 116, 97, 116, 117, 115, 103, 114, 112, 99, 45, 116, 105, 109, 101, 111, + 117, 116, 103, 114, 112, 99, 45, 116, 114, 97, 99, 105, 110, 103, 45, + 98, 105, 110, 103, 122, 105, 112, 103, 122, 105, 112, 44, 32, 100, 101, + 102, 108, 97, 116, 101, 104, 111, 115, 116, 104, 116, 116, 112, 104, 116, + 116, 112, 115, 105, 100, 101, 110, 116, 105, 116, 121, 105, 100, 101, 110, + 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116, 101, 105, 100, 101, + 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116, 101, 44, 103, + 122, 105, 112, 105, 100, 101, 110, 116, 105, 116, 121, 44, 103, 122, 105, + 112, 105, 102, 45, 109, 97, 116, 99, 104, 105, 102, 45, 109, 111, 100, + 105, 102, 105, 101, 100, 45, 115, 105, 110, 99, 101, 105, 102, 45, 110, + 111, 110, 101, 45, 109, 97, 116, 99, 104, 105, 102, 45, 114, 97, 110, + 103, 101, 105, 102, 45, 117, 110, 109, 111, 100, 105, 102, 105, 101, 100, + 45, 115, 105, 110, 99, 101, 108, 97, 115, 116, 45, 109, 111, 100, 105, + 102, 105, 101, 100, 108, 98, 45, 99, 111, 115, 116, 45, 98, 105, 110, + 108, 98, 45, 116, 111, 107, 101, 110, 108, 105, 110, 107, 108, 111, 99, + 97, 116, 105, 111, 110, 109, 97, 120, 45, 102, 111, 114, 119, 97, 114, + 100, 115, 58, 109, 101, 116, 104, 111, 100, 58, 112, 97, 116, 104, 80, + 79, 83, 84, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 101, 110, + 116, 105, 99, 97, 116, 101, 112, 114, 111, 120, 121, 45, 97, 117, 116, + 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, 80, 85, 84, 114, 97, + 110, 103, 101, 114, 101, 102, 101, 114, 101, 114, 114, 101, 102, 114, 101, + 115, 104, 114, 101, 116, 114, 121, 45, 97, 102, 116, 101, 114, 58, 115, + 99, 104, 101, 109, 101, 115, 101, 114, 118, 101, 114, 115, 101, 116, 45, + 99, 111, 111, 107, 105, 101, 47, 47, 105, 110, 100, 101, 120, 46, 104, + 116, 109, 108, 58, 115, 116, 97, 116, 117, 115, 115, 116, 114, 105, 99, + 116, 45, 116, 114, 97, 110, 115, 112, 111, 114, 116, 45, 115, 101, 99, + 117, 114, 105, 116, 121, 116, 101, 116, 114, 97, 105, 108, 101, 114, 115, + 116, 114, 97, 110, 115, 102, 101, 114, 45, 101, 110, 99, 111, 100, 105, + 110, 103, 117, 115, 101, 114, 45, 97, 103, 101, 110, 116, 118, 97, 114, + 121, 118, 105, 97, 119, 119, 119, 45, 97, 117, 116, 104, 101, 110, 116, + 105, 99, 97, 116, 101}; + +static void static_ref(void *unused) {} +static void static_unref(grpc_exec_ctx *exec_ctx, void *unused) {} +static grpc_slice_refcount g_refcnt = {static_ref, static_unref}; + +bool grpc_is_static_metadata_string(grpc_slice slice) { + return slice.refcount != NULL && slice.refcount->ref == static_ref; +}; + +const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = { + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 0, .length = 1}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 1, .length = 1}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 2, .length = 1}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 3, .length = 3}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 6, .length = 3}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 9, .length = 3}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 12, .length = 3}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 15, .length = 3}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 18, .length = 3}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 21, .length = 3}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 24, .length = 6}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 30, .length = 14}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 44, .length = 15}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 59, .length = 15}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 74, .length = 13}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 87, .length = 27}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 114, .length = 3}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 117, .length = 5}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 122, .length = 16}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 138, .length = 10}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 148, .length = 13}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 161, .length = 13}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 174, .length = 19}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 193, .length = 16}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 209, .length = 16}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 225, .length = 14}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 239, .length = 16}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 255, .length = 13}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 268, .length = 12}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 280, .length = 6}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 286, .length = 4}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 290, .length = 7}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 297, .length = 12}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 0}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 309, .length = 4}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 313, .length = 6}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 319, .length = 7}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 326, .length = 4}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 330, .length = 3}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 333, .length = 4}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 337, .length = 20}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 357, .length = 30}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 387, .length = 31}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 418, .length = 12}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 430, .length = 19}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 449, .length = 13}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 462, .length = 30}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 492, .length = 12}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 504, .length = 16}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 520, .length = 14}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 534, .length = 11}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 545, .length = 12}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 557, .length = 16}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 573, .length = 4}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 577, .length = 13}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 590, .length = 4}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 594, .length = 4}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 598, .length = 5}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 603, .length = 8}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 611, .length = 16}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 627, .length = 21}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 648, .length = 13}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 661, .length = 8}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 669, .length = 17}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 686, .length = 13}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 699, .length = 8}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 707, .length = 19}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 726, .length = 13}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 739, .length = 11}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 750, .length = 8}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 758, .length = 4}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 762, .length = 8}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 770, .length = 12}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 782, .length = 7}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 789, .length = 5}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 794, .length = 4}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 798, .length = 18}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 816, .length = 19}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 835, .length = 3}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 838, .length = 5}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 843, .length = 7}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 850, .length = 7}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 857, .length = 11}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 868, .length = 7}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 875, .length = 6}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 881, .length = 10}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 891, .length = 1}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 892, .length = 11}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 903, .length = 7}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 910, .length = 25}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 935, .length = 2}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 937, .length = 8}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 945, .length = 17}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 962, .length = 10}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 972, .length = 4}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 976, .length = 3}}, + {.refcount = &g_refcnt, + .data.refcounted = {.bytes = g_raw_bytes + 979, .length = 16}}, +}; + +static const uint8_t g_revmap[] = { + 0, 1, 2, 3, 255, 255, 4, 255, 255, 5, 255, 255, 6, 255, 255, + 7, 255, 255, 8, 255, 255, 9, 255, 255, 10, 255, 255, 255, 255, 255, + 11, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 13, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 14, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 15, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 16, 255, 255, 17, 255, 255, + 255, 255, 18, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 19, 255, 255, 255, 255, 255, 255, 255, 255, 255, 20, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 21, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 22, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 23, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 24, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 25, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 26, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 27, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 28, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 29, 255, 255, 255, 255, + 255, 30, 255, 255, 255, 31, 255, 255, 255, 255, 255, 255, 32, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 34, 255, 255, 255, 35, 255, + 255, 255, 255, 255, 36, 255, 255, 255, 255, 255, 255, 37, 255, 255, 255, + 38, 255, 255, 39, 255, 255, 255, 40, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 41, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 42, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 43, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 44, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 45, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 46, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 47, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 48, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 49, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 50, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 52, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 53, 255, 255, 255, 54, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 55, 255, 255, 255, 56, 255, 255, 255, 57, 255, + 255, 255, 255, 58, 255, 255, 255, 255, 255, 255, 255, 59, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 60, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 61, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 62, 255, 255, 255, 255, 255, 255, 255, 63, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 64, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 65, 255, 255, 255, 255, 255, + 255, 255, 66, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 67, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 68, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 69, 255, 255, 255, 255, 255, 255, 255, 70, 255, 255, 255, 71, 255, 255, + 255, 255, 255, 255, 255, 72, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 73, 255, 255, 255, 255, 255, 255, 74, 255, 255, 255, 255, 75, + 255, 255, 255, 76, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 77, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 78, 255, 255, 79, 255, + 255, 255, 255, 80, 255, 255, 255, 255, 255, 255, 81, 255, 255, 255, 255, + 255, 255, 82, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 83, 255, + 255, 255, 255, 255, 255, 84, 255, 255, 255, 255, 255, 85, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 86, 87, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 88, 255, 255, 255, 255, 255, 255, 89, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 90, 255, 91, 255, 255, 255, 255, 255, 255, 255, + 92, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 93, 255, 255, 255, 255, 255, 255, 255, 255, 255, 94, 255, 255, + 255, 95, 255, 255, 96, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255}; + +int grpc_static_metadata_index(grpc_slice slice) { + if (GRPC_SLICE_LENGTH(slice) == 0) return 33; + size_t ofs = (size_t)(GRPC_SLICE_START_PTR(slice) - g_raw_bytes); + if (ofs > sizeof(g_revmap)) return -1; + uint8_t id = g_revmap[ofs]; + return id == 255 ? -1 : id; +}; grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { @@ -50,111 +399,65 @@ uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +#define ELEMS_PHASHLEN 0x40 +#define ELEMS_PHASHNKEYS 81 +#define ELEMS_PHASHRANGE 128 +#define ELEMS_PHASHSALT 0x9e3779b9 + +static const uint8_t elems_tab[] = { + 47, 1, 61, 0, 32, 0, 47, 1, 37, 0, 0, 0, 47, 61, 76, 0, + 76, 0, 61, 0, 32, 37, 51, 0, 47, 47, 79, 4, 76, 1, 0, 0, + 0, 76, 0, 47, 85, 34, 0, 10, 0, 28, 0, 76, 0, 61, 0, 0, + 46, 4, 12, 47, 88, 28, 61, 79, 28, 70, 0, 68, 85, 0, 87, 0, +}; + +static uint32_t elems_phash(uint32_t val) { + val -= 1003; + + uint32_t a, b, rsl; + + b = (val & 0x3f); + a = ((val << 18) >> 26); + rsl = (a ^ elems_tab[b]); + return rsl; +} + +static const uint16_t elem_keys[] = { + 1218, 8544, 2652, 1973, 7264, 2458, 2734, 3933, 1682, 6435, 3912, 3941, + 4396, 4418, 4850, 4852, 7890, 8541, 6726, 9345, 6338, 6629, 6920, 3939, + 7156, 8540, 8108, 8090, 8181, 8666, 8821, 1876, 8545, 1391, 8957, 1488, + 7405, 7265, 3331, 2943, 2846, 6241, 4851, 2167, 5368, 1585, 1294, 1003, + 9054, 6144, 8542, 8539, 8107, 7793, 7502, 7159, 7696, 2264, 6532, 2749, + 9248, 1197, 7987, 9151, 7017, 4423, 7119, 6823, 3938, 8543, 3525, 3911, + 2070, 2361, 2555, 6047, 1100, 3940, 3622, 3428, 8278, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; +static const uint8_t elem_idxs[] = { + 3, 72, 17, 10, 54, 15, 18, 28, 8, 44, 27, 32, 33, 34, 36, 38, 60, + 69, 47, 80, 43, 46, 49, 30, 52, 68, 64, 62, 65, 74, 75, 9, 73, 5, + 76, 6, 56, 55, 22, 21, 20, 42, 37, 12, 39, 7, 4, 1, 77, 41, 70, + 67, 63, 59, 57, 53, 58, 13, 45, 19, 79, 2, 61, 78, 50, 35, 51, 48, + 29, 71, 24, 26, 11, 14, 16, 40, 0, 31, 25, 23, 66}; + +grpc_mdelem *grpc_static_mdelem_for_static_strings(int a, int b) { + if (a == -1 || b == -1) return NULL; + uint32_t k = (uint32_t)(a * 97 + b); + uint32_t h = elems_phash(k); + return elem_keys[h] == k ? &grpc_static_mdelem_table[elem_idxs[h]] : NULL; +} + const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2] = - {11, 33, 10, 33, 12, 33, 12, 50, 13, 33, 14, 33, 15, 33, 16, 33, 17, 33, + {11, 33, 10, 33, 12, 33, 12, 54, 13, 33, 14, 33, 15, 33, 16, 33, 17, 33, 19, 33, 20, 33, 21, 33, 22, 33, 23, 33, 24, 33, 25, 33, 26, 33, 27, 33, 28, 18, 28, 33, 29, 33, 30, 33, 34, 33, 35, 33, 36, 33, 37, 33, 40, 31, - 40, 32, 40, 49, 40, 54, 40, 55, 40, 56, 40, 57, 41, 31, 41, 49, 41, 54, - 46, 0, 46, 1, 46, 2, 51, 33, 58, 33, 59, 33, 60, 33, 61, 33, 62, 33, - 63, 33, 64, 33, 65, 33, 66, 33, 67, 33, 68, 33, 69, 38, 69, 71, 69, 74, - 70, 82, 70, 83, 72, 33, 73, 33, 75, 33, 76, 33, 77, 33, 78, 33, 79, 39, - 79, 52, 79, 53, 80, 33, 81, 33, 84, 3, 84, 4, 84, 5, 84, 6, 84, 7, - 84, 8, 84, 9, 85, 33, 86, 87, 88, 33, 89, 33, 90, 33, 91, 33, 92, 33}; - -const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = { - "0", - "1", - "2", - "200", - "204", - "206", - "304", - "400", - "404", - "500", - "accept", - "accept-charset", - "accept-encoding", - "accept-language", - "accept-ranges", - "access-control-allow-origin", - "age", - "allow", - "application/grpc", - ":authority", - "authorization", - "cache-control", - "content-disposition", - "content-encoding", - "content-language", - "content-length", - "content-location", - "content-range", - "content-type", - "cookie", - "date", - "deflate", - "deflate,gzip", - "", - "etag", - "expect", - "expires", - "from", - "GET", - "grpc", - "grpc-accept-encoding", - "grpc-encoding", - "grpc-internal-encoding-request", - "grpc-message", - "grpc-payload-bin", - "grpc-stats-bin", - "grpc-status", - "grpc-timeout", - "grpc-tracing-bin", - "gzip", - "gzip, deflate", - "host", - "http", - "https", - "identity", - "identity,deflate", - "identity,deflate,gzip", - "identity,gzip", - "if-match", - "if-modified-since", - "if-none-match", - "if-range", - "if-unmodified-since", - "last-modified", - "lb-cost-bin", - "lb-token", - "link", - "location", - "max-forwards", - ":method", - ":path", - "POST", - "proxy-authenticate", - "proxy-authorization", - "PUT", - "range", - "referer", - "refresh", - "retry-after", - ":scheme", - "server", - "set-cookie", - "/", - "/index.html", - ":status", - "strict-transport-security", - "te", - "trailers", - "transfer-encoding", - "user-agent", - "vary", - "via", - "www-authenticate"}; + 40, 32, 40, 53, 40, 58, 40, 59, 40, 60, 40, 61, 45, 31, 45, 53, 45, 58, + 50, 0, 50, 1, 50, 2, 55, 33, 62, 33, 63, 33, 64, 33, 65, 33, 66, 33, + 67, 33, 68, 33, 69, 33, 70, 33, 71, 33, 72, 33, 73, 38, 73, 75, 73, 78, + 74, 86, 74, 87, 76, 33, 77, 33, 79, 33, 80, 33, 81, 33, 82, 33, 83, 39, + 83, 56, 83, 57, 84, 33, 85, 33, 88, 3, 88, 4, 88, 5, 88, 6, 88, 7, + 88, 8, 88, 9, 89, 33, 90, 91, 92, 33, 93, 33, 94, 33, 95, 33, 96, 33}; const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 29, 26, 30, 28, 32, 27, 31}; diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 28ad6f2961..c6348a5280 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -44,195 +44,207 @@ #include "src/core/lib/transport/metadata.h" -#define GRPC_STATIC_MDSTR_COUNT 93 -extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT]; +#define GRPC_STATIC_MDSTR_COUNT 97 +extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* "0" */ -#define GRPC_MDSTR_0 (&grpc_static_mdstr_table[0]) +#define GRPC_MDSTR_0 (grpc_static_slice_table[0]) /* "1" */ -#define GRPC_MDSTR_1 (&grpc_static_mdstr_table[1]) +#define GRPC_MDSTR_1 (grpc_static_slice_table[1]) /* "2" */ -#define GRPC_MDSTR_2 (&grpc_static_mdstr_table[2]) +#define GRPC_MDSTR_2 (grpc_static_slice_table[2]) /* "200" */ -#define GRPC_MDSTR_200 (&grpc_static_mdstr_table[3]) +#define GRPC_MDSTR_200 (grpc_static_slice_table[3]) /* "204" */ -#define GRPC_MDSTR_204 (&grpc_static_mdstr_table[4]) +#define GRPC_MDSTR_204 (grpc_static_slice_table[4]) /* "206" */ -#define GRPC_MDSTR_206 (&grpc_static_mdstr_table[5]) +#define GRPC_MDSTR_206 (grpc_static_slice_table[5]) /* "304" */ -#define GRPC_MDSTR_304 (&grpc_static_mdstr_table[6]) +#define GRPC_MDSTR_304 (grpc_static_slice_table[6]) /* "400" */ -#define GRPC_MDSTR_400 (&grpc_static_mdstr_table[7]) +#define GRPC_MDSTR_400 (grpc_static_slice_table[7]) /* "404" */ -#define GRPC_MDSTR_404 (&grpc_static_mdstr_table[8]) +#define GRPC_MDSTR_404 (grpc_static_slice_table[8]) /* "500" */ -#define GRPC_MDSTR_500 (&grpc_static_mdstr_table[9]) +#define GRPC_MDSTR_500 (grpc_static_slice_table[9]) /* "accept" */ -#define GRPC_MDSTR_ACCEPT (&grpc_static_mdstr_table[10]) +#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[10]) /* "accept-charset" */ -#define GRPC_MDSTR_ACCEPT_CHARSET (&grpc_static_mdstr_table[11]) +#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[11]) /* "accept-encoding" */ -#define GRPC_MDSTR_ACCEPT_ENCODING (&grpc_static_mdstr_table[12]) +#define GRPC_MDSTR_ACCEPT_ENCODING (grpc_static_slice_table[12]) /* "accept-language" */ -#define GRPC_MDSTR_ACCEPT_LANGUAGE (&grpc_static_mdstr_table[13]) +#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[13]) /* "accept-ranges" */ -#define GRPC_MDSTR_ACCEPT_RANGES (&grpc_static_mdstr_table[14]) +#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[14]) /* "access-control-allow-origin" */ -#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (&grpc_static_mdstr_table[15]) +#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[15]) /* "age" */ -#define GRPC_MDSTR_AGE (&grpc_static_mdstr_table[16]) +#define GRPC_MDSTR_AGE (grpc_static_slice_table[16]) /* "allow" */ -#define GRPC_MDSTR_ALLOW (&grpc_static_mdstr_table[17]) +#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[17]) /* "application/grpc" */ -#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (&grpc_static_mdstr_table[18]) +#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[18]) /* ":authority" */ -#define GRPC_MDSTR_AUTHORITY (&grpc_static_mdstr_table[19]) +#define GRPC_MDSTR_AUTHORITY (grpc_static_slice_table[19]) /* "authorization" */ -#define GRPC_MDSTR_AUTHORIZATION (&grpc_static_mdstr_table[20]) +#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[20]) /* "cache-control" */ -#define GRPC_MDSTR_CACHE_CONTROL (&grpc_static_mdstr_table[21]) +#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[21]) /* "content-disposition" */ -#define GRPC_MDSTR_CONTENT_DISPOSITION (&grpc_static_mdstr_table[22]) +#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[22]) /* "content-encoding" */ -#define GRPC_MDSTR_CONTENT_ENCODING (&grpc_static_mdstr_table[23]) +#define GRPC_MDSTR_CONTENT_ENCODING (grpc_static_slice_table[23]) /* "content-language" */ -#define GRPC_MDSTR_CONTENT_LANGUAGE (&grpc_static_mdstr_table[24]) +#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[24]) /* "content-length" */ -#define GRPC_MDSTR_CONTENT_LENGTH (&grpc_static_mdstr_table[25]) +#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[25]) /* "content-location" */ -#define GRPC_MDSTR_CONTENT_LOCATION (&grpc_static_mdstr_table[26]) +#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[26]) /* "content-range" */ -#define GRPC_MDSTR_CONTENT_RANGE (&grpc_static_mdstr_table[27]) +#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[27]) /* "content-type" */ -#define GRPC_MDSTR_CONTENT_TYPE (&grpc_static_mdstr_table[28]) +#define GRPC_MDSTR_CONTENT_TYPE (grpc_static_slice_table[28]) /* "cookie" */ -#define GRPC_MDSTR_COOKIE (&grpc_static_mdstr_table[29]) +#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[29]) /* "date" */ -#define GRPC_MDSTR_DATE (&grpc_static_mdstr_table[30]) +#define GRPC_MDSTR_DATE (grpc_static_slice_table[30]) /* "deflate" */ -#define GRPC_MDSTR_DEFLATE (&grpc_static_mdstr_table[31]) +#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[31]) /* "deflate,gzip" */ -#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (&grpc_static_mdstr_table[32]) +#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[32]) /* "" */ -#define GRPC_MDSTR_EMPTY (&grpc_static_mdstr_table[33]) +#define GRPC_MDSTR_EMPTY (grpc_static_slice_table[33]) /* "etag" */ -#define GRPC_MDSTR_ETAG (&grpc_static_mdstr_table[34]) +#define GRPC_MDSTR_ETAG (grpc_static_slice_table[34]) /* "expect" */ -#define GRPC_MDSTR_EXPECT (&grpc_static_mdstr_table[35]) +#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[35]) /* "expires" */ -#define GRPC_MDSTR_EXPIRES (&grpc_static_mdstr_table[36]) +#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[36]) /* "from" */ -#define GRPC_MDSTR_FROM (&grpc_static_mdstr_table[37]) +#define GRPC_MDSTR_FROM (grpc_static_slice_table[37]) /* "GET" */ -#define GRPC_MDSTR_GET (&grpc_static_mdstr_table[38]) +#define GRPC_MDSTR_GET (grpc_static_slice_table[38]) /* "grpc" */ -#define GRPC_MDSTR_GRPC (&grpc_static_mdstr_table[39]) +#define GRPC_MDSTR_GRPC (grpc_static_slice_table[39]) /* "grpc-accept-encoding" */ -#define GRPC_MDSTR_GRPC_ACCEPT_ENCODING (&grpc_static_mdstr_table[40]) +#define GRPC_MDSTR_GRPC_ACCEPT_ENCODING (grpc_static_slice_table[40]) +/* "grpc.max_request_message_bytes" */ +#define GRPC_MDSTR_GRPC_DOT_MAX_REQUEST_MESSAGE_BYTES \ + (grpc_static_slice_table[41]) +/* "grpc.max_response_message_bytes" */ +#define GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES \ + (grpc_static_slice_table[42]) +/* "grpc.timeout" */ +#define GRPC_MDSTR_GRPC_DOT_TIMEOUT (grpc_static_slice_table[43]) +/* "grpc.wait_for_ready" */ +#define GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY (grpc_static_slice_table[44]) /* "grpc-encoding" */ -#define GRPC_MDSTR_GRPC_ENCODING (&grpc_static_mdstr_table[41]) +#define GRPC_MDSTR_GRPC_ENCODING (grpc_static_slice_table[45]) /* "grpc-internal-encoding-request" */ -#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (&grpc_static_mdstr_table[42]) +#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (grpc_static_slice_table[46]) /* "grpc-message" */ -#define GRPC_MDSTR_GRPC_MESSAGE (&grpc_static_mdstr_table[43]) +#define GRPC_MDSTR_GRPC_MESSAGE (grpc_static_slice_table[47]) /* "grpc-payload-bin" */ -#define GRPC_MDSTR_GRPC_PAYLOAD_BIN (&grpc_static_mdstr_table[44]) +#define GRPC_MDSTR_GRPC_PAYLOAD_BIN (grpc_static_slice_table[48]) /* "grpc-stats-bin" */ -#define GRPC_MDSTR_GRPC_STATS_BIN (&grpc_static_mdstr_table[45]) +#define GRPC_MDSTR_GRPC_STATS_BIN (grpc_static_slice_table[49]) /* "grpc-status" */ -#define GRPC_MDSTR_GRPC_STATUS (&grpc_static_mdstr_table[46]) +#define GRPC_MDSTR_GRPC_STATUS (grpc_static_slice_table[50]) /* "grpc-timeout" */ -#define GRPC_MDSTR_GRPC_TIMEOUT (&grpc_static_mdstr_table[47]) +#define GRPC_MDSTR_GRPC_TIMEOUT (grpc_static_slice_table[51]) /* "grpc-tracing-bin" */ -#define GRPC_MDSTR_GRPC_TRACING_BIN (&grpc_static_mdstr_table[48]) +#define GRPC_MDSTR_GRPC_TRACING_BIN (grpc_static_slice_table[52]) /* "gzip" */ -#define GRPC_MDSTR_GZIP (&grpc_static_mdstr_table[49]) +#define GRPC_MDSTR_GZIP (grpc_static_slice_table[53]) /* "gzip, deflate" */ -#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (&grpc_static_mdstr_table[50]) +#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[54]) /* "host" */ -#define GRPC_MDSTR_HOST (&grpc_static_mdstr_table[51]) +#define GRPC_MDSTR_HOST (grpc_static_slice_table[55]) /* "http" */ -#define GRPC_MDSTR_HTTP (&grpc_static_mdstr_table[52]) +#define GRPC_MDSTR_HTTP (grpc_static_slice_table[56]) /* "https" */ -#define GRPC_MDSTR_HTTPS (&grpc_static_mdstr_table[53]) +#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[57]) /* "identity" */ -#define GRPC_MDSTR_IDENTITY (&grpc_static_mdstr_table[54]) +#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[58]) /* "identity,deflate" */ -#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (&grpc_static_mdstr_table[55]) +#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[59]) /* "identity,deflate,gzip" */ #define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ - (&grpc_static_mdstr_table[56]) + (grpc_static_slice_table[60]) /* "identity,gzip" */ -#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (&grpc_static_mdstr_table[57]) +#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[61]) /* "if-match" */ -#define GRPC_MDSTR_IF_MATCH (&grpc_static_mdstr_table[58]) +#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[62]) /* "if-modified-since" */ -#define GRPC_MDSTR_IF_MODIFIED_SINCE (&grpc_static_mdstr_table[59]) +#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[63]) /* "if-none-match" */ -#define GRPC_MDSTR_IF_NONE_MATCH (&grpc_static_mdstr_table[60]) +#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[64]) /* "if-range" */ -#define GRPC_MDSTR_IF_RANGE (&grpc_static_mdstr_table[61]) +#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[65]) /* "if-unmodified-since" */ -#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (&grpc_static_mdstr_table[62]) +#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[66]) /* "last-modified" */ -#define GRPC_MDSTR_LAST_MODIFIED (&grpc_static_mdstr_table[63]) +#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[67]) /* "lb-cost-bin" */ -#define GRPC_MDSTR_LB_COST_BIN (&grpc_static_mdstr_table[64]) +#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[68]) /* "lb-token" */ -#define GRPC_MDSTR_LB_TOKEN (&grpc_static_mdstr_table[65]) +#define GRPC_MDSTR_LB_TOKEN (grpc_static_slice_table[69]) /* "link" */ -#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[66]) +#define GRPC_MDSTR_LINK (grpc_static_slice_table[70]) /* "location" */ -#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[67]) +#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[71]) /* "max-forwards" */ -#define GRPC_MDSTR_MAX_FORWARDS (&grpc_static_mdstr_table[68]) +#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[72]) /* ":method" */ -#define GRPC_MDSTR_METHOD (&grpc_static_mdstr_table[69]) +#define GRPC_MDSTR_METHOD (grpc_static_slice_table[73]) /* ":path" */ -#define GRPC_MDSTR_PATH (&grpc_static_mdstr_table[70]) +#define GRPC_MDSTR_PATH (grpc_static_slice_table[74]) /* "POST" */ -#define GRPC_MDSTR_POST (&grpc_static_mdstr_table[71]) +#define GRPC_MDSTR_POST (grpc_static_slice_table[75]) /* "proxy-authenticate" */ -#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[72]) +#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[76]) /* "proxy-authorization" */ -#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[73]) +#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[77]) /* "PUT" */ -#define GRPC_MDSTR_PUT (&grpc_static_mdstr_table[74]) +#define GRPC_MDSTR_PUT (grpc_static_slice_table[78]) /* "range" */ -#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[75]) +#define GRPC_MDSTR_RANGE (grpc_static_slice_table[79]) /* "referer" */ -#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[76]) +#define GRPC_MDSTR_REFERER (grpc_static_slice_table[80]) /* "refresh" */ -#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[77]) +#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[81]) /* "retry-after" */ -#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[78]) +#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[82]) /* ":scheme" */ -#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[79]) +#define GRPC_MDSTR_SCHEME (grpc_static_slice_table[83]) /* "server" */ -#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[80]) +#define GRPC_MDSTR_SERVER (grpc_static_slice_table[84]) /* "set-cookie" */ -#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[81]) +#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[85]) /* "/" */ -#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[82]) +#define GRPC_MDSTR_SLASH (grpc_static_slice_table[86]) /* "/index.html" */ -#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[83]) +#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[87]) /* ":status" */ -#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[84]) +#define GRPC_MDSTR_STATUS (grpc_static_slice_table[88]) /* "strict-transport-security" */ -#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[85]) +#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[89]) /* "te" */ -#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[86]) +#define GRPC_MDSTR_TE (grpc_static_slice_table[90]) /* "trailers" */ -#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[87]) +#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[91]) /* "transfer-encoding" */ -#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[88]) +#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[92]) /* "user-agent" */ -#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[89]) +#define GRPC_MDSTR_USER_AGENT (grpc_static_slice_table[93]) /* "vary" */ -#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[90]) +#define GRPC_MDSTR_VARY (grpc_static_slice_table[94]) /* "via" */ -#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[91]) +#define GRPC_MDSTR_VIA (grpc_static_slice_table[95]) /* "www-authenticate" */ -#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[92]) +#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[96]) + +bool grpc_is_static_metadata_string(grpc_slice slice); #define GRPC_STATIC_MDELEM_COUNT 81 extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; @@ -409,9 +421,9 @@ extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT]; /* "www-authenticate": "" */ #define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[80]) +grpc_mdelem *grpc_static_mdelem_for_static_strings(int a, int b); extern const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2]; -extern const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT]; extern const uint8_t grpc_static_accept_encoding_metadata[8]; #define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) \ (&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]]) diff --git a/src/core/lib/transport/transport_op_string.c b/src/core/lib/transport/transport_op_string.c index 58d6ad508e..deb155e659 100644 --- a/src/core/lib/transport/transport_op_string.c +++ b/src/core/lib/transport/transport_op_string.c @@ -49,12 +49,10 @@ static void put_metadata(gpr_strvec *b, grpc_mdelem *md) { gpr_strvec_add(b, gpr_strdup("key=")); - gpr_strvec_add( - b, grpc_dump_slice(md->key->slice, GPR_DUMP_HEX | GPR_DUMP_ASCII)); + gpr_strvec_add(b, grpc_dump_slice(md->key, GPR_DUMP_HEX | GPR_DUMP_ASCII)); gpr_strvec_add(b, gpr_strdup(" value=")); - gpr_strvec_add( - b, grpc_dump_slice(md->value->slice, GPR_DUMP_HEX | GPR_DUMP_ASCII)); + gpr_strvec_add(b, grpc_dump_slice(md->value, GPR_DUMP_HEX | GPR_DUMP_ASCII)); } static void put_metadata_list(gpr_strvec *b, grpc_metadata_batch md) { |