diff --git a/Makefile b/Makefile index 88c7548e8..59b706ec3 100644 --- a/Makefile +++ b/Makefile @@ -999,7 +999,7 @@ OBJS += src/mux_h2.o src/mux_h1.o src/mux_fcgi.o src/log.o \ src/ebsttree.o src/freq_ctr.o src/systemd.o src/init.o \ src/http_acl.o src/dict.o src/dgram.o src/pipe.o \ src/hpack-huff.o src/hpack-enc.o src/ebtree.o src/hash.o \ - src/httpclient_cli.o src/version.o + src/httpclient_cli.o src/version.o src/ncbmbuf.o ifneq ($(TRACE),) OBJS += src/calltrace.o diff --git a/include/haproxy/ncbmbuf-t.h b/include/haproxy/ncbmbuf-t.h new file mode 100644 index 000000000..19cef2e16 --- /dev/null +++ b/include/haproxy/ncbmbuf-t.h @@ -0,0 +1,32 @@ +#ifndef _HAPROXY_NCBMBUF_T_H +#define _HAPROXY_NCBMBUF_T_H + +#include + +/* Non-contiguous bitmap buffer + * + * This module is an alternative implementation to ncbuf type. Its main + * difference is that filled blocks and gaps are encoded via a bitmap. + * + * The main advantage of the bitmap is that contrary to ncbuf type there is no + * limitation on the minimal size of gaps. Thus, operation such as add and + * advance are guaranteed to succeed. + * + * Storage is reserved for the bitmap at the end of the buffer area, + * representing roughly 1/9 of the total space. Thus, usable buffer storage is + * smaller than the default ncbuf type. + */ + +#define NCBMBUF_NULL ((struct ncbmbuf){ }) + +struct ncbmbuf { + char *area; /* allocated area used for both data and bitmap storage */ + unsigned char *bitmap; /* bitmap storage located at the end of allocated area */ + + ncb_sz_t size; /* size usable for data storage */ + ncb_sz_t size_bm; /* size of bitmap storage */ + + ncb_sz_t head; +}; + +#endif /* _HAPROXY_NCBMBUF_T_H */ diff --git a/include/haproxy/ncbmbuf.h b/include/haproxy/ncbmbuf.h new file mode 100644 index 000000000..711985023 --- /dev/null +++ b/include/haproxy/ncbmbuf.h @@ -0,0 +1,27 @@ +#ifndef _HAPROXY_NCBMBUF_H +#define _HAPROXY_NCBMBUF_H + +#include + +static inline int ncbmb_is_null(const struct ncbmbuf *buf) +{ + return buf->size == 0; +} + +void ncbmb_init(struct ncbmbuf *buf, ncb_sz_t head); +struct ncbmbuf ncbmb_make(char *area, ncb_sz_t size, ncb_sz_t head); + +/* Returns the usable size of for data storage. This is the size of the + * allocated buffer without the bitmap space. + */ +static inline ncb_sz_t ncbmb_size(const struct ncbmbuf *buf) +{ + if (ncbmb_is_null(buf)) + return 0; + + return buf->size; +} + +int ncbmb_is_empty(const struct ncbmbuf *buf); + +#endif /* _HAPROXY_NCBMBUF_H */ diff --git a/src/ncbmbuf.c b/src/ncbmbuf.c new file mode 100644 index 000000000..c268d14ff --- /dev/null +++ b/src/ncbmbuf.c @@ -0,0 +1,101 @@ +#include + +#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 */ + +/* Initialize or reset by clearing all data. Its size is untouched. + * Buffer is positioned to offset. Use 0 to realign it. must not + * be NCBUF_NULL. + */ +void ncbmb_init(struct ncbmbuf *buf, ncb_sz_t head) +{ + BUG_ON_HOT(ncbmb_is_null(buf)); + + BUG_ON_HOT(head >= buf->size); + buf->head = head; + memset(buf->bitmap, 0, buf->size_bm); +} + +/* Construct a ncbmbuf with all its parameters. */ +struct ncbmbuf ncbmb_make(char *area, ncb_sz_t size, ncb_sz_t head) +{ + struct ncbmbuf buf; + ncb_sz_t size_bm; + + size_bm = (size + 8) / 9; + + buf.area = area; + buf.bitmap = (unsigned char *)area + size - size_bm; + buf.size = size - size_bm; + buf.size_bm = size_bm; + buf.head = head; + + memset(area, 0, size); + + return buf; +} + +ncb_sz_t ncbmb_total_data(const struct ncbmbuf *buf) +{ + /* TODO */ + return 0; +} + +/* Returns true if there is no data anywhere in . */ +int ncbmb_is_empty(const struct ncbmbuf *buf) +{ + size_t i = 0; + + if (ncbmb_is_null(buf)) + return 1; + + for (i = 0; i < buf->size_bm; ++i) { + if (buf->bitmap[i]) + return 0; + } + + return 1; +} + +int ncbmb_is_full(const struct ncbmbuf *buf) +{ + /* TODO */ + return 0; +} + +int ncbmb_is_fragmented(const struct ncbmbuf *buf) +{ + /* TODO */ + return 0; +} + +ncb_sz_t ncbmb_data(const struct ncbmbuf *buf, ncb_sz_t off) +{ + /* TODO */ + return 0; +} + +enum ncb_ret ncbmb_add(struct ncbmbuf *buf, ncb_sz_t off, + const char *data, ncb_sz_t len, enum ncb_add_mode mode) +{ + /* TODO */ + return NCB_RET_OK; +} + +enum ncb_ret ncbmb_advance(struct ncbmbuf *buf, ncb_sz_t adv) +{ + /* TODO */ + return NCB_RET_OK; +}