]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ncbmbuf: 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>
Mon, 20 Oct 2025 09:42:17 +0000 (11:42 +0200)
include/haproxy/ncbmbuf-t.h
src/ncbmbuf.c

index 518a3ffe4965644f16c45c78f9a1a035564b9dc4..5975e0b1c517a87e3ef1726ed26bd664269bb2be 100644 (file)
@@ -23,6 +23,7 @@ struct ncbmbuf {
        char *area;
        char *bitmap;
        ncb_sz_t size;
+       ncb_sz_t bitmap_sz;
        ncb_sz_t head;
 };
 
index 8cb61b8a49314ea2c1f24925edd18f0bc60a8124..5f51b1217e2edb66131802958287987631d139e2 100644 (file)
@@ -2,6 +2,105 @@
 
 #include <string.h>
 
+#ifdef DEBUG_STRICT
+# include <haproxy/bug.h>
+#else
+# include <stdio.h>
+# include <stdlib.h>
+
+# undef  BUG_ON
+# define BUG_ON(x)     if (x) { fprintf(stderr, "CRASH ON %s:%d\n", __func__, __LINE__); abort(); }
+
+# undef  BUG_ON_HOT
+# define BUG_ON_HOT(x) if (x) { fprintf(stderr, "CRASH ON %s:%d\n", __func__, __LINE__); abort(); }
+#endif /* DEBUG_STRICT */
+
+/* ******** internal API ******** */
+
+/* Type representing a bitmap byte. */
+struct itbmap {
+       char *b;
+       ncb_sz_t off;
+       unsigned char mask;
+       unsigned char bitcount;
+};
+
+static __attribute__((unused)) int itbmap_is_full(const struct itbmap *it)
+{
+       if (!it->b)
+               return 0;
+
+       return (*it->b & it->mask) == it->mask;
+}
+
+static __attribute__((unused)) void itbmap_load(struct itbmap *it, ncb_sz_t off,
+                                                const struct ncbmbuf *buf)
+{
+       const ncb_sz_t sz = ncbmb_size(buf);
+       ncb_sz_t off_abs;
+       ncb_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;
+       }
+}
+
+/* Returns an iterator on the bitmap byte corresponding to <off> offset
+ * relative to <buf> head.
+ */
+static __attribute__((unused)) struct itbmap itbmap_get(const struct ncbmbuf *buf, ncb_sz_t off)
+{
+       struct itbmap it;
+
+       BUG_ON(off >= ncbmb_size(buf));
+
+       itbmap_load(&it, off, buf);
+       return it;
+}
+
+/* Returns the next bitmap byte relative to <prev> iterator. */
+static __attribute__((unused)) struct itbmap itbmap_next(const struct ncbmbuf *buf, const struct itbmap *prev)
+{
+       const ncb_sz_t off_next = prev->off + prev->bitcount;
+       struct itbmap next;
+
+       BUG_ON_HOT(off_next > ncbmb_size(buf));
+
+       if (off_next == ncbmb_size(buf)) {
+               next.b = NULL;
+               next.off = off_next;
+       }
+       else {
+               itbmap_load(&next, prev->off + prev->bitcount, buf);
+       }
+
+       return next;
+}
+
+/* ******** public API ******** */
+
 /* Construct a ncbmbuf with all its parameters. */
 struct ncbmbuf ncbmb_make(char *area, ncb_sz_t size, ncb_sz_t head)
 {