]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: htx: Store the head position instead of the wrap one
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 30 Apr 2019 15:55:45 +0000 (17:55 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 28 May 2019 05:42:12 +0000 (07:42 +0200)
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.

include/common/htx.h
src/http_htx.c
src/htx.c
src/stream.c

index 78e62a5008671287e855b26b6a3cbe5d6e0f88ec..003680a2b64a1c53c028983b25801f74b3e53423 100644 (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,18 +345,30 @@ static inline uint32_t htx_get_blksz(const struct htx_blk *blk)
        }
 }
 
-/* Returns the position of the oldest entry (head).
+/* 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_head(const struct htx *htx)
+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));
+}
 
-       return (((htx->tail + 1U < htx->used) ? htx->wrap : 0) + htx->tail + 1U - htx->used);
+/* Returns the position of the oldest entry (head).
+ *
+ * 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_head(const struct htx *htx)
+{
+       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;
index 8a407cdff4ea69b695224683cb4deebbf7befcb9..471f1ab8114b368a150d58838e984ef6f89841a0 100644 (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;
index 9deddb15c88d71fbace9967c26f10e0ee12c1cca..9f75f7afa58d70fb7b1ce07170e891518af93e1d 100644 (file)
--- a/src/htx.c
+++ b/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;
                }
        }
 
index 1d2e6ce02b8adbae1e3c88a1d50b5c80b471c78f..e6530343ebd8d86eaafe7347494e84f5c5a2b0e9 100644 (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);
                }