Make huffman decoding slightly faster using evil looking macro
This commit is contained in:
parent
02468b1ca1
commit
bbdff112a3
|
@ -168,6 +168,23 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) {
|
||||||
ctx->accept = 1;
|
ctx->accept = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Use macro to make the code simpler..., but error case is tricky.
|
||||||
|
We spent most of the CPU in decoding, so we are doing this
|
||||||
|
thing. */
|
||||||
|
#define hd_huff_decode_sym_emit(bufs, sym, avail) \
|
||||||
|
do { \
|
||||||
|
if ((avail)) { \
|
||||||
|
nghttp2_bufs_fast_addb((bufs), (sym)); \
|
||||||
|
--(avail); \
|
||||||
|
} else { \
|
||||||
|
rv = nghttp2_bufs_addb((bufs), (sym)); \
|
||||||
|
if (rv != 0) { \
|
||||||
|
return rv; \
|
||||||
|
} \
|
||||||
|
(avail) = nghttp2_bufs_cur_avail((bufs)); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
||||||
nghttp2_bufs *bufs, const uint8_t *src,
|
nghttp2_bufs *bufs, const uint8_t *src,
|
||||||
size_t srclen, int final) {
|
size_t srclen, int final) {
|
||||||
|
@ -180,30 +197,28 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
||||||
/* We use the decoding algorithm described in
|
/* We use the decoding algorithm described in
|
||||||
http://graphics.ics.uci.edu/pub/Prefix.pdf */
|
http://graphics.ics.uci.edu/pub/Prefix.pdf */
|
||||||
for (i = 0; i < srclen; ++i) {
|
for (i = 0; i < srclen; ++i) {
|
||||||
uint8_t in = src[i] >> 4;
|
const nghttp2_huff_decode *t;
|
||||||
for (j = 0; j < 2; ++j) {
|
|
||||||
const nghttp2_huff_decode *t;
|
|
||||||
|
|
||||||
t = &huff_decode_table[ctx->state][in];
|
t = &huff_decode_table[ctx->state][src[i] >> 4];
|
||||||
if (t->flags & NGHTTP2_HUFF_FAIL) {
|
if (t->flags & NGHTTP2_HUFF_FAIL) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
}
|
|
||||||
if (t->flags & NGHTTP2_HUFF_SYM) {
|
|
||||||
if (avail) {
|
|
||||||
nghttp2_bufs_fast_addb(bufs, t->sym);
|
|
||||||
--avail;
|
|
||||||
} else {
|
|
||||||
rv = nghttp2_bufs_addb(bufs, t->sym);
|
|
||||||
if (rv != 0) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
avail = nghttp2_bufs_cur_avail(bufs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx->state = t->state;
|
|
||||||
ctx->accept = (t->flags & NGHTTP2_HUFF_ACCEPTED) != 0;
|
|
||||||
in = src[i] & 0xf;
|
|
||||||
}
|
}
|
||||||
|
if (t->flags & NGHTTP2_HUFF_SYM) {
|
||||||
|
/* this is macro, and may return from this function on error */
|
||||||
|
hd_huff_decode_sym_emit(bufs, t->sym, avail);
|
||||||
|
}
|
||||||
|
|
||||||
|
t = &huff_decode_table[t->state][src[i] & 0xf];
|
||||||
|
if (t->flags & NGHTTP2_HUFF_FAIL) {
|
||||||
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
}
|
||||||
|
if (t->flags & NGHTTP2_HUFF_SYM) {
|
||||||
|
/* this is macro, and may return from this function on error */
|
||||||
|
hd_huff_decode_sym_emit(bufs, t->sym, avail);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->state = t->state;
|
||||||
|
ctx->accept = (t->flags & NGHTTP2_HUFF_ACCEPTED) != 0;
|
||||||
}
|
}
|
||||||
if (final && !ctx->accept) {
|
if (final && !ctx->accept) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
|
Loading…
Reference in New Issue