proper intfilter expansion, vec improvements

This commit is contained in:
cathugger 2017-10-09 20:00:02 +00:00
parent 7a090d9ea6
commit d8c8fba4d2
4 changed files with 111 additions and 52 deletions

View file

@ -19,6 +19,7 @@ ED25519OBJ= $(ED25519_@ED25519IMPL@)
MAINOBJ= \ MAINOBJ= \
main.c.o \ main.c.o \
vec.c.o \
cpucount.c.o \ cpucount.c.o \
base32_to.c.o \ base32_to.c.o \
base32_from.c.o \ base32_from.c.o \

64
main.c
View file

@ -187,12 +187,6 @@ static inline int bfilter_conflict(struct binfilter *o,struct binfilter *n)
* 0xFFffFF0f ^ 0xFFffFF00 -> 0x0000000f <- direct mask * 0xFFffFF0f ^ 0xFFffFF00 -> 0x0000000f <- direct mask
* 0xFFffFF0f ^ 0x0000000f -> 0xFFffFF00 <- shifted 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 * essentially, we have to make direct mask + shifted mask bits worth of information
* and then split it into 2 parts * and then split it into 2 parts
* we do not need absolute shifted mask shifting value, just relative to direct mask * 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) * for each value, realmask <- (val & 0x000000dd) | ((val & 0x000sss00) << relshiftval)
* or.. * or..
* realmask <- (val & 0x000000dd) | ((val << relshiftval) & 0x0sss0000) * 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 // add expanded set of values
static void ifilter_addflattened( // space for that must already be allocated
static void ifilter_addexpanded(
size_t n,struct intfilter *ifltr, size_t n,struct intfilter *ifltr,
IFT dmask,IFT smask,IFT cmask, IFT dmask,IFT smask,IFT cmask,
int ishift,int rshift) int ishift,int rshift)
{ {
for (size_t j = 0;;++j) { 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) if (j == cmask)
break; break;
} }
} }
// flatten existing stuff // expand existing stuff
static void ifilter_flatten(IFT dmask,IFT smask,IFT cmask,int ishift,int rshift) // 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) 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 // preparations done
if (ifiltermask > mask) { if (ifiltermask > mask) {
// already existing stuff has more precise mask than we // 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 // first find where we should insert
VEC_FOR(ifilters,i) { VEC_FOR(ifilters,i) {
if (VEC_BUF(ifilters,i).f > ifltr->f) { if (VEC_BUF(ifilters,i).f > ifltr->f) {
// there // there
VEC_INSERTN(ifilters,i,cmask + 1); 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; return;
} }
} }
size_t i = VEC_LENGTH(ifilters); size_t i = VEC_LENGTH(ifilters);
VEC_ADDN(ifilters,cmask + 1); VEC_ADDN(ifilters,cmask + 1);
ifilter_addflattened(i,ifltr,dmask,smask,cmask,ishift,rshift); 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; return;
} }
assert(0); }
VEC_ADD(ifilters,*ifltr);
}
} }
#endif // BINSEARCH #endif // BINSEARCH
#endif // INTFILTER #endif // INTFILTER

48
vec.c Normal file
View file

@ -0,0 +1,48 @@
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#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();
}
}

48
vec.h
View file

@ -3,45 +3,21 @@ struct typename { \
inttype *buf; \ inttype *buf; \
size_t len, alen; \ size_t len, alen; \
} }
VEC_STRUCT(vec_basestruct,void) ;
#define VEC_INIT(ctl) memset(&ctl,0,sizeof(ctl)) #define VEC_INIT(ctl) memset(&ctl,0,sizeof(ctl))
#define VEC_ADD1(ctl) { \ void vec_add1(struct vec_basestruct *ctl,size_t sz);
if (!(ctl).alen) { \ #define VEC_ADD1(ctl) \
(ctl).alen = 8; \ vec_add1((struct vec_basestruct *)&(ctl),sizeof(*(ctl).buf))
(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; \
}
#define VEC_ADD(ctl,val) { \ #define VEC_ADD(ctl,val) { \
if (!(ctl).alen) { \ VEC_ADD1(ctl); \
(ctl).alen = 8; \ (ctl).buf[(ctl).len - 1] = (val); \
(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); \
} }
#define VEC_ADDN(ctl,n) { \ void vec_addn(struct vec_basestruct *ctl,size_t sz,size_t n);
if (!(ctl).alen) { \ #define VEC_ADDN(ctl,n) \
(ctl).alen = 8; \ vec_addn((struct vec_basestruct *)&(ctl),sizeof(*(ctl).buf),(n))
(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; \
}
#define VEC_REMOVE(ctl,n) { \ #define VEC_REMOVE(ctl,n) { \
--(ctl).len; \ --(ctl).len; \
@ -72,8 +48,10 @@ struct typename { \
((ctl).len - (n) - (m)) * sizeof(*(ctl).buf)); \ ((ctl).len - (n) - (m)) * sizeof(*(ctl).buf)); \
} }
#define VEC_ZERO(ctl) \ #define VEC_ZERO(ctl) { \
memset((ctl).buf,0,(ctl).len * sizeof(*(ctl).buf)) if ((ctl).buf) \
memset((ctl).buf,0,(ctl).len * sizeof(*(ctl).buf)); \
}
#define VEC_FREE(ctl) { \ #define VEC_FREE(ctl) { \
free((ctl).buf); \ free((ctl).buf); \