Refactor nghttp2_hd

This commit is contained in:
Tatsuhiro Tsujikawa 2013-07-20 00:30:56 +09:00
parent fb43f8aa93
commit 00b2d06850
2 changed files with 75 additions and 69 deletions

View File

@ -218,15 +218,15 @@ static void nghttp2_hd_context_free(nghttp2_hd_context *context)
nghttp2_hd_ws_entry *ent = &context->ws[i]; nghttp2_hd_ws_entry *ent = &context->ws[i];
switch(ent->cat) { switch(ent->cat) {
case NGHTTP2_HD_CAT_INDEXED: case NGHTTP2_HD_CAT_INDEXED:
--ent->entry->ref; --ent->indexed.entry->ref;
if(ent->entry->ref == 0) { if(ent->indexed.entry->ref == 0) {
nghttp2_hd_entry_free(ent->entry); nghttp2_hd_entry_free(ent->indexed.entry);
} }
break; break;
case NGHTTP2_HD_CAT_LITERAL_IDXNAME: case NGHTTP2_HD_CAT_INDNAME:
--ent->entv.entry->ref; --ent->indname.entry->ref;
if(ent->entv.entry->ref == 0) { if(ent->indname.entry->ref == 0) {
nghttp2_hd_entry_free(ent->entv.entry); nghttp2_hd_entry_free(ent->indname.entry);
} }
break; break;
default: default:
@ -384,13 +384,13 @@ static int add_workingset(nghttp2_hd_context *context, nghttp2_hd_entry *ent)
} }
ws_ent = &context->ws[context->wslen++]; ws_ent = &context->ws[context->wslen++];
ws_ent->cat = NGHTTP2_HD_CAT_INDEXED; ws_ent->cat = NGHTTP2_HD_CAT_INDEXED;
ws_ent->entry = ent; ws_ent->indexed.entry = ent;
ws_ent->checked = 1; ws_ent->indexed.checked = 1;
++ent->ref; ++ent->ref;
return 0; return 0;
} }
static int add_workingset_literal(nghttp2_hd_context *context, static int add_workingset_newname(nghttp2_hd_context *context,
nghttp2_nv *nv) nghttp2_nv *nv)
{ {
nghttp2_hd_ws_entry *ws_ent; nghttp2_hd_ws_entry *ws_ent;
@ -398,12 +398,12 @@ static int add_workingset_literal(nghttp2_hd_context *context,
return NGHTTP2_ERR_HEADER_COMP; return NGHTTP2_ERR_HEADER_COMP;
} }
ws_ent = &context->ws[context->wslen++]; ws_ent = &context->ws[context->wslen++];
ws_ent->cat = NGHTTP2_HD_CAT_LITERAL; ws_ent->cat = NGHTTP2_HD_CAT_NEWNAME;
ws_ent->nv = *nv; ws_ent->newname.nv = *nv;
return 0; return 0;
} }
static int add_workingset_literal_indname(nghttp2_hd_context *context, static int add_workingset_indname(nghttp2_hd_context *context,
nghttp2_hd_entry *ent, nghttp2_hd_entry *ent,
uint8_t *value, size_t valuelen) uint8_t *value, size_t valuelen)
{ {
@ -412,11 +412,11 @@ static int add_workingset_literal_indname(nghttp2_hd_context *context,
return NGHTTP2_ERR_HEADER_COMP; return NGHTTP2_ERR_HEADER_COMP;
} }
ws_ent = &context->ws[context->wslen++]; ws_ent = &context->ws[context->wslen++];
ws_ent->cat = NGHTTP2_HD_CAT_LITERAL_IDXNAME; ws_ent->cat = NGHTTP2_HD_CAT_INDNAME;
ws_ent->entv.entry = ent; ws_ent->indname.entry = ent;
++ent->ref; ++ent->ref;
ws_ent->entv.value = value; ws_ent->indname.value = value;
ws_ent->entv.valuelen = valuelen; ws_ent->indname.valuelen = valuelen;
return 0; return 0;
} }
@ -428,20 +428,20 @@ static nghttp2_hd_ws_entry* find_in_workingset(nghttp2_hd_context *context,
nghttp2_hd_ws_entry *ent = &context->ws[i]; nghttp2_hd_ws_entry *ent = &context->ws[i];
switch(ent->cat) { switch(ent->cat) {
case NGHTTP2_HD_CAT_INDEXED: case NGHTTP2_HD_CAT_INDEXED:
if(nghttp2_nv_equal(&ent->entry->nv, nv)) { if(nghttp2_nv_equal(&ent->indexed.entry->nv, nv)) {
return ent; return ent;
} }
break; break;
case NGHTTP2_HD_CAT_LITERAL_IDXNAME: case NGHTTP2_HD_CAT_INDNAME:
if(ent->entv.entry->nv.namelen == nv->namelen && if(ent->indname.entry->nv.namelen == nv->namelen &&
ent->entv.valuelen == nv->valuelen && ent->indname.valuelen == nv->valuelen &&
memcmp(ent->entv.entry->nv.name, nv->name, nv->namelen) == 0 && memcmp(ent->indname.entry->nv.name, nv->name, nv->namelen) == 0 &&
memcmp(ent->entv.value, nv->value, nv->valuelen) == 0) { memcmp(ent->indname.value, nv->value, nv->valuelen) == 0) {
return ent; return ent;
} }
break; break;
case NGHTTP2_HD_CAT_LITERAL: case NGHTTP2_HD_CAT_NEWNAME:
if(nghttp2_nv_equal(&ent->nv, nv)) { if(nghttp2_nv_equal(&ent->newname.nv, nv)) {
return ent; return ent;
} }
default: default:
@ -459,7 +459,7 @@ static nghttp2_hd_ws_entry* find_in_workingset_by_index
nghttp2_hd_ws_entry *ent = &context->ws[i]; nghttp2_hd_ws_entry *ent = &context->ws[i];
/* Compare against *frozen* index, not the current header table /* Compare against *frozen* index, not the current header table
index. */ index. */
if(ent->cat == NGHTTP2_HD_CAT_INDEXED && ent->index == index) { if(ent->cat == NGHTTP2_HD_CAT_INDEXED && ent->indexed.index == index) {
return ent; return ent;
} }
} }
@ -712,9 +712,9 @@ static void create_workingset(nghttp2_hd_context *context)
for(i = 0; i < context->refsetlen; ++i) { for(i = 0; i < context->refsetlen; ++i) {
nghttp2_hd_ws_entry *ent = &context->ws[i]; nghttp2_hd_ws_entry *ent = &context->ws[i];
ent->cat = NGHTTP2_HD_CAT_INDEXED; ent->cat = NGHTTP2_HD_CAT_INDEXED;
ent->entry = context->refset[i]; ent->indexed.entry = context->refset[i];
ent->index = ent->entry->index; ent->indexed.index = ent->indexed.entry->index;
ent->checked = 0; ent->indexed.checked = 0;
context->refset[i] = NULL; context->refset[i] = NULL;
} }
context->wslen = context->refsetlen; context->wslen = context->refsetlen;
@ -734,7 +734,9 @@ ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_context *deflater,
nghttp2_hd_ws_entry *ws_ent; nghttp2_hd_ws_entry *ws_ent;
ws_ent = find_in_workingset(deflater, &nv[i]); ws_ent = find_in_workingset(deflater, &nv[i]);
if(ws_ent) { if(ws_ent) {
ws_ent->checked = 1; if(ws_ent->cat == NGHTTP2_HD_CAT_INDEXED) {
ws_ent->indexed.checked = 1;
}
} else { } else {
nghttp2_hd_entry *ent; nghttp2_hd_entry *ent;
ent = find_in_hd_table(deflater, &nv[i]); ent = find_in_hd_table(deflater, &nv[i]);
@ -768,9 +770,10 @@ ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_context *deflater,
} }
for(i = 0; i < deflater->wslen; ++i) { for(i = 0; i < deflater->wslen; ++i) {
nghttp2_hd_ws_entry *ws_ent = &deflater->ws[i]; nghttp2_hd_ws_entry *ws_ent = &deflater->ws[i];
if(!ws_ent->checked) { if(ws_ent->cat == NGHTTP2_HD_CAT_INDEXED &&
assert(ws_ent->cat == NGHTTP2_HD_CAT_INDEXED); !ws_ent->indexed.checked) {
rv = emit_index_block(buf_ptr, buflen_ptr, &offset, ws_ent->entry); rv = emit_index_block(buf_ptr, buflen_ptr, &offset,
ws_ent->indexed.entry);
if(rv < 0) { if(rv < 0) {
return rv; return rv;
} }
@ -799,19 +802,19 @@ static ssize_t build_nv_array(nghttp2_hd_context *inflater,
nghttp2_hd_ws_entry *ent = &inflater->ws[i]; nghttp2_hd_ws_entry *ent = &inflater->ws[i];
switch(ent->cat) { switch(ent->cat) {
case NGHTTP2_HD_CAT_INDEXED: case NGHTTP2_HD_CAT_INDEXED:
*nv = ent->entry->nv; *nv = ent->indexed.entry->nv;
ent->checked = 1; ent->indexed.checked = 1;
++nv; ++nv;
break; break;
case NGHTTP2_HD_CAT_LITERAL_IDXNAME: case NGHTTP2_HD_CAT_INDNAME:
nv->name = ent->entv.entry->nv.name; nv->name = ent->indname.entry->nv.name;
nv->namelen = ent->entv.entry->nv.namelen; nv->namelen = ent->indname.entry->nv.namelen;
nv->value = ent->entv.value; nv->value = ent->indname.value;
nv->valuelen = ent->entv.valuelen; nv->valuelen = ent->indname.valuelen;
++nv; ++nv;
break; break;
case NGHTTP2_HD_CAT_LITERAL: case NGHTTP2_HD_CAT_NEWNAME:
*nv = ent->nv; *nv = ent->newname.nv;
++nv; ++nv;
break; break;
default: default:
@ -842,10 +845,10 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
ws_ent = find_in_workingset_by_index(inflater, index); ws_ent = find_in_workingset_by_index(inflater, index);
if(ws_ent) { if(ws_ent) {
assert(ws_ent->cat == NGHTTP2_HD_CAT_INDEXED); assert(ws_ent->cat == NGHTTP2_HD_CAT_INDEXED);
--ws_ent->entry->ref; --ws_ent->indexed.entry->ref;
if(ws_ent->entry->ref == 0) { if(ws_ent->indexed.entry->ref == 0) {
nghttp2_hd_entry_free(ws_ent->entry); nghttp2_hd_entry_free(ws_ent->indexed.entry);
free(ws_ent->entry); free(ws_ent->indexed.entry);
} }
ws_ent->cat = NGHTTP2_HD_CAT_NONE; ws_ent->cat = NGHTTP2_HD_CAT_NONE;
} else { } else {
@ -883,7 +886,7 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
in += valuelen; in += valuelen;
nghttp2_downcase(nv.name, nv.namelen); nghttp2_downcase(nv.name, nv.namelen);
if(c == 0x60u) { if(c == 0x60u) {
rv = add_workingset_literal(inflater, &nv); rv = add_workingset_newname(inflater, &nv);
} else { } else {
nghttp2_hd_entry *ent = add_hd_table_incremental(inflater, &nv); nghttp2_hd_entry *ent = add_hd_table_incremental(inflater, &nv);
if(ent) { if(ent) {
@ -918,7 +921,7 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
value = in; value = in;
in += valuelen; in += valuelen;
if((c & 0x60u) == 0x60u) { if((c & 0x60u) == 0x60u) {
rv = add_workingset_literal_indname(inflater, ent, value, valuelen); rv = add_workingset_indname(inflater, ent, value, valuelen);
} else { } else {
nghttp2_nv nv; nghttp2_nv nv;
nghttp2_hd_entry *new_ent; nghttp2_hd_entry *new_ent;
@ -1032,21 +1035,21 @@ int nghttp2_hd_end_headers(nghttp2_hd_context *context)
nghttp2_hd_ws_entry *ws_ent = &context->ws[i]; nghttp2_hd_ws_entry *ws_ent = &context->ws[i];
switch(ws_ent->cat) { switch(ws_ent->cat) {
case NGHTTP2_HD_CAT_INDEXED: case NGHTTP2_HD_CAT_INDEXED:
if(ws_ent->checked == 0 || ws_ent->entry->ref == 1) { if(ws_ent->indexed.checked == 0 || ws_ent->indexed.entry->ref == 1) {
--ws_ent->entry->ref; --ws_ent->indexed.entry->ref;
if(ws_ent->entry->ref == 0) { if(ws_ent->indexed.entry->ref == 0) {
nghttp2_hd_entry_free(ws_ent->entry); nghttp2_hd_entry_free(ws_ent->indexed.entry);
free(ws_ent->entry); free(ws_ent->indexed.entry);
} }
} else { } else {
context->refset[context->refsetlen++] = ws_ent->entry; context->refset[context->refsetlen++] = ws_ent->indexed.entry;
} }
break; break;
case NGHTTP2_HD_CAT_LITERAL_IDXNAME: case NGHTTP2_HD_CAT_INDNAME:
--ws_ent->entv.entry->ref; --ws_ent->indname.entry->ref;
if(ws_ent->entv.entry->ref == 0) { if(ws_ent->indname.entry->ref == 0) {
nghttp2_hd_entry_free(ws_ent->entv.entry); nghttp2_hd_entry_free(ws_ent->indname.entry);
free(ws_ent->entv.entry); free(ws_ent->indname.entry);
} }
break; break;
default: default:

View File

@ -63,28 +63,31 @@ typedef struct {
typedef enum { typedef enum {
NGHTTP2_HD_CAT_NONE, NGHTTP2_HD_CAT_NONE,
NGHTTP2_HD_CAT_INDEXED, NGHTTP2_HD_CAT_INDEXED,
NGHTTP2_HD_CAT_LITERAL_IDXNAME, NGHTTP2_HD_CAT_INDNAME,
NGHTTP2_HD_CAT_LITERAL NGHTTP2_HD_CAT_NEWNAME
} nghttp2_hd_entry_cat; } nghttp2_hd_entry_cat;
typedef struct nghttp2_hd_ws_entry { typedef struct nghttp2_hd_ws_entry {
nghttp2_hd_entry_cat cat; nghttp2_hd_entry_cat cat;
union { union {
/* For NGHTTP2_HD_CAT_INDEXED */ /* For NGHTTP2_HD_CAT_INDEXED */
nghttp2_hd_entry *entry; struct {
/* For NGHTTP2_HD_CAT_LITERAL */ nghttp2_hd_entry *entry;
nghttp2_nv nv; uint8_t index;
/* For NGHTTP2_HD_CAT_LITERAL_IDXNAME */ uint8_t checked;
} indexed;
/* For NGHTTP2_HD_CAT_NEWNAME */
struct {
nghttp2_nv nv;
} newname;
/* For NGHTTP2_HD_CAT_LITERAL_INDNAME */
struct { struct {
/* The entry in header table the name stored */ /* The entry in header table the name stored */
nghttp2_hd_entry *entry; nghttp2_hd_entry *entry;
uint8_t *value; uint8_t *value;
uint16_t valuelen; uint16_t valuelen;
} entv; } indname;
}; };
/* TODO Only usable with NGHTTP2_HD_CAT_INDEXED */
uint8_t index;
uint8_t checked;
} nghttp2_hd_ws_entry; } nghttp2_hd_ws_entry;
typedef struct { typedef struct {