diff options
author | yang-g <yangg@google.com> | 2016-03-30 14:58:53 -0700 |
---|---|---|
committer | yang-g <yangg@google.com> | 2016-03-30 14:58:53 -0700 |
commit | cb7a80266b4fb867481807dc439d3c002f74d466 (patch) | |
tree | 33f11445bae0bb5a46e1b34fcd7d8779cd16a002 /src/core | |
parent | 503c3caf0804c7b9e2619f7c58de6b2b415a8fb0 (diff) |
Use base64 encoded length for decoder table size
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/ext/transport/chttp2/transport/hpack_encoder.c | 7 | ||||
-rw-r--r-- | src/core/lib/transport/metadata.c | 29 | ||||
-rw-r--r-- | src/core/lib/transport/metadata.h | 2 |
3 files changed, 34 insertions, 4 deletions
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c index 819addd9e3..ef89f1ce19 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.c +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.c @@ -49,6 +49,7 @@ #include "src/core/ext/transport/chttp2/transport/hpack_table.h" #include "src/core/ext/transport/chttp2/transport/timeout_encoding.h" #include "src/core/ext/transport/chttp2/transport/varint.h" +#include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/static_metadata.h" #define HASH_FRAGMENT_1(x) ((x)&255) @@ -178,8 +179,7 @@ static void add_elem(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 new_index = c->tail_remote_index + c->table_elems + 1; - size_t elem_size = 32 + GPR_SLICE_LENGTH(elem->key->slice) + - GPR_SLICE_LENGTH(elem->value->slice); + size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem); GPR_ASSERT(elem_size < 65536); @@ -395,8 +395,7 @@ static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem, } /* should this elem be in the table? */ - decoder_space_usage = 32 + GPR_SLICE_LENGTH(elem->key->slice) + - GPR_SLICE_LENGTH(elem->value->slice); + decoder_space_usage = grpc_mdelem_get_size_in_hpack_table(elem); should_add_elem = decoder_space_usage < MAX_DECODER_SPACE_USAGE && c->filter_elems[HASH_FRAGMENT_1(elem_hash)] >= c->filter_elems_sum / ONE_ON_ADD_PROBABILITY; diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c index 451c8d1cd3..b1005f317a 100644 --- a/src/core/lib/transport/metadata.c +++ b/src/core/lib/transport/metadata.c @@ -38,6 +38,7 @@ #include <string.h> #include <grpc/compression.h> +#include <grpc/grpc.h> #include <grpc/support/alloc.h> #include <grpc/support/atm.h> #include <grpc/support/log.h> @@ -93,6 +94,9 @@ typedef struct internal_string { gpr_slice base64_and_huffman; + uint8_t has_size_in_decoder_table; + size_t size_in_decoder_table; + struct internal_string *bucket_next; } internal_string; @@ -407,6 +411,8 @@ grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *buf, size_t length) { } s->has_base64_and_huffman_encoded = 0; s->hash = hash; + s->has_size_in_decoder_table = 0; + s->size_in_decoder_table = 0; s->bucket_next = shard->strs[idx]; shard->strs[idx] = s; @@ -576,6 +582,29 @@ grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key, grpc_mdstr_from_string(key), grpc_mdstr_from_buffer(value, value_length)); } +size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem *elem) { + size_t overhead_and_key = 32 + GPR_SLICE_LENGTH(elem->key->slice); + if (is_mdstr_static(elem->value)) { + return overhead_and_key + GPR_SLICE_LENGTH(elem->value->slice); + } else { + internal_string *is = (internal_string *)elem->value; + size_t value_len = GPR_SLICE_LENGTH(is->slice); + static const uint8_t tail_xtra[3] = {0, 2, 3}; + if (is->has_size_in_decoder_table == 0) { + is->has_size_in_decoder_table = 1; + if (grpc_is_binary_header( + (const char *)GPR_SLICE_START_PTR(elem->key->slice), + GPR_SLICE_LENGTH(elem->key->slice))) { + is->size_in_decoder_table = + value_len / 3 * 4 + tail_xtra[value_len % 3]; + } else { + is->size_in_decoder_table = value_len; + } + } + return overhead_and_key + is->size_in_decoder_table; + } +} + grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *gmd DEBUG_ARGS) { internal_metadata *md = (internal_metadata *)gmd; if (is_mdelem_static(gmd)) return gmd; diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index d72ec9accc..9705a7f25e 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -110,6 +110,8 @@ grpc_mdelem *grpc_mdelem_from_string_and_buffer(const char *key, const uint8_t *value, size_t value_length); +size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem *elem); + /* Mutator and accessor for grpc_mdelem user data. The destructor function is used as a type tag and is checked during user_data fetch. */ void *grpc_mdelem_get_user_data(grpc_mdelem *md, |