From: Amaury Denoyelle Date: Fri, 1 Jul 2022 12:45:41 +0000 (+0200) Subject: MINOR: ncbuf: implement ncb_is_fragmented() X-Git-Tag: v2.7-dev2~164 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e0a92a7e56b47af8586b303e33eb5ae413a51a9d;p=thirdparty%2Fhaproxy.git MINOR: ncbuf: implement ncb_is_fragmented() 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. --- diff --git a/include/haproxy/ncbuf.h b/include/haproxy/ncbuf.h index b16e10a3bd..5c4a4ea49d 100644 --- a/include/haproxy/ncbuf.h +++ b/include/haproxy/ncbuf.h @@ -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); diff --git a/src/ncbuf.c b/src/ncbuf.c index adb32b57a9..d2e17fef47 100644 --- a/src/ncbuf.c +++ b/src/ncbuf.c @@ -488,6 +488,24 @@ int ncb_is_full(const struct ncbuf *buf) return first_data == ncb_size(buf); } +/* Returns true if 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 starting at offset * 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);