Start getting interning into hpack parser/encoder

reviewable/pr8842/r1
Craig Tiller 8 years ago
parent 480e1d8d9f
commit cf1c821ae6
  1. 37
      src/core/ext/transport/chttp2/transport/hpack_encoder.c
  2. 39
      src/core/ext/transport/chttp2/transport/hpack_parser.c

@ -187,9 +187,23 @@ static void evict_entry(grpc_chttp2_hpack_compressor *c) {
c->table_elems--;
}
static bool is_interned(grpc_mdelem elem) {
switch (GRPC_MDELEM_STORAGE(elem)) {
case GRPC_MDELEM_STORAGE_ALLOCATED:
case GRPC_MDELEM_STORAGE_EXTERNAL:
return false;
case GRPC_MDELEM_STORAGE_INTERNED:
case GRPC_MDELEM_STORAGE_STATIC:
return true;
}
GPR_UNREACHABLE_CODE(return false);
}
/* add an element to the decoder table */
static void add_elem(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
grpc_mdelem elem) {
GPR_ASSERT(is_interned(elem));
uint32_t key_hash = grpc_slice_hash(GRPC_MDKEY(elem));
uint32_t value_hash = grpc_slice_hash(GRPC_MDVALUE(elem));
uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, value_hash);
@ -384,13 +398,6 @@ 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 = grpc_slice_hash(GRPC_MDKEY(elem));
uint32_t value_hash = grpc_slice_hash(GRPC_MDVALUE(elem));
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(GRPC_MDKEY(elem)) > 0);
if (GRPC_SLICE_START_PTR(GRPC_MDKEY(elem))[0] != ':') { /* regular header */
st->seen_regular_header = 1;
@ -400,6 +407,22 @@ static void hpack_enc(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
"Reserved header (colon-prefixed) happening after regular ones.");
}
if (!is_interned(elem)) {
emit_lithdr_noidx_v(c, elem, st);
return;
}
uint32_t key_hash;
uint32_t value_hash;
uint32_t elem_hash;
size_t decoder_space_usage;
uint32_t indices_key;
int should_add_elem;
key_hash = grpc_slice_hash(GRPC_MDKEY(elem));
value_hash = grpc_slice_hash(GRPC_MDVALUE(elem));
elem_hash = GRPC_MDSTR_KV_HASH(key_hash, value_hash);
inc_filter(HASH_FRAGMENT_1(elem_hash), &c->filter_elems_sum, c->filter_elems);
/* is this elem currently in the decoders table? */

@ -671,6 +671,8 @@ static const uint8_t inverse_base64[256] = {
static grpc_error *on_hdr(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_parser *p,
grpc_mdelem md, int add_to_table) {
if (add_to_table) {
GPR_ASSERT(GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_INTERNED ||
GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC);
grpc_error *err = grpc_chttp2_hptbl_add(exec_ctx, &p->table, md);
if (err != GRPC_ERROR_NONE) return err;
}
@ -683,8 +685,14 @@ static grpc_error *on_hdr(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_parser *p,
}
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);
grpc_chttp2_hpack_parser_string *str,
bool intern) {
grpc_slice s;
if (intern) {
s = grpc_slice_intern(grpc_slice_from_static_buffer(str->str, str->length));
} else {
s = grpc_slice_from_copied_buffer(str->str, str->length);
}
str->length = 0;
return s;
}
@ -819,7 +827,7 @@ static grpc_error *finish_lithdr_incidx(grpc_exec_ctx *exec_ctx,
grpc_error *err = on_hdr(
exec_ctx, p,
grpc_mdelem_from_slices(exec_ctx, grpc_slice_ref_internal(GRPC_MDKEY(md)),
take_string(p, &p->value)),
take_string(p, &p->value, true)),
1);
if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
return parse_begin(exec_ctx, p, cur, end);
@ -830,9 +838,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_slices(exec_ctx, take_string(p, &p->key),
take_string(p, &p->value)),
grpc_error *err =
on_hdr(exec_ctx, p,
grpc_mdelem_from_slices(exec_ctx, take_string(p, &p->key, true),
take_string(p, &p->value, true)),
1);
if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
return parse_begin(exec_ctx, p, cur, end);
@ -888,7 +897,7 @@ static grpc_error *finish_lithdr_notidx(grpc_exec_ctx *exec_ctx,
grpc_error *err = on_hdr(
exec_ctx, p,
grpc_mdelem_from_slices(exec_ctx, grpc_slice_ref_internal(GRPC_MDKEY(md)),
take_string(p, &p->value)),
take_string(p, &p->value, false)),
0);
if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
return parse_begin(exec_ctx, p, cur, end);
@ -899,9 +908,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_slices(exec_ctx, take_string(p, &p->key),
take_string(p, &p->value)),
grpc_error *err =
on_hdr(exec_ctx, p,
grpc_mdelem_from_slices(exec_ctx, take_string(p, &p->key, false),
take_string(p, &p->value, false)),
0);
if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
return parse_begin(exec_ctx, p, cur, end);
@ -957,7 +967,7 @@ static grpc_error *finish_lithdr_nvridx(grpc_exec_ctx *exec_ctx,
grpc_error *err = on_hdr(
exec_ctx, p,
grpc_mdelem_from_slices(exec_ctx, grpc_slice_ref_internal(GRPC_MDKEY(md)),
take_string(p, &p->value)),
take_string(p, &p->value, false)),
0);
if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
return parse_begin(exec_ctx, p, cur, end);
@ -968,9 +978,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_slices(exec_ctx, take_string(p, &p->key),
take_string(p, &p->value)),
grpc_error *err =
on_hdr(exec_ctx, p,
grpc_mdelem_from_slices(exec_ctx, take_string(p, &p->key, false),
take_string(p, &p->value, false)),
0);
if (err != GRPC_ERROR_NONE) return parse_error(exec_ctx, p, cur, end, err);
return parse_begin(exec_ctx, p, cur, end);

Loading…
Cancel
Save