Use base64 encoded length for decoder table size

pull/6029/head
yang-g 9 years ago
parent 503c3caf08
commit cb7a80266b
  1. 7
      src/core/ext/transport/chttp2/transport/hpack_encoder.c
  2. 29
      src/core/lib/transport/metadata.c
  3. 2
      src/core/lib/transport/metadata.h

@ -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;

@ -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;

@ -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,

Loading…
Cancel
Save