mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 23:56:57 +02:00
MEDIUM: htx: make htx_add_data() never defragment the buffer
Now instead of trying to fit 100% of the input data into the output buffer at the risk of defragmenting it, we put what fits into it only and return the amount of bytes transferred. In a test, compared to the previous commit, it increases the cached data rate from 44 Gbps to 55 Gbps and saves a lot in case of large buffers : with a 1 MB buffer, uncached transfers jumped from 700 Mbps to 30 Gbps.
This commit is contained in:
parent
0a7ef02074
commit
0350b90e31
66
src/htx.c
66
src/htx.c
@ -763,13 +763,69 @@ struct htx_blk *htx_add_endof(struct htx *htx, enum htx_blk_type type)
|
|||||||
*/
|
*/
|
||||||
size_t htx_add_data(struct htx *htx, const struct ist data)
|
size_t htx_add_data(struct htx *htx, const struct ist data)
|
||||||
{
|
{
|
||||||
struct htx_blk *blk;
|
struct htx_blk *blk, *tailblk, *headblk, *frtblk;
|
||||||
|
struct ist v;
|
||||||
|
int32_t room;
|
||||||
|
int32_t len = data.len;
|
||||||
|
|
||||||
blk = htx_add_data_atonce(htx, data);
|
if (!htx->used)
|
||||||
if (blk)
|
goto add_new_block;
|
||||||
return data.len;
|
|
||||||
else
|
/* Not enough space to store data */
|
||||||
|
if (len > htx_free_data_space(htx))
|
||||||
|
len = htx_free_data_space(htx);
|
||||||
|
|
||||||
|
if (!len)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* get the tail and head block */
|
||||||
|
tailblk = htx_get_tail_blk(htx);
|
||||||
|
headblk = htx_get_head_blk(htx);
|
||||||
|
if (tailblk == NULL || headblk == NULL)
|
||||||
|
goto add_new_block;
|
||||||
|
|
||||||
|
/* Don't try to append data if the last inserted block is not of the
|
||||||
|
* same type */
|
||||||
|
if (htx_get_blk_type(tailblk) != HTX_BLK_DATA)
|
||||||
|
goto add_new_block;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Same type and enough space: append data
|
||||||
|
*/
|
||||||
|
frtblk = htx_get_blk(htx, htx->front);
|
||||||
|
if (tailblk->addr >= headblk->addr) {
|
||||||
|
if (htx->tail != htx->front)
|
||||||
|
goto add_new_block;
|
||||||
|
room = sizeof(htx->blocks[0]) * htx_pos_to_idx(htx, htx->tail) - (frtblk->addr + htx_get_blksz(frtblk));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
room = headblk->addr - (tailblk->addr + htx_get_blksz(tailblk));
|
||||||
|
|
||||||
|
if (room < len)
|
||||||
|
len = room;
|
||||||
|
|
||||||
|
append_data:
|
||||||
|
/* get the value of the tail block */
|
||||||
|
/* FIXME: check v.len + len < 256MB */
|
||||||
|
v = htx_get_blk_value(htx, tailblk);
|
||||||
|
|
||||||
|
/* Append data and update the block itself */
|
||||||
|
memcpy(v.ptr + v.len, data.ptr, len);
|
||||||
|
htx_set_blk_value_len(tailblk, v.len + len);
|
||||||
|
|
||||||
|
/* Update HTTP message */
|
||||||
|
htx->data += len;
|
||||||
|
return len;
|
||||||
|
|
||||||
|
add_new_block:
|
||||||
|
/* FIXME: check tlr.len (< 256MB) */
|
||||||
|
blk = htx_add_blk(htx, HTX_BLK_DATA, len);
|
||||||
|
if (!blk)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
blk->info += len;
|
||||||
|
memcpy(htx_get_blk_ptr(htx, blk), data.ptr, len);
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adds an HTX block of type TLR in <htx>. It returns the new block on
|
/* Adds an HTX block of type TLR in <htx>. It returns the new block on
|
||||||
|
Loading…
Reference in New Issue
Block a user