mirror of
https://github.com/nginx/nginx.git
synced 2026-05-06 07:46:38 -04:00
HTTP/3: optimize encoder stream memory usage
Previously, the encoder stream allocated each new inserted field in the connection pool. This memory was not freed until the end of the connection. Now a special insert buffer is used for all inserts.
This commit is contained in:
committed by
Roman Arutyunyan
parent
4e89ce224f
commit
d7dd7e9ae4
@@ -633,9 +633,23 @@ ngx_http_v3_parse_literal(ngx_connection_t *c, ngx_http_v3_parse_literal_t *st,
|
||||
st->huffstate = 0;
|
||||
}
|
||||
|
||||
st->last = ngx_pnalloc(c->pool, n + 1);
|
||||
if (st->last == NULL) {
|
||||
return NGX_ERROR;
|
||||
if (st->buf) {
|
||||
if ((size_t) (st->buf->end - st->buf->last) < n + 1) {
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||
"not enough dynamic table capacity");
|
||||
|
||||
st->last = NULL;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
st->last = st->buf->last;
|
||||
st->buf->last += n + 1;
|
||||
|
||||
} else {
|
||||
st->last = ngx_pnalloc(c->pool, n + 1);
|
||||
if (st->last == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
st->value.data = st->last;
|
||||
@@ -1486,6 +1500,11 @@ ngx_http_v3_parse_field_inr(ngx_connection_t *c,
|
||||
|
||||
ch = *b->pos;
|
||||
|
||||
st->literal.buf = ngx_http_v3_get_insert_buffer(c);
|
||||
if (st->literal.buf == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
st->dynamic = (ch & 0x40) ? 0 : 1;
|
||||
st->state = sw_name_index;
|
||||
|
||||
@@ -1590,6 +1609,11 @@ ngx_http_v3_parse_field_iln(ngx_connection_t *c,
|
||||
|
||||
ch = *b->pos;
|
||||
|
||||
st->literal.buf = ngx_http_v3_get_insert_buffer(c);
|
||||
if (st->literal.buf == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
st->literal.huffman = (ch & 0x20) ? 1 : 0;
|
||||
st->state = sw_name_len;
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ typedef struct {
|
||||
ngx_str_t value;
|
||||
u_char *last;
|
||||
u_char huffstate;
|
||||
ngx_buf_t *buf;
|
||||
} ngx_http_v3_parse_literal_t;
|
||||
|
||||
|
||||
|
||||
@@ -155,6 +155,28 @@ static ngx_http_v3_field_t ngx_http_v3_static_table[] = {
|
||||
};
|
||||
|
||||
|
||||
ngx_buf_t *
|
||||
ngx_http_v3_get_insert_buffer(ngx_connection_t *c)
|
||||
{
|
||||
ngx_http_v3_session_t *h3c;
|
||||
ngx_http_v3_dynamic_table_t *dt;
|
||||
|
||||
h3c = ngx_http_v3_get_session(c);
|
||||
dt = &h3c->table;
|
||||
|
||||
if (dt->insert_buffer == NULL) {
|
||||
dt->insert_buffer = ngx_create_temp_buf(c->pool, dt->capacity);
|
||||
if (dt->insert_buffer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
dt->insert_buffer->last = dt->insert_buffer->pos;
|
||||
|
||||
return dt->insert_buffer;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_v3_ref_insert(ngx_connection_t *c, ngx_uint_t dynamic,
|
||||
ngx_uint_t index, ngx_str_t *value)
|
||||
|
||||
@@ -29,11 +29,13 @@ typedef struct {
|
||||
uint64_t insert_count;
|
||||
uint64_t ack_insert_count;
|
||||
ngx_event_t send_insert_count;
|
||||
ngx_buf_t *insert_buffer;
|
||||
} ngx_http_v3_dynamic_table_t;
|
||||
|
||||
|
||||
void ngx_http_v3_inc_insert_count_handler(ngx_event_t *ev);
|
||||
void ngx_http_v3_cleanup_table(ngx_http_v3_session_t *h3c);
|
||||
ngx_buf_t *ngx_http_v3_get_insert_buffer(ngx_connection_t *c);
|
||||
ngx_int_t ngx_http_v3_ref_insert(ngx_connection_t *c, ngx_uint_t dynamic,
|
||||
ngx_uint_t index, ngx_str_t *value);
|
||||
ngx_int_t ngx_http_v3_insert(ngx_connection_t *c, ngx_str_t *name,
|
||||
|
||||
Reference in New Issue
Block a user