mirror of
https://github.com/cathugger/mkp224o.git
synced 2025-04-20 13:59:11 +00:00
all filters are loaded fast now
This commit is contained in:
parent
74a2b68648
commit
3bae9caa97
2 changed files with 94 additions and 145 deletions
190
main.c
190
main.c
|
@ -103,57 +103,23 @@ static void filters_init()
|
|||
}
|
||||
|
||||
#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 *))
|
||||
{
|
||||
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
|
||||
* big endian -- 0xFFFFF000
|
||||
|
@ -199,18 +165,6 @@ static inline int bfilter_conflict(struct binfilter *o,struct binfilter *n)
|
|||
* 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) \
|
||||
((init) | ((((j) & (dmask)) | (((j) << (rshift)) & (smask))) << (ishift)))
|
||||
// add expanded set of values
|
||||
|
@ -285,7 +239,48 @@ static inline void ifilter_addflatten(struct intfilter *ifltr,IFT mask)
|
|||
}
|
||||
}
|
||||
|
||||
# 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
|
||||
|
||||
static void filters_add(const char *filter)
|
||||
|
@ -339,76 +334,21 @@ static void filters_add(const char *filter)
|
|||
# ifdef BINSEARCH
|
||||
ifilter_addflatten(&ifltr,mc.i);
|
||||
# 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);
|
||||
# endif // BINSEARCH
|
||||
#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);
|
||||
#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
|
||||
}
|
||||
|
||||
static void filters_prepare()
|
||||
{
|
||||
#ifdef INTFILTER
|
||||
#ifdef BINSEARCH
|
||||
if (!quietflag)
|
||||
fprintf(stderr,"sorting filters...\n");
|
||||
ifilter_sort();
|
||||
// TODO remove dups
|
||||
#endif // BINSEARCH
|
||||
#endif // INTFILTER
|
||||
fprintf(stderr,"sorting filters...");
|
||||
filter_sort(filter_compare);
|
||||
if (!quietflag)
|
||||
fprintf(stderr," done.\n");
|
||||
// TODO remove duplicates
|
||||
}
|
||||
|
||||
static void filters_clean()
|
||||
|
@ -554,14 +494,16 @@ static void filters_print()
|
|||
for (i = 0;i < l;++i) {
|
||||
char buf0[256],buf1[256];
|
||||
u8 bufx[128];
|
||||
#ifdef INTFILTER
|
||||
size_t len = 0;
|
||||
u8 *imraw;
|
||||
|
||||
if (i >= 20) {
|
||||
fprintf(stderr,"[another %llu filters not shown]\n",(unsigned long long)(filters_count() - 20));
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef INTFILTER
|
||||
size_t len = 0;
|
||||
u8 *imraw;
|
||||
|
||||
#ifndef BINSEARCH
|
||||
imraw = (u8 *)&VEC_BUF(ifilters,i).m;
|
||||
#else
|
||||
|
|
35
vec.h
35
vec.h
|
@ -12,53 +12,60 @@ VEC_STRUCT(vec_basestruct,void) ;
|
|||
void vec_add1(struct vec_basestruct *ctl,size_t sz);
|
||||
#define VEC_ADD1(ctl) \
|
||||
vec_add1((struct vec_basestruct *)&(ctl),VEC_ELSIZE(ctl))
|
||||
#define VEC_ADD(ctl,val) { \
|
||||
#define VEC_ADD(ctl,val) \
|
||||
do { \
|
||||
VEC_ADD1(ctl); \
|
||||
(ctl).buf[(ctl).len - 1] = (val); \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
void vec_addn(struct vec_basestruct *ctl,size_t sz,size_t n);
|
||||
#define VEC_ADDN(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; \
|
||||
memmove( \
|
||||
&(ctl).buf[n], \
|
||||
&(ctl).buf[(n) + (m)], \
|
||||
((ctl).len - (n)) * VEC_ELSIZE(ctl)); \
|
||||
}
|
||||
} while (0)
|
||||
#define VEC_REMOVE(ctl,n) VEC_REMOVEN(ctl,n,1)
|
||||
|
||||
#define VEC_INSERT1(ctl,n) { \
|
||||
#define VEC_INSERT1(ctl,n) \
|
||||
do { \
|
||||
VEC_ADD1(ctl); \
|
||||
memmove( \
|
||||
&(ctl).buf[(n) + 1], \
|
||||
&(ctl).buf[n], \
|
||||
((ctl).len - (n) - 1) * VEC_ELSIZE(ctl)); \
|
||||
}
|
||||
#define VEC_INSERT(ctl,n,val) { \
|
||||
} while (0)
|
||||
#define VEC_INSERT(ctl,n,val) \
|
||||
do { \
|
||||
VEC_INSERT1(ctl,n); \
|
||||
(ctl).buf[n] = (val); \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
#define VEC_INSERTN(ctl,n,m) { \
|
||||
#define VEC_INSERTN(ctl,n,m) \
|
||||
do { \
|
||||
VEC_ADDN(ctl,m); \
|
||||
memmove( \
|
||||
&(ctl).buf[(n) + (m)], \
|
||||
&(ctl).buf[n], \
|
||||
((ctl).len - (n) - (m)) * VEC_ELSIZE(ctl)); \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
#define VEC_ZERO(ctl) { \
|
||||
#define VEC_ZERO(ctl) \
|
||||
do { \
|
||||
if ((ctl).buf) \
|
||||
memset((ctl).buf,0,(ctl).len * VEC_ELSIZE(ctl)); \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
#define VEC_FREE(ctl) { \
|
||||
#define VEC_FREE(ctl) \
|
||||
do { \
|
||||
free((ctl).buf); \
|
||||
memset(&(ctl), 0, sizeof(ctl)); \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
#define VEC_LENGTH(ctl) ((ctl).len)
|
||||
#define VEC_BUF(ctl,num) ((ctl).buf[num])
|
||||
|
|
Loading…
Add table
Reference in a new issue