This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
tango-maat/scanner/ip_matcher/IntervalIndex/ACEI.cpp

431 lines
8.8 KiB
C++
Raw Normal View History

#include <math.h>
#include <string.h>
#include <memory.h>
#include <time.h>
#include "ACEI.h"
ACEI::ACEI(unsigned int eRange):Exp2Size(32)
{
r = int(((unsigned long long)1 << eRange) - 1); //<2F>ں<EFBFBD><DABA><EFBFBD><EFBFBD><EFBFBD>r<EFBFBD><72>ʹ<EFBFBD><CAB9><EFBFBD>о<EFBFBD><D0BE><EFBFBD><EFBFBD>ȼ<EFBFBD>1
}
ACEI::~ACEI()
{
ruin();
}
long long ACEI::PreProcessing(const std::vector<u_int> &a, const std::vector<u_int> &b)
{
if (a.size() != b.size())
return -1;
initQIMatrix();
int i;
for (i = 0; i < (int)a.size(); i++)
{
HQI.ppQImatrix[HQI.rowID][HQI.colID].l = a[i];//be careful
HQI.ppQImatrix[HQI.rowID][HQI.colID].r = b[i]+1;//<2F>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾΪ[, )
HQI.ppQImatrix[HQI.rowID][HQI.colID].index = i;
++HQI.cnt;
//adjust QI matrix begin
HQI.colID = (HQI.colID + 1) % HQI.ROWLEN;
if(HQI.colID == 0)
{
++HQI.rowID;
if(HQI.rowID < HQI.MAXROWS)
{
HQI.ppQImatrix[HQI.rowID] = (_QueryInterval*)malloc(sizeof(_QueryInterval)*HQI.ROWLEN);
}
else
{
printf("Query Interval matrix run over, reminder discard !!!\n");
return 1;
}
}
//adjust end
}
n = HQI.cnt;
init();
return 0;
}
int ACEI::Find(unsigned int key, unsigned int * result, unsigned int size)
{
return searchX(key, result, size);
}
//input & output
void ACEI::initQIMatrix()
{
HQI.MAXROWS = 10000;
HQI.ROWLEN = 1024;
HQI.ppQImatrix = (_QueryInterval**)malloc(sizeof(_QueryInterval*)*HQI.MAXROWS);
HQI.ppQImatrix[0] = (_QueryInterval*)malloc(sizeof(_QueryInterval)*HQI.ROWLEN);
HQI.rowID = 0;
HQI.colID = 0;
HQI.cnt = 0;
}
void ACEI::ruinQIMatirc()
{
int i;
if(HQI.ppQImatrix)
{
for(i = HQI.rowID; i >= 0; i--)
free(HQI.ppQImatrix[i]);
free(HQI.ppQImatrix);
HQI.ppQImatrix = NULL;
}
HQI.rowID = 0;
HQI.colID = 0;
HQI.cnt = 0;
}
//init & ruin
int ACEI::init()
{
u_int i,j,k;
pExp2 = (unsigned long*)malloc(sizeof(unsigned long)*Exp2Size);
for(i = 0; i < Exp2Size; i++) pExp2[i] = (unsigned long)pow((double)2, (double)i);
w = getAvrgRng();
if(n*w>4*r)
{
H = (u_int)ceil((double)log(sqrt((double)w/4))/log((double)2));
h = (u_int)ceil((double)log(sqrt((double)n*w/4/r))/log((double)2));
if(H <= h) H = h+1;
}
else
{
H = (u_int)ceil((double)log(sqrt((double)r/3/n+w/6))/log((double)2));
h = 0;
if(H <= h) H = h+1;
}
L = pExp2[H];
SNum = r/L + 1;
SCEINum = pExp2[h+1];
pTopCEIs = (_CEI*)malloc(sizeof(_CEI)*SNum*SCEINum);
if(!pTopCEIs)
{
printf("Malloc error !!! for pTopCEIs\n");
return -1;
}
memset(pTopCEIs, 0, SNum*SCEINum*sizeof(_CEI));
ppBotCEIs = (_CEI**)malloc(sizeof(_CEI*) * SNum);
if(!ppBotCEIs)
{
printf("Malloc error !!! for ppBotCEIs\n");
return -1;
}
memset(ppBotCEIs, 0, SNum*sizeof(_CEI*));
for (k = 0; k < HQI.cnt; k++)
{
i = k / HQI.ROWLEN;
j = k % HQI.ROWLEN;
addIntvl(HQI.ppQImatrix[i][j].l, HQI.ppQImatrix[i][j].r, &(HQI.ppQImatrix[i][j]));
}
serial();
return 0;
}
void ACEI::ruin()
{
u_int i,j;
free(pExp2);
//releaseCEIs(&pTopCEIs, SNum*SCEINum);
//for (i = 0; i < SNum; i++)
//{
// if (ppBotCEIs[i])
// {
// releaseCEIs(&(ppBotCEIs[i]), L);
// }
//}
//free(ppBotCEIs);
for (i = 0; i < SNum*SCEINum; i++)
if(pTopSrlCEIs[i].head)
free(pTopSrlCEIs[i].head);
free(pTopSrlCEIs);
for (i = 0; i < SNum; i++)
if(ppBotSrlCEIs[i])
{
for (j = 0; j < L; j++)
if(ppBotSrlCEIs[i][j].head)
free(ppBotSrlCEIs[i][j].head);
free(ppBotSrlCEIs[i]);
}
free(ppBotSrlCEIs);
ruinQIMatirc();
}
void ACEI::releaseCEIs(_CEI **ppIIDSet, u_int lCEIsNum)
{
u_int i;
_IID * pTID, * pTIDpre;
for (i = 0; i < lCEIsNum; i++)
{
if(((*ppIIDSet)[i]).head != NULL)
{
for(pTID = ((*ppIIDSet)[i]).head, pTIDpre = NULL; pTID != NULL;)
{
pTIDpre = pTID;
pTID = pTID->next;
free(pTIDpre);
}
}
}
free(*ppIIDSet);
*ppIIDSet = NULL;
}
//search
int ACEI::searchX(unsigned int x, unsigned int * result, unsigned int size)
{
std::vector<u_int> vecui;
u_int sID, uID, dID, lx;
u_int i;
_SrlIID *pIID;
lx = x;
//if(lx >= r) return vecui;
if(lx > r)
return 0;
sID = lx >> H;
dID = lx - (sID << H);
uID = (dID >> (H - h)) + pExp2[h];
//lx = (u_int)floor(x);
//sID = lx / L;
//dID = lx % L;
//uID = dID / pExp2[H-h] + pExp2[h];
//if (fpQueryRslt) fprintf(fpQueryRslt, "%10.6lf\tin ", x);
//else printf("%10.6lf\tin ", x);
unsigned int n = 0;
if(ppBotSrlCEIs[sID] && ppBotSrlCEIs[sID][dID].head != NULL)
{
for (pIID = ppBotSrlCEIs[sID][dID].head; pIID->iid != NULL; pIID++)
{
if(n >= size)
{
return n;
}
result[n++] = pIID->iid->index;
}
}
for (i = 0; i <= h; i++)
{
if (pTopSrlCEIs[sID*SCEINum+uID].head != NULL)
{
for (pIID = pTopSrlCEIs[sID*SCEINum+uID].head; pIID->iid != NULL; pIID++)
{
if(n >= size)
{
return n;
}
result[n++] = pIID->iid->index;
}
}
uID >>= 1;
}
return n;
}
//insert
//void insertIntvl(u_int l, u_int r)
//{
// _QueryInterval * pQI = (_QueryInterval*)malloc(sizeof(_QueryInterval));
// MemCst += sizeof(_QueryInterval);//for stat.
// pQI->l = l;
// pQI->r = r;
// pQI->next = NULL;
// if (HQI.head != NULL)
// {
// HQI.tail->next = pQI;
// HQI.tail = pQI;
// }
// else
// {
// HQI.head = HQI.tail = pQI;
// }
// HQI.len ++;
// addIntvl(l, r, pQI);
//}
void ACEI::addIntvl(u_int ll, u_int lr, _QueryInterval* pQI)//<2F><>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҿ<EFBFBD><D2BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȣ<EFBFBD><C8A3><EFBFBD>ô<EFBFBD><C3B4>Ϊ<EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD><EFBFBD><EFBFBD>
{
unsigned long long lft = ll;
unsigned long long rght = lr;
if (!lr)
rght += ((unsigned long long)1 << 32);
u_int sLID, sRID;
u_int i;
sLID = (u_int)ceil((double)lft/L);
sRID = (u_int)floor((double)rght/L);
if (sLID > sRID) addFrgmnt(ll, lr, sRID, pQI);
else
{
if (sLID < sRID)
{
for(i = sLID; i < sRID; i++) addID(&(pTopCEIs[i*SCEINum+1]), pQI);
}
if (lft < (unsigned long long)sLID * L) addFrgmnt(ll, sLID*L, sLID-1, pQI);
if (rght > (unsigned long long)sRID * L) addFrgmnt(sRID*L, lr, sRID, pQI);
}
}
void ACEI::addFrgmnt(u_int ll, u_int lr, u_int sID, _QueryInterval* pQI)//lr <20><><EFBFBD><EFBFBD>Ϊ0<CEAA><30>ֻҪL<D2AA><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2^32<33><32><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD><EFBFBD>ٳ<EFBFBD><D9B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҷ˵<D2B6><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
u_int lft = ll % L;
u_int rght = lr % L;
u_int sLID, sRID;
u_int i,k;
if(!rght) rght+= L;
sLID = (u_int)ceil((double)lft/pExp2[H-h]);
sRID = (u_int)floor((double)rght/pExp2[H-h]);
if (sLID > sRID) addBtmCEIs(lft, rght, sID, pQI);
else
{
if (lft < sLID * pExp2[H-h]) addBtmCEIs(lft, sLID*pExp2[H-h], sID, pQI);
if (rght > sRID * pExp2[H-h]) addBtmCEIs(sRID*pExp2[H-h], rght, sID, pQI);
if (sLID < sRID)
{
sLID += pExp2[h];
sRID += pExp2[h];
i = 1;
k = sRID - sLID;
while(1)
{
if (sLID % 2 == 0 && i*2 <= k)
{
sLID /= 2;
i *= 2;
}
else
{
addID(&(pTopCEIs[sID*SCEINum+sLID]), pQI);
sLID = sRID + i - k;
k = k - i;
i = 1;
if (k == 0) return;
}
}
}
}
return;
}
void ACEI::addBtmCEIs(u_int ll, u_int lr, u_int sID, _QueryInterval *pQI)
{
u_int i;
if (ppBotCEIs[sID] == NULL && ll < lr)
{
ppBotCEIs[sID] = (_CEI*)malloc(sizeof(_CEI) * L);
memset(ppBotCEIs[sID], 0, sizeof(_CEI)*L);
}
for (i = ll; i < lr; i++)
addID(&(ppBotCEIs[sID][i]), pQI);
}
void ACEI::addID(_CEI* pCEI, _QueryInterval* pQI)
{
_IID *pNewIID = (_IID*)malloc(sizeof(_IID));
pNewIID->iid = pQI;
pNewIID->next = NULL;
if (pCEI->head != NULL)
{
pCEI->tail->next = pNewIID;
pCEI->tail = pNewIID;
}
else
{
pCEI->head = pCEI->tail = pNewIID;
}
}
//ultlity
double ACEI::getAvrgRng()
{
double d = 0;
u_int i,j,k;
if (HQI.cnt == 0)
{
printf("!!! NO QueryISet loaded when calc w\n");
return 0;
}
for (k = 0; k < HQI.cnt; k++)
{
i = k / HQI.ROWLEN;
j = k % HQI.ROWLEN;
d += HQI.ppQImatrix[i][j].r - HQI.ppQImatrix[i][j].l;
}
return d / n;
}
//serialization
void ACEI::serializeCEI(_CEI *pCEI, _SrlCEI* pSrlCEI)//suppose pCEI not NULL
{
u_int i,num = 0;
_IID *pIID;
for(pIID = pCEI->head; pIID; ++num, pIID = pIID->next);
pSrlCEI->head = (_SrlIID*)malloc(sizeof(_SrlIID)*(num+1));
for (i = 0, pIID = pCEI->head; pIID; i++)
{
(pSrlCEI->head)[i].iid = pIID->iid;
pIID = pIID->next;
//free(pIIDpre);
}
((pSrlCEI->head)[num]).iid = NULL;
}
void ACEI::serialBtmCEIs()
{
u_int i,j;
ppBotSrlCEIs = (_SrlCEI**)malloc(sizeof(_SrlCEI*)*SNum);
memset(ppBotSrlCEIs, 0, sizeof(_SrlCEI*)*SNum);
for (i = 0; i < SNum; i++)
{
if (ppBotCEIs[i])
{
ppBotSrlCEIs[i] = (_SrlCEI*)malloc(sizeof(_SrlCEI)*L);
memset(ppBotSrlCEIs[i], 0, sizeof(_SrlCEI)*L);
for (j = 0; j < L; j++)
if (ppBotCEIs[i][j].head)
serializeCEI(&(ppBotCEIs[i][j]), &(ppBotSrlCEIs[i][j]));
else
ppBotSrlCEIs[i][j].head = NULL;
//free(ppBotCEIs[i]);
}
}
//free(ppBotCEIs);
}
void ACEI::serialTopCEIs()
{
u_int i;
pTopSrlCEIs = (_SrlCEI*)malloc(sizeof(_SrlCEI)*SNum*SCEINum);
memset(pTopSrlCEIs, 0, sizeof(_SrlCEI)*SNum*SCEINum);
for (i = 0; i < SNum*SCEINum; i++)
{
if (pTopCEIs[i].head)
serializeCEI(&(pTopCEIs[i]), &(pTopSrlCEIs[i]));
}
//free(pTopCEIs);
}
void ACEI::serial()
{
u_int i;
serialTopCEIs();
serialBtmCEIs();
releaseCEIs(&pTopCEIs, SNum*SCEINum);
for(i = 0; i < SNum; i++)
{
if(ppBotCEIs[i])
releaseCEIs(&(ppBotCEIs[i]), L);
}
free(ppBotCEIs);
}