ipmatcher rule_id -> long long & scanner engine centralization
This commit is contained in:
156
scanner/ip_matcher/IntervalIndex/SuccinctHash.cpp
Normal file
156
scanner/ip_matcher/IntervalIndex/SuccinctHash.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2008--2015
|
||||
* String Algorithms Research Group
|
||||
* Institute of Information Engineering, Chinese Academy of Sciences (IIE-CAS)
|
||||
* National Engineering Laboratory for Information Security Technologies (NELIST)
|
||||
* All rights reserved
|
||||
*
|
||||
* Written by: LIU YANBING (liuyanbing@iie.ac.cn)
|
||||
* Last modification: 2015-12-9
|
||||
*
|
||||
* This code is the exclusive and proprietary property of IIE-CAS and NELIST.
|
||||
* Usage for direct or indirect commercial advantage is not allowed without
|
||||
* written permission from the authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "SuccinctHash.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
static const unsigned long long ONE=1;
|
||||
static const unsigned int B=22695477;
|
||||
|
||||
inline unsigned int myhash(unsigned int key)
|
||||
{
|
||||
//return key;
|
||||
unsigned int h=0;
|
||||
FOR(j, 4)
|
||||
{
|
||||
h=h*B+(key&255);
|
||||
key>>=8;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
CSuccinctHash::CSuccinctHash()
|
||||
{
|
||||
m_RT=NULL;
|
||||
m_kv_array=NULL;
|
||||
m_kv_ptr = NULL;
|
||||
}
|
||||
|
||||
CSuccinctHash::~CSuccinctHash()
|
||||
{
|
||||
if(m_RT!=NULL)
|
||||
{
|
||||
aligned_free(m_RT);
|
||||
}
|
||||
|
||||
if(m_kv_array!=NULL)
|
||||
{
|
||||
delete [] m_kv_array;
|
||||
}
|
||||
if(m_kv_ptr != NULL)
|
||||
{
|
||||
delete []m_kv_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
long long CSuccinctHash::init(unsigned int keys[], unsigned int values[], unsigned int num)
|
||||
{
|
||||
m_hash_bits=(int)(log10((double)num)/log10(2.0))+4;
|
||||
if(m_hash_bits<8) m_hash_bits=8;
|
||||
|
||||
//printf("m_hash_bits=%d\n", m_hash_bits);
|
||||
|
||||
m_RT=(packedRT_t *)aligned_malloc(sizeof(packedRT_t)*((1U<<(m_hash_bits-8))+1), 64);
|
||||
|
||||
FOR(i, (1U<<(m_hash_bits-8)))
|
||||
{
|
||||
FOR(j, 4) m_RT[i].bitmap[j]=0;
|
||||
}
|
||||
|
||||
FOR(i, num)
|
||||
{
|
||||
unsigned int h=myhash(keys[i]);
|
||||
|
||||
h&=((1U<<m_hash_bits)-1);
|
||||
int q=h&255;
|
||||
m_RT[h>>8].bitmap[q>>6]|=(ONE<<(q&63));
|
||||
}
|
||||
|
||||
m_RT[0].A=0;
|
||||
FOR(i, (1U<<(m_hash_bits-8)))
|
||||
{
|
||||
m_RT[i].B[0]=0;
|
||||
m_RT[i].B[1]= popcnt_u64(m_RT[i].bitmap[0]);
|
||||
m_RT[i].B[2]= m_RT[i].B[1]+popcnt_u64(m_RT[i].bitmap[1]);
|
||||
m_RT[i].B[3]= m_RT[i].B[2]+popcnt_u64(m_RT[i].bitmap[2]);
|
||||
m_RT[i+1].A=m_RT[i].A+m_RT[i].B[3]+popcnt_u64(m_RT[i].bitmap[3]);
|
||||
}
|
||||
int tn=m_RT[(1U<<(m_hash_bits-8))].A;
|
||||
|
||||
m_kv_ptr=new unsigned int[tn+1];
|
||||
FOR(i, tn+1) m_kv_ptr[i]=0;
|
||||
FOR(i, num)
|
||||
{
|
||||
unsigned int h=myhash(keys[i]);
|
||||
h&=((1U<<m_hash_bits)-1);
|
||||
unsigned int idx=rank(h);
|
||||
m_kv_ptr[idx]++;
|
||||
}
|
||||
FOR(i, tn) m_kv_ptr[i+1]+=m_kv_ptr[i];
|
||||
|
||||
m_kv_array=new unsigned int[2*num];
|
||||
FOR(i, num)
|
||||
{
|
||||
unsigned int h=myhash(keys[i]);
|
||||
h&=((1U<<m_hash_bits)-1);
|
||||
unsigned int idx=rank(h);
|
||||
unsigned int j=--m_kv_ptr[idx];
|
||||
m_kv_array[2*j]=keys[i];
|
||||
m_kv_array[2*j+1]=values[i];
|
||||
}
|
||||
|
||||
long long mem_bytes=(1U<<(m_hash_bits-3))*sizeof(char)*5/4+(tn+1+2*num)*sizeof(unsigned int);
|
||||
return mem_bytes;
|
||||
}
|
||||
|
||||
unsigned int CSuccinctHash::rank(unsigned int h)
|
||||
{
|
||||
int p=(h>>8);
|
||||
int r=((h&255)>>6);
|
||||
int s=(h&63);
|
||||
unsigned long long e=m_RT[p].bitmap[r]&((ONE<<s)-1);
|
||||
|
||||
return m_RT[p].A+m_RT[p].B[r]+popcnt_u64(e);
|
||||
}
|
||||
|
||||
int CSuccinctHash::find(unsigned int key, unsigned int * value, unsigned int size)
|
||||
{
|
||||
unsigned int h=myhash(key);
|
||||
h&=((1U<<m_hash_bits)-1);
|
||||
int q=h&255;
|
||||
unsigned int r=0;
|
||||
|
||||
if(m_RT[h>>8].bitmap[q>>6]&(ONE<<(q&63)))
|
||||
{
|
||||
unsigned int idx=rank(h);
|
||||
|
||||
for(unsigned int j=m_kv_ptr[idx]; j<m_kv_ptr[idx+1]; j++)
|
||||
{
|
||||
if(m_kv_array[2*j]==key)
|
||||
{
|
||||
if(r==size) return r;
|
||||
*value++=m_kv_array[2*j+1];
|
||||
r++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
Reference in New Issue
Block a user