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.
diff --git a/include/common/htx.h b/include/common/htx.h
index 78e62a5..003680a 100644
--- a/include/common/htx.h
+++ b/include/common/htx.h
@@ -152,8 +152,8 @@
 
 	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 @@
 	}
 }
 
-/* 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 @@
 	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 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 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 @@
 	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;
diff --git a/src/http_htx.c b/src/http_htx.c
index 8a407cd..471f1ab 100644
--- a/src/http_htx.c
+++ b/src/http_htx.c
@@ -68,12 +68,10 @@
 	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 @@
 	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 @@
 			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;
diff --git a/src/htx.c b/src/htx.c
index 9deddb1..9f75f7a 100644
--- a/src/htx.c
+++ b/src/htx.c
@@ -42,10 +42,8 @@
 	/* 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 @@
 
 	}
 
+	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 @@
 
 	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 @@
 	}
 
 	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 @@
 			/* 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 @@
 		}
 	}
 
-	htx->wrap  = wrap;
 	htx->tail  = tail;
 	htx->used  = used;
 	htx->data += blksz;
@@ -216,7 +213,7 @@
 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 @@
 
 	/* 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 @@
 		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;
 		}
 	}
 
diff --git a/src/stream.c b/src/stream.c
index 1d2e6ce..e653034 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -3295,7 +3295,7 @@
 			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 @@
 			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);
 		}