Don't copy static header and put static table in front of dynamic table

This commit is contained in:
Tatsuhiro Tsujikawa 2014-07-16 23:04:00 +09:00
parent 38bfbffb1b
commit 744ec4dba1
3 changed files with 47 additions and 71 deletions

View File

@ -100,7 +100,7 @@ static nghttp2_hd_entry static_table[] = {
MAKE_ENT("www-authenticate", "", 4051929931u, 0u), MAKE_ENT("www-authenticate", "", 4051929931u, 0u),
}; };
static const size_t STATIC_TABLE_LENGTH = const size_t NGHTTP2_STATIC_TABLE_LENGTH =
sizeof(static_table)/sizeof(static_table[0]); sizeof(static_table)/sizeof(static_table[0]);
static int memeq(const void *s1, const void *s2, size_t n) static int memeq(const void *s1, const void *s2, size_t n)
@ -860,15 +860,33 @@ static search_result search_hd_table(nghttp2_hd_context *context,
uint32_t value_hash = hash(nv->value, nv->valuelen); uint32_t value_hash = hash(nv->value, nv->valuelen);
int use_index = (nv->flags & NGHTTP2_NV_FLAG_NO_INDEX) == 0; int use_index = (nv->flags & NGHTTP2_NV_FLAG_NO_INDEX) == 0;
for(i = 0; i < NGHTTP2_STATIC_TABLE_LENGTH; ++i) {
nghttp2_hd_entry *ent = &static_table[i];
if(ent->name_hash != name_hash || !name_eq(&ent->nv, nv)) {
continue;
}
if(res.index == -1) {
res.index = (ssize_t)i;
}
if(use_index &&
ent->value_hash == value_hash && value_eq(&ent->nv, nv)) {
res.index = (ssize_t)i;
res.name_value_match = 1;
return res;
}
}
if(use_index) { if(use_index) {
for(i = 0; i < context->hd_table.len; ++i) { for(i = 0; i < context->hd_table.len; ++i) {
nghttp2_hd_entry *ent = hd_ringbuf_get(&context->hd_table, i); nghttp2_hd_entry *ent = hd_ringbuf_get(&context->hd_table, i);
if(ent->name_hash == name_hash && name_eq(&ent->nv, nv)) { if(ent->name_hash == name_hash && name_eq(&ent->nv, nv)) {
if(res.index == -1) { if(res.index == -1) {
res.index = (ssize_t)i; res.index = (ssize_t)i + NGHTTP2_STATIC_TABLE_LENGTH;
} }
if(ent->value_hash == value_hash && value_eq(&ent->nv, nv)) { if(ent->value_hash == value_hash && value_eq(&ent->nv, nv)) {
res.index = (ssize_t)i; res.index = (ssize_t)i + NGHTTP2_STATIC_TABLE_LENGTH;
res.name_value_match = 1; res.name_value_match = 1;
return res; return res;
} }
@ -876,23 +894,6 @@ static search_result search_hd_table(nghttp2_hd_context *context,
} }
} }
for(i = 0; i < STATIC_TABLE_LENGTH; ++i) {
nghttp2_hd_entry *ent = &static_table[i];
if(ent->name_hash != name_hash || !name_eq(&ent->nv, nv)) {
continue;
}
if(res.index == -1) {
res.index = (ssize_t)(context->hd_table.len + i);
}
if(use_index &&
ent->value_hash == value_hash && value_eq(&ent->nv, nv)) {
res.index = (ssize_t)(context->hd_table.len + i);
res.name_value_match = 1;
return res;
}
}
return res; return res;
} }
@ -935,21 +936,21 @@ int nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
} }
#define INDEX_RANGE_VALID(context, idx) \ #define INDEX_RANGE_VALID(context, idx) \
((idx) < (context)->hd_table.len + STATIC_TABLE_LENGTH) ((idx) < (context)->hd_table.len + NGHTTP2_STATIC_TABLE_LENGTH)
static size_t get_max_index(nghttp2_hd_context *context) static size_t get_max_index(nghttp2_hd_context *context)
{ {
return context->hd_table.len + STATIC_TABLE_LENGTH - 1; return context->hd_table.len + NGHTTP2_STATIC_TABLE_LENGTH - 1;
} }
nghttp2_hd_entry* nghttp2_hd_table_get(nghttp2_hd_context *context, nghttp2_hd_entry* nghttp2_hd_table_get(nghttp2_hd_context *context,
size_t idx) size_t idx)
{ {
assert(INDEX_RANGE_VALID(context, idx)); assert(INDEX_RANGE_VALID(context, idx));
if(idx < context->hd_table.len) { if(idx >= NGHTTP2_STATIC_TABLE_LENGTH) {
return hd_ringbuf_get(&context->hd_table, idx); return hd_ringbuf_get(&context->hd_table, idx - NGHTTP2_STATIC_TABLE_LENGTH);
} else { } else {
return &static_table[idx - context->hd_table.len]; return &static_table[idx];
} }
} }
@ -980,7 +981,7 @@ static int deflate_nv(nghttp2_hd_deflater *deflater,
nghttp2_bufs *bufs, const nghttp2_nv *nv) nghttp2_bufs *bufs, const nghttp2_nv *nv)
{ {
int rv; int rv;
nghttp2_hd_entry *ent; /* nghttp2_hd_entry *ent; */
search_result res; search_result res;
DEBUGF(fprintf(stderr, "deflatehd: deflating ")); DEBUGF(fprintf(stderr, "deflatehd: deflating "));
@ -997,29 +998,9 @@ static int deflate_nv(nghttp2_hd_deflater *deflater,
DEBUGF(fprintf(stderr, "deflatehd: name/value match index=%zd\n", DEBUGF(fprintf(stderr, "deflatehd: name/value match index=%zd\n",
res.index)); res.index));
ent = nghttp2_hd_table_get(&deflater->ctx, idx); rv = emit_indexed_block(bufs, idx);
if(idx >= deflater->ctx.hd_table.len) { if(rv != 0) {
nghttp2_hd_entry *new_ent; return rv;
new_ent = add_hd_table_incremental(&deflater->ctx, bufs, &ent->nv,
NGHTTP2_HD_FLAG_NONE);
if(!new_ent) {
return NGHTTP2_ERR_HEADER_COMP;
}
if(new_ent->ref == 0) {
nghttp2_hd_entry_free(new_ent);
free(new_ent);
new_ent = NULL;
}
rv = emit_indexed_block(bufs, idx);
if(rv != 0) {
return rv;
}
} else {
rv = emit_indexed_block(bufs, idx);
if(rv != 0) {
return rv;
}
} }
} else { } else {
ssize_t idx = -1; ssize_t idx = -1;
@ -1032,7 +1013,7 @@ static int deflate_nv(nghttp2_hd_deflater *deflater,
} }
if(hd_deflate_should_indexing(deflater, nv)) { if(hd_deflate_should_indexing(deflater, nv)) {
nghttp2_hd_entry *new_ent; nghttp2_hd_entry *new_ent;
if(idx >= (ssize_t)deflater->ctx.hd_table.len) { if(idx != -1 && idx < (ssize_t)NGHTTP2_STATIC_TABLE_LENGTH) {
nghttp2_nv nv_indname; nghttp2_nv nv_indname;
nv_indname = *nv; nv_indname = *nv;
nv_indname.name = nghttp2_hd_table_get(&deflater->ctx, idx)->nv.name; nv_indname.name = nghttp2_hd_table_get(&deflater->ctx, idx)->nv.name;
@ -1320,18 +1301,6 @@ static int hd_inflate_commit_indexed(nghttp2_hd_inflater *inflater,
nghttp2_nv *nv_out) nghttp2_nv *nv_out)
{ {
nghttp2_hd_entry *ent = nghttp2_hd_table_get(&inflater->ctx, inflater->index); nghttp2_hd_entry *ent = nghttp2_hd_table_get(&inflater->ctx, inflater->index);
if(inflater->index >= inflater->ctx.hd_table.len) {
nghttp2_hd_entry *new_ent;
new_ent = add_hd_table_incremental(&inflater->ctx, NULL, &ent->nv,
NGHTTP2_HD_FLAG_NONE);
if(!new_ent) {
return NGHTTP2_ERR_NOMEM;
}
/* new_ent->ref == 0 may be hold */
emit_indexed_header(nv_out, new_ent);
inflater->ent_keep = new_ent;
return 0;
}
emit_indexed_header(nv_out, ent); emit_indexed_header(nv_out, ent);
@ -1462,7 +1431,7 @@ static int hd_inflate_commit_indname(nghttp2_hd_inflater *inflater,
int static_name; int static_name;
ent_flags = NGHTTP2_HD_FLAG_VALUE_ALLOC | NGHTTP2_HD_FLAG_VALUE_GIFT; ent_flags = NGHTTP2_HD_FLAG_VALUE_ALLOC | NGHTTP2_HD_FLAG_VALUE_GIFT;
static_name = inflater->index >= inflater->ctx.hd_table.len; static_name = inflater->index < NGHTTP2_STATIC_TABLE_LENGTH;
if(!static_name) { if(!static_name) {
ent_flags |= NGHTTP2_HD_FLAG_NAME_ALLOC; ent_flags |= NGHTTP2_HD_FLAG_NAME_ALLOC;

View File

@ -47,6 +47,9 @@
encoder only uses the memory up to this value. */ encoder only uses the memory up to this value. */
#define NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE (1 << 12) #define NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE (1 << 12)
/* Exported for unit test */
extern const size_t NGHTTP2_STATIC_TABLE_LENGTH;
typedef enum { typedef enum {
NGHTTP2_HD_ROLE_DEFLATE, NGHTTP2_HD_ROLE_DEFLATE,
NGHTTP2_HD_ROLE_INFLATE NGHTTP2_HD_ROLE_INFLATE

View File

@ -294,9 +294,11 @@ void test_nghttp2_hd_inflate_indname_inc(void)
CU_ASSERT(1 == out.nvlen); CU_ASSERT(1 == out.nvlen);
assert_nv_equal(&nv, out.nva, 1); assert_nv_equal(&nv, out.nva, 1);
CU_ASSERT(1 == inflater.ctx.hd_table.len); CU_ASSERT(1 == inflater.ctx.hd_table.len);
assert_nv_equal(&nv, assert_nv_equal
&GET_TABLE_ENT(&inflater.ctx, (&nv,
inflater.ctx.hd_table.len-1)->nv, 1); &GET_TABLE_ENT
(&inflater.ctx,
NGHTTP2_STATIC_TABLE_LENGTH + inflater.ctx.hd_table.len-1)->nv, 1);
nva_out_reset(&out); nva_out_reset(&out);
nghttp2_bufs_free(&bufs); nghttp2_bufs_free(&bufs);
@ -413,9 +415,11 @@ void test_nghttp2_hd_inflate_newname_inc(void)
CU_ASSERT(1 == out.nvlen); CU_ASSERT(1 == out.nvlen);
assert_nv_equal(&nv, out.nva, 1); assert_nv_equal(&nv, out.nva, 1);
CU_ASSERT(1 == inflater.ctx.hd_table.len); CU_ASSERT(1 == inflater.ctx.hd_table.len);
assert_nv_equal(&nv, assert_nv_equal
&GET_TABLE_ENT(&inflater.ctx, (&nv,
inflater.ctx.hd_table.len-1)->nv, 1); &GET_TABLE_ENT
(&inflater.ctx,
NGHTTP2_STATIC_TABLE_LENGTH + inflater.ctx.hd_table.len-1)->nv, 1);
nva_out_reset(&out); nva_out_reset(&out);
nghttp2_bufs_free(&bufs); nghttp2_bufs_free(&bufs);
@ -579,8 +583,8 @@ void test_nghttp2_hd_change_table_size(void)
{ {
nghttp2_hd_deflater deflater; nghttp2_hd_deflater deflater;
nghttp2_hd_inflater inflater; nghttp2_hd_inflater inflater;
nghttp2_nv nva[] = { MAKE_NV(":method", "GET"), nghttp2_nv nva[] = { MAKE_NV("alpha", "bravo"),
MAKE_NV(":path", "/") }; MAKE_NV("charlie", "delta") };
nghttp2_bufs bufs; nghttp2_bufs bufs;
ssize_t rv; ssize_t rv;
nva_out out; nva_out out;