]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ncbuf: implement ncb_is_fragmented()
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 1 Jul 2022 12:45:41 +0000 (14:45 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 1 Jul 2022 13:54:23 +0000 (15:54 +0200)
Implement a new status function for ncbuf. It allows to quickly report
if a buffer contains data in a fragmented way, i.e. with gaps in between
or at start of the buffer.

To summarize, a buffer is considered as non-fragmented in the following
cases :
- a null or empty buffer
- a full buffer
- a buffer containing exactly one data block at the beginning, following
  by a gap until the end.

include/haproxy/ncbuf.h
src/ncbuf.c

index b16e10a3bd9fc50b8298c63e7362dc9ed60bfa32..5c4a4ea49dce127e7999e62a54f4bbf7b83a0187 100644 (file)
@@ -15,6 +15,7 @@ ncb_sz_t ncb_size(const struct ncbuf *buf);
 ncb_sz_t ncb_total_data(const struct ncbuf *buf);
 int ncb_is_empty(const struct ncbuf *buf);
 int ncb_is_full(const struct ncbuf *buf);
+int ncb_is_fragmented(const struct ncbuf *buf);
 
 ncb_sz_t ncb_data(const struct ncbuf *buf, ncb_sz_t offset);
 
index adb32b57a9d1e1fac84e94be5fc3eccff08345f8..d2e17fef475527d975f9dbddcec9e07934675a95 100644 (file)
@@ -488,6 +488,24 @@ int ncb_is_full(const struct ncbuf *buf)
        return first_data == ncb_size(buf);
 }
 
+/* Returns true if <buf> contains data fragmented by gaps. */
+int ncb_is_fragmented(const struct ncbuf *buf)
+{
+       struct ncb_blk data, gap;
+
+       if (ncb_is_null(buf))
+               return 0;
+
+       /* check if buffer is empty or full */
+       if (ncb_is_empty(buf) || ncb_is_full(buf))
+               return 0;
+
+       /* check that following gap is the last block */
+       data = ncb_blk_first(buf);
+       gap = ncb_blk_next(buf, data);
+       return !ncb_blk_is_last(buf, gap);
+}
+
 /* Returns the number of bytes of data avaiable in <buf> starting at offset
  * <off> until the next gap or the buffer end. The counted data may wrapped if
  * the buffer storage is not aligned.
@@ -833,6 +851,7 @@ static int ncbuf_test(ncb_sz_t head, int reset, int print_delay)
        BUG_ON(ncb_size(&b) != 0);
        BUG_ON(!ncb_is_empty(&b));
        BUG_ON(ncb_is_full(&b));
+       BUG_ON(ncb_is_fragmented(&b));
 
        b.area = (char *)bufarea;
        b.size = bufsize;
@@ -848,15 +867,21 @@ static int ncbuf_test(ncb_sz_t head, int reset, int print_delay)
 
        NCB_INIT(&b); NCB_DATA_EQ(&b, 0, 0);
        NCB_ADD_EQ(&b,  0, data0, 16, NCB_ADD_PRESERVE, NCB_RET_OK); NCB_DATA_EQ(&b, 0, 16);
+       BUG_ON(ncb_is_fragmented(&b));
        NCB_ADD_EQ(&b, 24, data0, 16, NCB_ADD_PRESERVE, NCB_RET_OK); NCB_DATA_EQ(&b, 0, 16);
+       BUG_ON(!ncb_is_fragmented(&b));
        /* insert data overlapping two data blocks and a gap */
        NCB_ADD_EQ(&b, 12, data0, 16, NCB_ADD_PRESERVE, NCB_RET_OK); NCB_DATA_EQ(&b, 0, 40);
+       BUG_ON(ncb_is_fragmented(&b));
 
        NCB_INIT(&b);
        NCB_ADD_EQ(&b, 32, data0, 16, NCB_ADD_PRESERVE, NCB_RET_OK); NCB_DATA_EQ(&b, 0,  0); NCB_DATA_EQ(&b, 16,  0); NCB_DATA_EQ(&b, 32, 16);
+       BUG_ON(!ncb_is_fragmented(&b));
        NCB_ADD_EQ(&b,  0, data0, 16, NCB_ADD_PRESERVE, NCB_RET_OK); NCB_DATA_EQ(&b, 0, 16); NCB_DATA_EQ(&b, 16,  0); NCB_DATA_EQ(&b, 32, 16);
+       BUG_ON(!ncb_is_fragmented(&b));
        /* insert data to exactly cover a gap between two data blocks */
        NCB_ADD_EQ(&b, 16, data0, 16, NCB_ADD_PRESERVE, NCB_RET_OK); NCB_DATA_EQ(&b, 0, 48); NCB_DATA_EQ(&b, 16, 32); NCB_DATA_EQ(&b, 32, 16);
+       BUG_ON(ncb_is_fragmented(&b));
 
        NCB_INIT(&b);
        NCB_ADD_EQ(&b, 0,  data0, 8, NCB_ADD_PRESERVE, NCB_RET_OK);