aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2016-11-18 17:40:32 -0800
committerGravatar Craig Tiller <ctiller@google.com>2016-11-18 17:40:32 -0800
commitcf1c821ae6565c7ab1c1cf8b34660c4f69949171 (patch)
tree16aac6c6bdf59da632229636729d5792ea9bbbe7
parent480e1d8d9fcf2165f09412318f75dd3f6e01fb96 (diff)
Start getting interning into hpack parser/encoder
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_encoder.c37
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_parser.c45
2 files changed, 58 insertions, 24 deletions
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c
index 8e2264a602..7f7dfa5b55 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.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? */
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c
index 91bedcf7f0..a1ff528d72 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c
@@ -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,10 +838,11 @@ 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)),
- 1);
+ 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,10 +908,11 @@ 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)),
- 0);
+ 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,10 +978,11 @@ 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)),
- 0);
+ 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);
}