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:
Christopher Faulet 2019-04-30 17:55:45 +02:00 committed by Willy Tarreau
parent c8b246f108
commit 28f29c7eea
4 changed files with 57 additions and 59 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);
}