mirror of
https://github.com/cathugger/mkp224o.git
synced 2025-04-22 23:09:10 +00:00
proper intfilter expansion, vec improvements
This commit is contained in:
parent
7a090d9ea6
commit
d8c8fba4d2
4 changed files with 111 additions and 52 deletions
|
@ -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
64
main.c
|
@ -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
48
vec.c
Normal 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
48
vec.h
|
@ -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); \
|
||||||
|
|
Loading…
Add table
Reference in a new issue