Use substitution as long as no eviction is required

This commit is contained in:
Tatsuhiro Tsujikawa 2013-07-20 01:19:00 +09:00
parent aa87130711
commit e92b74d66e
2 changed files with 33 additions and 7 deletions

View File

@ -722,6 +722,14 @@ static void create_workingset(nghttp2_hd_context *context)
context->refsetlen = 0; context->refsetlen = 0;
} }
static int require_eviction_on_subst(nghttp2_hd_context *context,
nghttp2_nv *nv,
nghttp2_hd_entry *ent)
{
return context->capacity - entry_room(ent->nv.namelen, ent->nv.valuelen) +
entry_room(nv->namelen, nv->valuelen) > NGHTTP2_MAX_HD_TABLE_CAPACITY;
}
ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_context *deflater, ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_context *deflater,
uint8_t **buf_ptr, size_t *buflen_ptr, uint8_t **buf_ptr, size_t *buflen_ptr,
size_t nv_offset, size_t nv_offset,
@ -755,10 +763,28 @@ ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_context *deflater,
/* Check name exists in hd_table */ /* Check name exists in hd_table */
ent = find_name_in_hd_table(deflater, &nv[i]); ent = find_name_in_hd_table(deflater, &nv[i]);
if(ent) { if(ent) {
rv = emit_literal_indname_block(buf_ptr, buflen_ptr, &offset, ent, /* As long as no eviction kicked in, perform substitution */
nv[i].value, nv[i].valuelen, 0); if(require_eviction_on_subst(deflater, &nv[i], ent)) {
if(rv < 0) { rv = emit_literal_indname_block(buf_ptr, buflen_ptr, &offset, ent,
return rv; nv[i].value, nv[i].valuelen, 0);
} else {
nghttp2_hd_entry *new_ent;
/* No need to increment ent->ref here */
new_ent = add_hd_table_subst(deflater, &nv[i], ent->index);
if(!new_ent) {
return NGHTTP2_ERR_HEADER_COMP;
}
rv = add_workingset(deflater, new_ent);
if(rv < 0) {
return rv;
}
rv = emit_subst_indname_block(buf_ptr, buflen_ptr, &offset,
new_ent,
nv[i].value, nv[i].valuelen,
new_ent->index);
if(rv < 0) {
return rv;
}
} }
} else { } else {
rv = emit_literal_block(buf_ptr, buflen_ptr, &offset, &nv[i], 0); rv = emit_literal_block(buf_ptr, buflen_ptr, &offset, &nv[i], 0);

View File

@ -62,7 +62,7 @@ void test_nghttp2_hd_deflate(void)
blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, nv_offset, nva1, blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, nv_offset, nva1,
sizeof(nva1)/sizeof(nghttp2_nv)); sizeof(nva1)/sizeof(nghttp2_nv));
CU_ASSERT((1+1+22)+(1)+(1+1+5+1+5) == blocklen); CU_ASSERT(blocklen > 0);
nghttp2_hd_end_headers(&deflater); nghttp2_hd_end_headers(&deflater);
CU_ASSERT(3 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf + nv_offset, CU_ASSERT(3 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf + nv_offset,
@ -73,12 +73,12 @@ void test_nghttp2_hd_deflate(void)
nghttp2_nv_array_del(resnva); nghttp2_nv_array_del(resnva);
nghttp2_hd_end_headers(&inflater); nghttp2_hd_end_headers(&inflater);
CU_ASSERT(1 == inflater.refsetlen); CU_ASSERT(2 == inflater.refsetlen);
/* Second headers */ /* Second headers */
blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, nv_offset, nva2, blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, nv_offset, nva2,
sizeof(nva2)/sizeof(nghttp2_nv)); sizeof(nva2)/sizeof(nghttp2_nv));
CU_ASSERT((1+1+10) == blocklen); CU_ASSERT(blocklen > 0);
nghttp2_hd_end_headers(&deflater); nghttp2_hd_end_headers(&deflater);
CU_ASSERT(2 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf + nv_offset, CU_ASSERT(2 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf + nv_offset,