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= \
main.c.o \
vec.c.o \
cpucount.c.o \
base32_to.c.o \
base32_from.c.o \

66
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 ^ 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

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; \
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); \