]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: buffers: implement b_adv() to advance a buffer's pointer
authorWilly Tarreau <w@1wt.eu>
Sat, 5 May 2012 21:32:27 +0000 (23:32 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 8 May 2012 10:28:14 +0000 (12:28 +0200)
This is more convenient and efficient than buf->p = b_ptr(buf, n);
It simply advances the buffer's pointer by <n> and trasfers that
amount of bytes from <in> to <out>. The BF_OUT_EMPTY flag is updated
accordingly.

A few occurrences of such computations in buffers.c and stream_sock.c
were updated to use b_adv(), which resulted in a small code shrink.

include/proto/buffers.h
src/buffers.c
src/stream_sock.c

index 5caff85fb1cef25b920b9f1328c471d9bc1f699f..f82e461d5eacb64c8ab70f013ca6c4f7daaa57f6 100644 (file)
@@ -242,6 +242,19 @@ static inline int buffer_contig_space(const struct buffer *buf)
        return right - left;
 }
 
+/* Advances the buffer by <adv> bytes, which means that the buffer
+ * pointer advances, and that as many bytes from in are transferred
+ * to out. The caller is responsible for ensuring that adv is always
+ * smaller than or equal to b->i. The BF_OUT_EMPTY flag is updated.
+ */
+static inline void b_adv(struct buffer *b, unsigned int adv)
+{
+       b->i -= adv;
+       b->o += adv;
+       if (b->o)
+               b->flags &= ~BF_OUT_EMPTY;
+       b->p = b_ptr(b, adv);
+}
 
 /* Return the amount of bytes that can be written into the buffer at once,
  * excluding the amount of reserved space passed in <res>, which is
index 40aa57a96fa165bfd4df27898562a0651c0a19e4..2bd24a8c549b888dbcf7f6b4e1f9d67425c3be16 100644 (file)
@@ -42,29 +42,26 @@ unsigned long long buffer_forward(struct buffer *buf, unsigned long long bytes)
 {
        unsigned int new_forward;
        unsigned int forwarded;
+       unsigned int bytes32;
 
-       if (!bytes)
-               return 0;
-       if (bytes <= (unsigned long long)buf->i) {
-               buf->p = b_ptr(buf, (unsigned int)bytes);
-               buf->o += bytes;
-               buf->i -= bytes;
-               buf->flags &= ~BF_OUT_EMPTY;
-               return bytes;
+       bytes32 = bytes;
+
+       /* hint: avoid comparisons on long long for the fast case, since if the
+        * length does not fit in an unsigned it, it will never be forwarded at
+        * once anyway.
+        */
+       if (bytes <= ~0U) {
+               if (bytes32 <= buf->i) {
+                       /* OK this amount of bytes might be forwarded at once */
+                       if (!bytes32)
+                               return 0;
+                       b_adv(buf, bytes32);
+                       return bytes;
+               }
        }
 
        forwarded = buf->i;
-       buf->p = bi_end(buf);
-       buf->o += forwarded;
-       buf->i = 0;
-
-       if (buf->o)
-               buf->flags &= ~BF_OUT_EMPTY;
-
-       if (buf->o < buffer_max_len(buf))
-               buf->flags &= ~BF_FULL;
-       else
-               buf->flags |= BF_FULL;
+       b_adv(buf, buf->i);
 
        /* Note: the case below is the only case where we may return
         * a byte count that does not fit into a 32-bit number.
@@ -211,10 +208,7 @@ int buffer_put_block(struct buffer *buf, const char *blk, int len)
                                fwd = buf->to_forward;
                        buf->to_forward -= fwd;
                }
-               buf->o += fwd;
-               buf->i -= fwd;
-               buf->p = b_ptr(buf, fwd);
-               buf->flags &= ~BF_OUT_EMPTY;
+               b_adv(buf, fwd);
        }
 
        buf->flags &= ~BF_FULL;
index 038e8c81a100393de5ac0dceb1b90859f498deab..575e24c0bdc664637fcbba7473d749fb47b1b781 100644 (file)
@@ -309,10 +309,7 @@ int stream_sock_read(int fd) {
                                                fwd = b->to_forward;
                                        b->to_forward -= fwd;
                                }
-                               b->o += fwd;
-                               b->i -= fwd;
-                               b->p = b_ptr(b, fwd);
-                               b->flags &= ~BF_OUT_EMPTY;
+                               b_adv(b, fwd);
                        }
 
                        if (fdtab[fd].state == FD_STCONN)