From d8c8fba4d27ba9f8d8c9bcf194f291c4c67577cf Mon Sep 17 00:00:00 2001 From: cathugger Date: Mon, 9 Oct 2017 20:00:02 +0000 Subject: [PATCH] proper intfilter expansion, vec improvements --- Makefile.in | 1 + main.c | 66 +++++++++++++++++++++++++++++++++++++++-------------- vec.c | 48 ++++++++++++++++++++++++++++++++++++++ vec.h | 48 +++++++++++--------------------------- 4 files changed, 111 insertions(+), 52 deletions(-) create mode 100644 vec.c diff --git a/Makefile.in b/Makefile.in index 28845d7..2b04b6d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -19,6 +19,7 @@ ED25519OBJ= $(ED25519_@ED25519IMPL@) MAINOBJ= \ main.c.o \ + vec.c.o \ cpucount.c.o \ base32_to.c.o \ base32_from.c.o \ diff --git a/main.c b/main.c index 6f5ad03..43d3c2e 100644 --- a/main.c +++ b/main.c @@ -187,12 +187,6 @@ static inline int bfilter_conflict(struct binfilter *o,struct binfilter *n) * 0xFFffFF0f ^ 0xFFffFF00 -> 0x0000000f <- direct mask * 0xFFffFF0f ^ 0x0000000f -> 0xFFffFF00 <- shifted mask * - * above method doesn't work in some cases. better way: - * l: 0x80ffFFff ^ 0x00f0FFff -> 0x800f0000 - * 0x800f0000 >> 16 -> 0x0000800f - * 0x0000800f + 1 -> 0x00008010 - * 0x0000800f & 0x00008010 -> 0x00008000 <- smask - * 0x0000800f ^ 0x00008000 -> 0x0000000f <- dmask * essentially, we have to make direct mask + shifted mask bits worth of information * and then split it into 2 parts * we do not need absolute shifted mask shifting value, just relative to direct mask @@ -203,25 +197,51 @@ static inline int bfilter_conflict(struct binfilter *o,struct binfilter *n) * for each value, realmask <- (val & 0x000000dd) | ((val & 0x000sss00) << relshiftval) * or.. * realmask <- (val & 0x000000dd) | ((val << relshiftval) & 0x0sss0000) + * ... + * above method doesn't work in some cases. better way: + * l: 0x80ffFFff ^ 0x00f0FFff -> 0x800f0000 + * 0x800f0000 >> 16 -> 0x0000800f + * 0x0000800f + 1 -> 0x00008010 + * 0x0000800f & 0x00008010 -> 0x00008000 <- smask + * 0x0000800f ^ 0x00008000 -> 0x0000000f <- dmask */ -// add flattened set of values -static void ifilter_addflattened( +// add expanded set of values +// space for that must already be allocated +static void ifilter_addexpanded( size_t n,struct intfilter *ifltr, IFT dmask,IFT smask,IFT cmask, int ishift,int rshift) { for (size_t j = 0;;++j) { - VEC_BUF(ifilters,n + j).f = ifltr->f | (((j & dmask) | ((j << rshift) & smask)) << ishift); + VEC_BUF(ifilters,n + j).f = + ifltr->f | (((j & dmask) | ((j << rshift) & smask)) << ishift); if (j == cmask) break; } } -// flatten existing stuff -static void ifilter_flatten(IFT dmask,IFT smask,IFT cmask,int ishift,int rshift) +// expand existing stuff +// allocates needed stuff on its own +static void ifilter_expand(IFT dmask,IFT smask,IFT cmask,int ishift,int rshift) { - + size_t len = VEC_LENGTH(ifilters); + printf(">expand:cm:%08X,len:%d,cm*len:%d\n", + cmask,(int)len,(int)(cmask * len)); + VEC_ADDN(ifilters,cmask * len); + printf(">expand after\n"); + size_t esz = cmask + 1; // size of expanded elements + for (size_t i = len - 1;;--i) { + for (IFT j = 0;;++j) { + VEC_BUF(ifilters,i * esz + j).f = + VEC_BUF(ifilters,i).f | + (((j & dmask) | ((j << rshift) & smask)) << ishift); + if (j == cmask) + break; + } + if (i == 0) + break; + } } static inline void ifilter_addflatten(struct intfilter *ifltr,IFT mask) @@ -267,22 +287,34 @@ static inline void ifilter_addflatten(struct intfilter *ifltr,IFT mask) // preparations done if (ifiltermask > mask) { // already existing stuff has more precise mask than we - // so we need to flatten our stuff + // so we need to expand our stuff // first find where we should insert VEC_FOR(ifilters,i) { if (VEC_BUF(ifilters,i).f > ifltr->f) { // there VEC_INSERTN(ifilters,i,cmask + 1); - ifilter_addflattened(i,ifltr,dmask,smask,cmask,ishift,rshift); + ifilter_addexpanded(i,ifltr,dmask,smask,cmask,ishift,rshift); return; } } size_t i = VEC_LENGTH(ifilters); VEC_ADDN(ifilters,cmask + 1); - ifilter_addflattened(i,ifltr,dmask,smask,cmask,ishift,rshift); - return; + ifilter_addexpanded(i,ifltr,dmask,smask,cmask,ishift,rshift); + } + else { + // adjust existing mask + ifiltermask = mask; + // already existing stuff needs to be expanded + ifilter_expand(dmask,smask,cmask,ishift,rshift); + // now just insert our stuff in the right place + VEC_FOR(ifilters,i) { + if (VEC_BUF(ifilters,i).f > ifltr->f) { + VEC_INSERT(ifilters,i,*ifltr); + return; + } + } + VEC_ADD(ifilters,*ifltr); } - assert(0); } #endif // BINSEARCH #endif // INTFILTER diff --git a/vec.c b/vec.c new file mode 100644 index 0000000..634bed6 --- /dev/null +++ b/vec.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include "vec.h" + +void vec_add1(struct vec_basestruct *ctl,size_t sz) +{ + if (!ctl->alen) { + ctl->alen = 8; + if (SIZE_MAX / 8 < sz) + ctl->alen = 1; + ctl->buf = malloc(ctl->alen * sz); + if (!ctl->buf) + abort(); + } else if (ctl->len >= ctl->alen) { + ctl->alen *= 2; + if (SIZE_MAX / ctl->alen < sz) + abort(); + ctl->buf = realloc(ctl->buf,ctl->alen * sz); + if (!ctl->buf) + abort(); + } + ++ctl->len; +} + +void vec_addn(struct vec_basestruct *ctl,size_t sz,size_t n) +{ + if (!ctl->alen) + ctl->alen = 8; + size_t nlen = ctl->alen; + ctl->len += n; + while (ctl->len > nlen) + nlen *= 2; + if (nlen > ctl->alen) { + ctl->alen = nlen; + if (SIZE_MAX / nlen < sz) + abort(); + ctl->buf = realloc(ctl->buf,nlen * sz); + if (!ctl->buf) + abort(); + } else if (!ctl->buf) { + if (SIZE_MAX / ctl->alen < sz) + abort(); + ctl->buf = malloc(ctl->alen * sz); + if (!ctl->buf) + abort(); + } +} diff --git a/vec.h b/vec.h index c8bf51c..c6db384 100644 --- a/vec.h +++ b/vec.h @@ -3,45 +3,21 @@ struct typename { \ inttype *buf; \ size_t len, alen; \ } +VEC_STRUCT(vec_basestruct,void) ; #define VEC_INIT(ctl) memset(&ctl,0,sizeof(ctl)) -#define VEC_ADD1(ctl) { \ - if (!(ctl).alen) { \ - (ctl).alen = 8; \ - (ctl).buf = malloc(8 * sizeof(*(ctl).buf)); \ - } else if ((ctl).len >= (ctl).alen) { \ - (ctl).alen *= 2; \ - (ctl).buf = realloc((ctl).buf,(ctl).alen * sizeof(*(ctl).buf)); \ - } \ - ++(ctl).len; \ -} - +void vec_add1(struct vec_basestruct *ctl,size_t sz); +#define VEC_ADD1(ctl) \ + vec_add1((struct vec_basestruct *)&(ctl),sizeof(*(ctl).buf)) #define VEC_ADD(ctl,val) { \ - if (!(ctl).alen) { \ - (ctl).alen = 8; \ - (ctl).buf = malloc(8 * sizeof(*(ctl).buf)); \ - } else if ((ctl).len >= (ctl).alen) { \ - (ctl).alen *= 2; \ - (ctl).buf = realloc((ctl).buf,(ctl).alen * sizeof(*(ctl).buf)); \ - } \ - (ctl).buf[(ctl).len++] = (val); \ + VEC_ADD1(ctl); \ + (ctl).buf[(ctl).len - 1] = (val); \ } -#define VEC_ADDN(ctl,n) { \ - if (!(ctl).alen) { \ - (ctl).alen = 8; \ - (ctl).buf = malloc(8 * sizeof(*(ctl).buf)); \ - } \ - size_t nlen = (ctl).alen; \ - while ((ctl).len + n > nlen) \ - nlen *= 2; \ - if (nlen > (ctl).alen) { \ - (ctl).alen = nlen; \ - (ctl).buf = realloc((ctl).buf,nlen * sizeof(*(ctl).buf)); \ - } \ - (ctl).len += n; \ -} +void vec_addn(struct vec_basestruct *ctl,size_t sz,size_t n); +#define VEC_ADDN(ctl,n) \ + vec_addn((struct vec_basestruct *)&(ctl),sizeof(*(ctl).buf),(n)) #define VEC_REMOVE(ctl,n) { \ --(ctl).len; \ @@ -72,8 +48,10 @@ struct typename { \ ((ctl).len - (n) - (m)) * sizeof(*(ctl).buf)); \ } -#define VEC_ZERO(ctl) \ - memset((ctl).buf,0,(ctl).len * sizeof(*(ctl).buf)) +#define VEC_ZERO(ctl) { \ + if ((ctl).buf) \ + memset((ctl).buf,0,(ctl).len * sizeof(*(ctl).buf)); \ +} #define VEC_FREE(ctl) { \ free((ctl).buf); \