mirror of
https://github.com/cathugger/mkp224o.git
synced 2025-04-22 06:49:09 +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= \
|
||||
main.c.o \
|
||||
vec.c.o \
|
||||
cpucount.c.o \
|
||||
base32_to.c.o \
|
||||
base32_from.c.o \
|
||||
|
|
66
main.c
66
main.c
|
@ -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
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; \
|
||||
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); \
|
||||
|
|
Loading…
Add table
Reference in a new issue