mirror of
https://github.com/cathugger/mkp224o.git
synced 2025-04-19 21:39: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
204
main.c
204
main.c
|
@ -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
35
vec.h
|
@ -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])
|
||||||
|
|
Loading…
Add table
Reference in a new issue