]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ncbuf2: implement iterator bitmap utilities functions
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 16 Oct 2025 15:34:10 +0000 (17:34 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 17 Oct 2025 07:29:01 +0000 (09:29 +0200)
src/ncbuf2.c

index ba83ce8b2631430a14854c79a6e238e302a5ff0a..0cea43d01d528285b27ebfcfd9cbe8f14a7972fb 100644 (file)
@@ -2,6 +2,87 @@
 
 #include <string.h>
 
+/* ******** internal API ******** */
+
+struct itbmap {
+       char *b;
+       ncb2_sz_t off;
+       unsigned char mask;
+       unsigned char bitcount;
+};
+
+static int itbmap_is_full(const struct itbmap *it)
+{
+       if (!it->b)
+               return 0;
+
+       return (*it->b & it->mask) == it->mask;
+}
+
+static void itbmap_load(struct itbmap *it, ncb2_sz_t off,
+                         const struct ncbuf2 *buf)
+{
+       const ncb2_sz_t sz = ncb2_size(buf);
+       ncb2_sz_t off_abs;
+       ncb2_sz_t off_bmap;
+
+       off_abs = buf->head + off;
+       if (off_abs >= sz)
+               off_abs -= sz;
+       off_bmap = off_abs / 8;
+       BUG_ON_HOT(off_bmap >= buf->bitmap_sz);
+
+       it->b = buf->bitmap + off_bmap;
+       it->off = off;
+       it->mask = 0xff;
+       it->bitcount = 8;
+
+       if (off_bmap == buf->bitmap_sz - 1 && (sz % 8)) {
+               it->mask <<= 8 - (sz % 8);
+               it->bitcount -= 8 - (sz % 8);
+       }
+
+       if (off_abs % 8) {
+               it->mask &= (0xff >> (off_abs % 8));
+               it->bitcount -= off_abs % 8;
+       }
+
+       if (it->off + it->bitcount > sz) {
+               it->mask &= (0xff << (it->off + it->bitcount - sz));
+               it->bitcount -= it->off + it->bitcount - sz;
+       }
+}
+
+static struct itbmap itbmap_get(const struct ncbuf2 *buf, ncb2_sz_t off)
+{
+       struct itbmap it;
+
+       BUG_ON(off >= ncb2_size(buf));
+
+       itbmap_load(&it, off, buf);
+       return it;
+}
+
+static struct itbmap itbmap_next(const struct ncbuf2 *buf, const struct itbmap *prev)
+{
+       const ncb2_sz_t off_next = prev->off + prev->bitcount;
+       struct itbmap next;
+
+       BUG_ON_HOT(off_next > ncb2_size(buf));
+
+       if (off_next == ncb2_size(buf)) {
+               next.b = NULL;
+               next.off = off_next;
+       }
+       else {
+               itbmap_load(&next, prev->off + prev->bitcount, buf);
+       }
+
+       return next;
+}
+
+/* ******** public API ******** */
+
 struct ncbuf2 ncb2_make(char *area, ncb2_sz_t size, ncb2_sz_t head)
 {
        struct ncbuf2 buf;