Reduce huffman decoding table

Previously we have uint16_t as state member variable in
nghttp2_huff_decode structure to express -1 as failure.  This is
because we have 256 valid states.  However, we can express failed
state using flags member variable and make state uint8_t.  This commit
does this and as a result the size of decoding table is reduced.
This commit is contained in:
Tatsuhiro Tsujikawa 2014-05-31 00:19:30 +09:00
parent 7a797b2c11
commit 88b69bb669
4 changed files with 31 additions and 26 deletions

View File

@ -179,10 +179,8 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
for(j = 0; j < 2; ++j) {
const nghttp2_huff_decode *t;
assert(ctx->state >= 0);
t = &huff_decode_table[ctx->state][in];
if(t->state == -1) {
if(t->flags & NGHTTP2_HUFF_FAIL) {
return NGHTTP2_ERR_HEADER_COMP;
}
if(t->flags & NGHTTP2_HUFF_SYM) {

View File

@ -36,13 +36,17 @@ typedef enum {
sequence. */
NGHTTP2_HUFF_ACCEPTED = 1,
/* This state emits symbol */
NGHTTP2_HUFF_SYM = (1 << 1)
NGHTTP2_HUFF_SYM = (1 << 1),
/* If state machine reaches this state, decoding fails. */
NGHTTP2_HUFF_FAIL = (1 << 2),
} nghttp2_huff_decode_flag;
typedef struct {
/* huffman decoding state, which is actually the node ID of internal
huffman tree */
int16_t state;
huffman tree. We have 257 leaf nodes, but they are identical to
root node other than emitting a symbol, so we have 256 internal
nodes [1..255], inclusive. */
uint8_t state;
/* bitwise OR of zero or more of the nghttp2_huff_decode_flag */
uint8_t flags;
/* symbol if NGHTTP2_HUFF_SYM flag set */
@ -54,7 +58,7 @@ typedef nghttp2_huff_decode huff_decode_table_type[16];
typedef struct {
/* Current huffman decoding state. We stripped leaf nodes, so the
value range is [0..255], inclusive. */
int16_t state;
uint8_t state;
/* nonzero if we can say that the decoding process succeeds at this
state */
uint8_t accept;

View File

@ -3624,7 +3624,7 @@ const nghttp2_huff_decode huff_decode_table[][16] = {
{0, 0x03, 253},
{0, 0x03, 254},
{0, 0x03, 255},
{-1, 0x00, 0},
{0, 0x04, 0},
{189, 0x00, 0},
{191, 0x00, 0},
{192, 0x00, 0},
@ -3772,8 +3772,8 @@ const nghttp2_huff_decode huff_decode_table[][16] = {
{14, 0x03, 254},
{1, 0x02, 255},
{14, 0x03, 255},
{-1, 0x00, 0},
{-1, 0x00, 0},
{0, 0x04, 0},
{0, 0x04, 0},
{0, 0x03, 0},
{0, 0x03, 1},
{0, 0x03, 2},
@ -3840,10 +3840,10 @@ const nghttp2_huff_decode huff_decode_table[][16] = {
},
/* 187 */
{
{-1, 0x00, 0},
{-1, 0x00, 0},
{-1, 0x00, 0},
{-1, 0x00, 0},
{0, 0x04, 0},
{0, 0x04, 0},
{0, 0x04, 0},
{0, 0x04, 0},
{1, 0x02, 0},
{14, 0x03, 0},
{1, 0x02, 1},
@ -3859,14 +3859,14 @@ const nghttp2_huff_decode huff_decode_table[][16] = {
},
/* 188 */
{
{-1, 0x00, 0},
{-1, 0x00, 0},
{-1, 0x00, 0},
{-1, 0x00, 0},
{-1, 0x00, 0},
{-1, 0x00, 0},
{-1, 0x00, 0},
{-1, 0x00, 0},
{0, 0x04, 0},
{0, 0x04, 0},
{0, 0x04, 0},
{0, 0x04, 0},
{0, 0x04, 0},
{0, 0x04, 0},
{0, 0x04, 0},
{0, 0x04, 0},
{2, 0x02, 0},
{6, 0x02, 0},
{15, 0x02, 0},

View File

@ -84,6 +84,7 @@ def dfs(node, root):
NGHTTP2_HUFF_ACCEPTED = 1
NGHTTP2_HUFF_SYM = 1 << 1
NGHTTP2_HUFF_FAIL = 1 << 2
def dfs_print(node):
if node.term is not None:
@ -100,7 +101,8 @@ def dfs_print(node):
out = syms[0]
flags |= NGHTTP2_HUFF_SYM
if nd is None:
id = -1
id = 0
flags |= NGHTTP2_HUFF_FAIL
else:
id = nd.id
if id is None:
@ -159,13 +161,14 @@ print ''
print '''\
enum {{
NGHTTP2_HUFF_ACCEPTED = {},
NGHTTP2_HUFF_SYM = {}
NGHTTP2_HUFF_SYM = {},
NGHTTP2_HUFF_FAIL = {},
}} nghttp2_huff_decode_flag;
'''.format(NGHTTP2_HUFF_ACCEPTED, NGHTTP2_HUFF_SYM)
'''.format(NGHTTP2_HUFF_ACCEPTED, NGHTTP2_HUFF_SYM, NGHTTP2_HUFF_FAIL)
print '''\
typedef struct {
int16_t state;
uint8_t state;
uint8_t flags;
uint8_t sym;
} nghttp2_huff_decode;