all filters are loaded fast now

This commit is contained in:
cathugger 2017-10-21 21:42:19 +03:00
parent 74a2b68648
commit 3bae9caa97
2 changed files with 94 additions and 145 deletions

204
main.c
View file

@ -103,57 +103,23 @@ static void filters_init()
} }
#ifdef INTFILTER #ifdef INTFILTER
// o - old filter, n - new
// return -1 - old stays, 0 - no conflict, 1 - new overrides old
// assumes masked bits are cleared already
#ifndef BINSEARCH
static inline int ifilter_conflict(struct intfilter *o,struct intfilter *n)
{
if ((o->f & n->m) != (n->f & o->m))
return 0;
// determine which filter contain less bits
if (o->m <= n->m)
return -1;
return 1;
}
#endif // BINSEARCH
#else // INTFILTER
// o - old filter, n - new
// return: -1 - old stays, 0 - no conflict, 1 - new overrides old
// assumes irrelevant bits are cleared already
static inline int bfilter_conflict(struct binfilter *o,struct binfilter *n)
{
for (size_t i = 0;i < sizeof(o->f);++i) {
u8 oo,nn;
if (i < n->len)
oo = o->f[i];
else if (i == n->len)
oo = o->f[i] & n->mask;
else
oo = 0;
if (i < o->len)
nn = n->f[i];
else if (i == o->len)
nn = n->f[i] & o->mask;
else
nn = 0;
if (oo != nn)
return 0;
}
// functional filters subset was the same
// determine which filter contain less bits
if (o->len < n->len)
return -1;
if (o->len > n->len)
return 1;
if (o->mask <= n->mask)
return -1;
return 1;
}
#endif
#ifdef INTFILTER static void filter_sort(int (*compf)(const void *,const void *))
#ifdef BINSEARCH {
qsort(&VEC_BUF(ifilters,0),VEC_LENGTH(ifilters),sizeof(struct intfilter),compf);
}
# ifdef BINSEARCH
static int filter_compare(const void *p1,const void *p2)
{
if (((const struct intfilter *)p1)->f < ((const struct intfilter *)p2)->f)
return -1;
if (((const struct intfilter *)p1)->f > ((const struct intfilter *)p2)->f)
return 1;
return 0;
}
/* /*
* raw representation -- FF.FF.F0.00 * raw representation -- FF.FF.F0.00
* big endian -- 0xFFFFF000 * big endian -- 0xFFFFF000
@ -199,18 +165,6 @@ static inline int bfilter_conflict(struct binfilter *o,struct binfilter *n)
* 0x0000800f ^ 0x00008000 -> 0x0000000f <- dmask * 0x0000800f ^ 0x00008000 -> 0x0000000f <- dmask
*/ */
static int ifilter_compare(const void *p1,const void *p2)
{
if (((const struct intfilter *)p1)->f < ((const struct intfilter *)p2)->f) return -1;
if (((const struct intfilter *)p1)->f > ((const struct intfilter *)p2)->f) return 1;
return 0;
}
static void ifilter_sort()
{
qsort(&VEC_BUF(ifilters,0),VEC_LENGTH(ifilters),sizeof(struct intfilter),ifilter_compare);
}
#define EXPVAL(init,j,dmask,smask,ishift,rshift) \ #define EXPVAL(init,j,dmask,smask,ishift,rshift) \
((init) | ((((j) & (dmask)) | (((j) << (rshift)) & (smask))) << (ishift))) ((init) | ((((j) & (dmask)) | (((j) << (rshift)) & (smask))) << (ishift)))
// add expanded set of values // add expanded set of values
@ -285,7 +239,48 @@ static inline void ifilter_addflatten(struct intfilter *ifltr,IFT mask)
} }
} }
#endif // BINSEARCH # else // BINSEARCH
/*
* struct intfilter layout: filter,mask
* stuff is compared in big-endian way, so memcmp
* filter needs to be compared first
* if its equal, mask needs to be compared
* memcmp is aplicable there too
* due to struct intfilter layout, it all can be stuffed into one memcmp call
*/
static int filter_compare(const void *p1,const void *p2)
{
return memcmp(p1,p2,sizeof(struct intfilter));
}
# endif // BINSEARCH
#else // INTFILTER
static void filter_sort(int (*compf)(const void *,const void *))
{
qsort(&VEC_BUF(bfilters,0),VEC_LENGTH(bfilters),sizeof(struct binfilter),compf);
}
static int filter_compare(const void *p1,const void *p2)
{
const struct binfilter *b1 = (const struct binfilter *)p1;
const struct binfilter *b2 = (const struct binfilter *)p2;
size_t l = b1->len <= b2->len ? b1->len : b2->len;
int cmp = memcmp(b1->f,b2->f,l);
if (cmp)
return cmp;
if (b1->len < b2->len)
return -1;
if (b1->len > b2->len)
return 1;
if (b1->mask < b2->mask)
return -1;
if (b1->mask > b2->mask)
return 1;
return 0;
}
#endif // INTFILTER #endif // INTFILTER
static void filters_add(const char *filter) static void filters_add(const char *filter)
@ -332,83 +327,28 @@ static void filters_add(const char *filter)
fc.i &= mc.i; fc.i &= mc.i;
struct intfilter ifltr = { struct intfilter ifltr = {
.f = fc.i, .f = fc.i,
#ifndef BINSEARCH # ifndef BINSEARCH
.m = mc.i, .m = mc.i,
#endif # endif
}; };
#ifdef BINSEARCH # ifdef BINSEARCH
ifilter_addflatten(&ifltr,mc.i); ifilter_addflatten(&ifltr,mc.i);
#else // BINSEARCH # else // BINSEARCH
VEC_FOR(ifilters,i) {
int c;
c = ifilter_conflict(&VEC_BUF(ifilters,i),&ifltr);
if (c < 0)
return; // old filter eats us
else if (c > 0) {
VEC_REMOVE(ifilters,i);
--i;
// we eat old filter
}
}
VEC_FOR(ifilters,i) {
// filter with least bits first
if (VEC_BUF(ifilters,i).m > ifltr.m) {
VEC_INSERT(ifilters,i,ifltr);
return;
}
}
VEC_ADD(ifilters,ifltr); VEC_ADD(ifilters,ifltr);
#endif // BINSEARCH # endif // BINSEARCH
#else // INTFILTER #else // INTFILTER
VEC_FOR(bfilters,i) {
int c = bfilter_conflict(&VEC_BUF(bfilters,i),&bf);
if (c < 0)
return; // old filter eats us
else if (c > 0) {
VEC_REMOVE(bfilters,i);
--i;
// we eat old filter
}
}
#ifdef BINSEARCH
VEC_FOR(bfilters,i) {
/*
* mask is irrelevant, as they're not
* conflicting and have proper order
* (unlike when using little endian words)
*/
if (memcmp(VEC_BUF(bfilters,i).f,bf.f,sizeof(bf.f)) > 0) {
VEC_INSERT(bfilters,i,bf);
return;
}
}
VEC_ADD(bfilters,bf); VEC_ADD(bfilters,bf);
#else
VEC_FOR(bfilters,i) {
// filter with least bits first
if (VEC_BUF(bfilters,i).len > bf.len ||
(VEC_BUF(bfilters,i).len == bf.len &&
(VEC_BUF(bfilters,i).mask > bf.mask)))
{
VEC_INSERT(bfilters,i,bf);
return;
}
}
VEC_ADD(bfilters,bf);
#endif // BINSEARCH
#endif // INTFILTER #endif // INTFILTER
} }
static void filters_prepare() static void filters_prepare()
{ {
#ifdef INTFILTER
#ifdef BINSEARCH
if (!quietflag) if (!quietflag)
fprintf(stderr,"sorting filters...\n"); fprintf(stderr,"sorting filters...");
ifilter_sort(); filter_sort(filter_compare);
// TODO remove dups if (!quietflag)
#endif // BINSEARCH fprintf(stderr," done.\n");
#endif // INTFILTER // TODO remove duplicates
} }
static void filters_clean() static void filters_clean()
@ -554,14 +494,16 @@ static void filters_print()
for (i = 0;i < l;++i) { for (i = 0;i < l;++i) {
char buf0[256],buf1[256]; char buf0[256],buf1[256];
u8 bufx[128]; u8 bufx[128];
#ifdef INTFILTER
size_t len = 0;
u8 *imraw;
if (i >= 20) { if (i >= 20) {
fprintf(stderr,"[another %llu filters not shown]\n",(unsigned long long)(filters_count() - 20)); fprintf(stderr,"[another %llu filters not shown]\n",(unsigned long long)(filters_count() - 20));
break; break;
} }
#ifdef INTFILTER
size_t len = 0;
u8 *imraw;
#ifndef BINSEARCH #ifndef BINSEARCH
imraw = (u8 *)&VEC_BUF(ifilters,i).m; imraw = (u8 *)&VEC_BUF(ifilters,i).m;
#else #else

35
vec.h
View file

@ -12,53 +12,60 @@ VEC_STRUCT(vec_basestruct,void) ;
void vec_add1(struct vec_basestruct *ctl,size_t sz); void vec_add1(struct vec_basestruct *ctl,size_t sz);
#define VEC_ADD1(ctl) \ #define VEC_ADD1(ctl) \
vec_add1((struct vec_basestruct *)&(ctl),VEC_ELSIZE(ctl)) vec_add1((struct vec_basestruct *)&(ctl),VEC_ELSIZE(ctl))
#define VEC_ADD(ctl,val) { \ #define VEC_ADD(ctl,val) \
do { \
VEC_ADD1(ctl); \ VEC_ADD1(ctl); \
(ctl).buf[(ctl).len - 1] = (val); \ (ctl).buf[(ctl).len - 1] = (val); \
} } while (0)
void vec_addn(struct vec_basestruct *ctl,size_t sz,size_t n); void vec_addn(struct vec_basestruct *ctl,size_t sz,size_t n);
#define VEC_ADDN(ctl,n) \ #define VEC_ADDN(ctl,n) \
vec_addn((struct vec_basestruct *)&(ctl),VEC_ELSIZE(ctl),(n)) vec_addn((struct vec_basestruct *)&(ctl),VEC_ELSIZE(ctl),(n))
#define VEC_REMOVEN(ctl,n,m) { \ #define VEC_REMOVEN(ctl,n,m) \
do { \
(ctl).len -= m; \ (ctl).len -= m; \
memmove( \ memmove( \
&(ctl).buf[n], \ &(ctl).buf[n], \
&(ctl).buf[(n) + (m)], \ &(ctl).buf[(n) + (m)], \
((ctl).len - (n)) * VEC_ELSIZE(ctl)); \ ((ctl).len - (n)) * VEC_ELSIZE(ctl)); \
} } while (0)
#define VEC_REMOVE(ctl,n) VEC_REMOVEN(ctl,n,1) #define VEC_REMOVE(ctl,n) VEC_REMOVEN(ctl,n,1)
#define VEC_INSERT1(ctl,n) { \ #define VEC_INSERT1(ctl,n) \
do { \
VEC_ADD1(ctl); \ VEC_ADD1(ctl); \
memmove( \ memmove( \
&(ctl).buf[(n) + 1], \ &(ctl).buf[(n) + 1], \
&(ctl).buf[n], \ &(ctl).buf[n], \
((ctl).len - (n) - 1) * VEC_ELSIZE(ctl)); \ ((ctl).len - (n) - 1) * VEC_ELSIZE(ctl)); \
} } while (0)
#define VEC_INSERT(ctl,n,val) { \ #define VEC_INSERT(ctl,n,val) \
do { \
VEC_INSERT1(ctl,n); \ VEC_INSERT1(ctl,n); \
(ctl).buf[n] = (val); \ (ctl).buf[n] = (val); \
} } while (0)
#define VEC_INSERTN(ctl,n,m) { \ #define VEC_INSERTN(ctl,n,m) \
do { \
VEC_ADDN(ctl,m); \ VEC_ADDN(ctl,m); \
memmove( \ memmove( \
&(ctl).buf[(n) + (m)], \ &(ctl).buf[(n) + (m)], \
&(ctl).buf[n], \ &(ctl).buf[n], \
((ctl).len - (n) - (m)) * VEC_ELSIZE(ctl)); \ ((ctl).len - (n) - (m)) * VEC_ELSIZE(ctl)); \
} } while (0)
#define VEC_ZERO(ctl) { \ #define VEC_ZERO(ctl) \
do { \
if ((ctl).buf) \ if ((ctl).buf) \
memset((ctl).buf,0,(ctl).len * VEC_ELSIZE(ctl)); \ memset((ctl).buf,0,(ctl).len * VEC_ELSIZE(ctl)); \
} } while (0)
#define VEC_FREE(ctl) { \ #define VEC_FREE(ctl) \
do { \
free((ctl).buf); \ free((ctl).buf); \
memset(&(ctl), 0, sizeof(ctl)); \ memset(&(ctl), 0, sizeof(ctl)); \
} } while (0)
#define VEC_LENGTH(ctl) ((ctl).len) #define VEC_LENGTH(ctl) ((ctl).len)
#define VEC_BUF(ctl,num) ((ctl).buf[num]) #define VEC_BUF(ctl,num) ((ctl).buf[num])