From: Amaury Denoyelle Date: Thu, 16 Oct 2025 15:34:10 +0000 (+0200) Subject: MINOR: ncbmbuf: implement iterator bitmap utilities functions X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=95d40940cdf5198fd72dd74fc40566cd1aabc121;p=thirdparty%2Fhaproxy.git MINOR: ncbmbuf: implement iterator bitmap utilities functions --- diff --git a/include/haproxy/ncbmbuf-t.h b/include/haproxy/ncbmbuf-t.h index 518a3ffe4..5975e0b1c 100644 --- a/include/haproxy/ncbmbuf-t.h +++ b/include/haproxy/ncbmbuf-t.h @@ -23,6 +23,7 @@ struct ncbmbuf { char *area; char *bitmap; ncb_sz_t size; + ncb_sz_t bitmap_sz; ncb_sz_t head; }; diff --git a/src/ncbmbuf.c b/src/ncbmbuf.c index 8cb61b8a4..5f51b1217 100644 --- a/src/ncbmbuf.c +++ b/src/ncbmbuf.c @@ -2,6 +2,105 @@ #include +#ifdef DEBUG_STRICT +# include +#else +# include +# include + +# 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 offset + * relative to 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 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) {