mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-21 13:02:55 +00:00
MINOR: htx: Store the head position instead of the wrap one
The head of an HTX message is heavily used whereas the wrap position is only used when a block is added or removed. So it is more logical to store the head position in the HTX message instead of the wrap one. The wrap position can be easily deduced. To get it, the new function htx_get_wrap() may be used.
This commit is contained in:
parent
c8b246f108
commit
28f29c7eea
@ -152,8 +152,8 @@ struct htx {
|
||||
|
||||
uint32_t used; /* number of blocks in use */
|
||||
uint32_t tail; /* last inserted block */
|
||||
uint32_t head; /* older inserted block */
|
||||
uint32_t front; /* block's position of the first content before the blocks table */
|
||||
uint32_t wrap; /* the position were the blocks table wraps, if any */
|
||||
|
||||
uint64_t extra; /* known bytes amount remaining to receive */
|
||||
uint32_t flags; /* HTX_FL_* */
|
||||
@ -345,6 +345,21 @@ static inline uint32_t htx_get_blksz(const struct htx_blk *blk)
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns the wrap position, ie the position where the blocks table wraps.
|
||||
*
|
||||
* An signed 32-bits integer is returned to handle -1 case. Blocks position are
|
||||
* store on unsigned 32-bits integer, but it is impossible to have so much
|
||||
* blocks to overflow a 32-bits signed integer !
|
||||
*/
|
||||
static inline int32_t htx_get_wrap(const struct htx *htx)
|
||||
{
|
||||
if (!htx->used)
|
||||
return -1;
|
||||
return ((htx->tail >= htx->head)
|
||||
? (htx->used + htx->head)
|
||||
: (htx->used - 1) + (htx->head - htx->tail));
|
||||
}
|
||||
|
||||
/* Returns the position of the oldest entry (head).
|
||||
*
|
||||
* An signed 32-bits integer is returned to handle -1 case. Blocks position are
|
||||
@ -353,10 +368,7 @@ static inline uint32_t htx_get_blksz(const struct htx_blk *blk)
|
||||
*/
|
||||
static inline int32_t htx_get_head(const struct htx *htx)
|
||||
{
|
||||
if (!htx->used)
|
||||
return -1;
|
||||
|
||||
return (((htx->tail + 1U < htx->used) ? htx->wrap : 0) + htx->tail + 1U - htx->used);
|
||||
return (htx->used ? htx->head : -1);
|
||||
}
|
||||
|
||||
/* Returns the oldest HTX block (head) if the HTX message is not
|
||||
@ -424,8 +436,10 @@ static inline int32_t htx_get_prev(const struct htx *htx, uint32_t pos)
|
||||
head = htx_get_head(htx);
|
||||
if (head == -1 || pos == head)
|
||||
return -1;
|
||||
if (!pos)
|
||||
return (htx->wrap - 1);
|
||||
if (!pos) {
|
||||
/* htx_get_wrap() is always greater than 1 here */
|
||||
return (htx_get_wrap(htx) - 1);
|
||||
}
|
||||
return (pos - 1);
|
||||
}
|
||||
|
||||
@ -450,14 +464,11 @@ static inline struct htx_blk *htx_get_prev_blk(const struct htx *htx,
|
||||
*/
|
||||
static inline int32_t htx_get_next(const struct htx *htx, uint32_t pos)
|
||||
{
|
||||
if (!htx->used)
|
||||
return -1;
|
||||
|
||||
if (pos == htx->tail)
|
||||
if (!htx->used || pos == htx->tail)
|
||||
return -1;
|
||||
pos++;
|
||||
if (pos >= htx->wrap)
|
||||
pos = 0;
|
||||
if (pos == htx_get_wrap(htx))
|
||||
return 0;
|
||||
return pos;
|
||||
|
||||
}
|
||||
@ -663,7 +674,7 @@ static inline int htx_almost_full(const struct htx *htx)
|
||||
|
||||
static inline void htx_reset(struct htx *htx)
|
||||
{
|
||||
htx->data = htx->used = htx->tail = htx->wrap = htx->front = 0;
|
||||
htx->data = htx->used = htx->tail = htx->head = htx->front = 0;
|
||||
htx->extra = 0;
|
||||
htx->flags = HTX_FL_NONE;
|
||||
htx->sl_off = -1;
|
||||
@ -779,11 +790,10 @@ static inline void htx_dump(struct htx *htx)
|
||||
int32_t pos;
|
||||
|
||||
fprintf(stderr, "htx:%p [ size=%u - data=%u - used=%u - wrap=%s - extra=%llu]\n",
|
||||
htx, htx->size, htx->data, htx->used,
|
||||
(!htx->used || htx->tail+1 == htx->wrap) ? "NO" : "YES",
|
||||
htx, htx->size, htx->data, htx->used, (htx->tail >= htx->head) ? "NO" : "YES",
|
||||
(unsigned long long)htx->extra);
|
||||
fprintf(stderr, "\thead=%d - tail=%u - front=%u - wrap=%u\n",
|
||||
htx_get_head(htx), htx->tail, htx->front, htx->wrap);
|
||||
fprintf(stderr, "\thead=%u, tail=%u - front=%u\n",
|
||||
htx->head, htx->tail, htx->front);
|
||||
|
||||
for (pos = htx_get_head(htx); pos != -1; pos = htx_get_next(htx, pos)) {
|
||||
struct htx_sl *sl;
|
||||
|
@ -68,12 +68,10 @@ int http_find_header(const struct htx *htx, const struct ist name,
|
||||
struct htx_blk *blk = ctx->blk;
|
||||
struct ist n, v;
|
||||
enum htx_blk_type type;
|
||||
uint32_t pos;
|
||||
|
||||
if (blk) {
|
||||
char *p;
|
||||
|
||||
pos = htx_get_blk_pos(htx, blk);
|
||||
if (!ctx->value.ptr)
|
||||
goto rescan_hdr;
|
||||
if (full)
|
||||
@ -96,15 +94,13 @@ int http_find_header(const struct htx *htx, const struct ist name,
|
||||
if (!htx->used)
|
||||
return 0;
|
||||
|
||||
pos = htx_get_head(htx);
|
||||
while (1) {
|
||||
for (blk = htx_get_head_blk(htx); blk; blk = htx_get_next_blk(htx, blk)) {
|
||||
rescan_hdr:
|
||||
blk = htx_get_blk(htx, pos);
|
||||
type = htx_get_blk_type(blk);
|
||||
if (type == HTX_BLK_EOH || type == HTX_BLK_EOM)
|
||||
break;
|
||||
if (type != HTX_BLK_HDR)
|
||||
goto next_blk;
|
||||
continue;
|
||||
if (name.len) {
|
||||
/* If no name was passed, we want any header. So skip the comparison */
|
||||
n = htx_get_blk_name(htx, blk);
|
||||
@ -128,17 +124,13 @@ int http_find_header(const struct htx *htx, const struct ist name,
|
||||
ctx->lws_after++;
|
||||
}
|
||||
if (!v.len)
|
||||
goto next_blk;
|
||||
continue;
|
||||
ctx->blk = blk;
|
||||
ctx->value = v;
|
||||
return 1;
|
||||
|
||||
next_blk:
|
||||
if (pos == htx->tail)
|
||||
break;
|
||||
pos++;
|
||||
if (pos >= htx->wrap)
|
||||
pos = 0;
|
||||
;
|
||||
}
|
||||
|
||||
ctx->blk = NULL;
|
||||
|
50
src/htx.c
50
src/htx.c
@ -42,10 +42,8 @@ struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk)
|
||||
/* start from the head */
|
||||
for (old = htx_get_head(htx); old != -1; old = htx_get_next(htx, old)) {
|
||||
oldblk = htx_get_blk(htx, old);
|
||||
if (htx_get_blk_type(oldblk) == HTX_BLK_UNUSED) {
|
||||
htx->used--;
|
||||
if (htx_get_blk_type(oldblk) == HTX_BLK_UNUSED)
|
||||
continue;
|
||||
}
|
||||
|
||||
newblk = htx_get_blk(tmp, new);
|
||||
newblk->addr = addr;
|
||||
@ -66,8 +64,9 @@ struct htx_blk *htx_defrag(struct htx *htx, struct htx_blk *blk)
|
||||
|
||||
}
|
||||
|
||||
htx->used = new;
|
||||
htx->sl_off = sl_off;
|
||||
htx->wrap = htx->used;
|
||||
htx->head = 0;
|
||||
htx->front = htx->tail = new - 1;
|
||||
memcpy((void *)htx->blocks, (void *)tmp->blocks, htx->size);
|
||||
|
||||
@ -95,8 +94,8 @@ static struct htx_blk *htx_reserve_nxblk(struct htx *htx, uint32_t blksz)
|
||||
|
||||
if (!htx->used) {
|
||||
/* Empty message */
|
||||
htx->front = htx->tail = 0;
|
||||
htx->wrap = htx->used = 1;
|
||||
htx->front = htx->head = htx->tail = 0;
|
||||
htx->used = 1;
|
||||
blk = htx_get_blk(htx, htx->tail);
|
||||
blk->addr = 0;
|
||||
htx->data = blksz;
|
||||
@ -104,10 +103,10 @@ static struct htx_blk *htx_reserve_nxblk(struct htx *htx, uint32_t blksz)
|
||||
}
|
||||
|
||||
used = htx->used + 1;
|
||||
tail = htx->tail + 1;
|
||||
prev = htx->tail;
|
||||
wrap = htx->wrap;
|
||||
head = htx_get_head(htx);
|
||||
head = htx->head;
|
||||
tail = htx->tail + 1;
|
||||
wrap = htx_get_wrap(htx);
|
||||
|
||||
if (tail == wrap) {
|
||||
frtblk = htx_get_blk(htx, htx->front);
|
||||
@ -178,7 +177,6 @@ static struct htx_blk *htx_reserve_nxblk(struct htx *htx, uint32_t blksz)
|
||||
/* need to defragment the table before inserting upfront */
|
||||
htx_defrag(htx, NULL);
|
||||
frtblk = htx_get_blk(htx, htx->front);
|
||||
wrap = htx->wrap + 1;
|
||||
tail = htx->tail + 1;
|
||||
used = htx->used + 1;
|
||||
blk = htx_get_blk(htx, tail);
|
||||
@ -187,7 +185,6 @@ static struct htx_blk *htx_reserve_nxblk(struct htx *htx, uint32_t blksz)
|
||||
}
|
||||
}
|
||||
|
||||
htx->wrap = wrap;
|
||||
htx->tail = tail;
|
||||
htx->used = used;
|
||||
htx->data += blksz;
|
||||
@ -216,7 +213,7 @@ struct htx_blk *htx_add_blk(struct htx *htx, enum htx_blk_type type, uint32_t bl
|
||||
struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk)
|
||||
{
|
||||
enum htx_blk_type type = htx_get_blk_type(blk);
|
||||
uint32_t next, head, pos;
|
||||
uint32_t next, pos, wrap;
|
||||
|
||||
if (type != HTX_BLK_UNUSED) {
|
||||
/* Mark the block as unused, decrement allocated size */
|
||||
@ -228,28 +225,27 @@ struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk)
|
||||
|
||||
/* This is the last block in use */
|
||||
if (htx->used == 1/* || !htx->data */) {
|
||||
htx->front = htx->tail = 0;
|
||||
htx->wrap = htx->used = 0;
|
||||
htx->front = htx->head = htx->tail = 0;
|
||||
htx->used = 0;
|
||||
htx->data = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* There is at least 2 blocks, so tail is always >= 0 */
|
||||
pos = htx_get_blk_pos(htx, blk);
|
||||
head = htx_get_head(htx);
|
||||
blk = NULL;
|
||||
next = pos + 1; /* By default retrun the next block */
|
||||
if (htx->tail + 1 == htx->wrap) {
|
||||
wrap = htx_get_wrap(htx);
|
||||
if (htx->tail + 1 == wrap) {
|
||||
/* The HTTP message doesn't wrap */
|
||||
if (pos == head) {
|
||||
/* remove the head, so just return the new head */
|
||||
if (pos == htx->head) {
|
||||
/* move the head forward */
|
||||
htx->used--;
|
||||
next = htx_get_head(htx);
|
||||
htx->head++;
|
||||
}
|
||||
else if (pos == htx->tail) {
|
||||
/* remove the tail. this was the last inserted block so
|
||||
* return NULL. */
|
||||
htx->wrap--;
|
||||
htx->tail--;
|
||||
htx->used--;
|
||||
goto end;
|
||||
@ -260,17 +256,17 @@ struct htx_blk *htx_remove_blk(struct htx *htx, struct htx_blk *blk)
|
||||
if (pos == htx->tail) {
|
||||
/* remove the tail. try to unwrap the message (pos == 0)
|
||||
* and return NULL. */
|
||||
htx->tail = ((pos == 0) ? htx->wrap-1 : htx->tail-1);
|
||||
htx->tail = ((pos == 0) ? wrap-1 : htx->tail-1);
|
||||
htx->used--;
|
||||
goto end;
|
||||
}
|
||||
else if (pos == head) {
|
||||
/* remove the head, try to unwrap the message (pos+1 ==
|
||||
* wrap) and return the new head */
|
||||
else if (pos == htx->head) {
|
||||
/* move the head forward and try to unwrap the message
|
||||
* (head+1 == wrap) */
|
||||
htx->used--;
|
||||
if (pos + 1 == htx->wrap)
|
||||
htx->wrap = htx->tail + 1;
|
||||
next = htx_get_head(htx);
|
||||
htx->head++;
|
||||
if (htx->head == wrap)
|
||||
htx->head = next = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3295,7 +3295,7 @@ static int stats_dump_full_strm_to_buffer(struct stream_interface *si, struct st
|
||||
chunk_appendf(&trash,
|
||||
" htx=%p flags=0x%x size=%u data=%u used=%u wrap=%s extra=%llu\n",
|
||||
htx, htx->flags, htx->size, htx->data, htx->used,
|
||||
(!htx->used || htx->tail+1 == htx->wrap) ? "NO" : "YES",
|
||||
(htx->tail >= htx->head) ? "NO" : "YES",
|
||||
(unsigned long long)htx->extra);
|
||||
}
|
||||
|
||||
@ -3334,7 +3334,7 @@ static int stats_dump_full_strm_to_buffer(struct stream_interface *si, struct st
|
||||
chunk_appendf(&trash,
|
||||
" htx=%p flags=0x%x size=%u data=%u used=%u wrap=%s extra=%llu\n",
|
||||
htx, htx->flags, htx->size, htx->data, htx->used,
|
||||
(!htx->used || htx->tail+1 == htx->wrap) ? "NO" : "YES",
|
||||
(htx->tail >= htx->head) ? "NO" : "YES",
|
||||
(unsigned long long)htx->extra);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user