|
@@ -3,12 +3,11 @@
|
|
|
#include<cstdlib>
|
|
|
#include<cstring>
|
|
|
#include<exception>
|
|
|
+#include<cstdint>
|
|
|
#include"../basic/nanxing_operator_check.h"
|
|
|
|
|
|
namespace nanxing_extend
|
|
|
{
|
|
|
-
|
|
|
-
|
|
|
//这是个意外,本来是想工厂类和不同的过滤器划分到不同文件的,但是由于贯彻head_only,还没想出来怎么组织文件,只能丢在一起了
|
|
|
//同时也是一个控制类,即这个类本身带有控制功能,只允许一次产生持有唯一的filter
|
|
|
//如果不对产生的类进行管控,最后的结果很可能是完全无法处理,因为C++中内存分配方式过于多样,malloc,new,new[],数组。。。。乱七八糟,最后类内生成的空间完全无法析构,因为根本不知道类内怎么实现的
|
|
@@ -26,16 +25,31 @@ namespace nanxing_extend
|
|
|
public:
|
|
|
//限制当主动生成一个工厂类后,不管怎么赋值,最后只有一个工厂
|
|
|
//move-only
|
|
|
- FilterPolicy(){};
|
|
|
+ FilterPolicy(){}
|
|
|
FilterPolicy(FilterPolicy&&){}
|
|
|
- virtual void policy_print(){} //输出对应的计算公式
|
|
|
- virtual void parameter_print(){} //输出过滤器的参数
|
|
|
- virtual void insert(K key)noexcept{}; //当向数据库插入数据后对过滤器进行调整
|
|
|
- [[nodiscard]]virtual bool check(K key)noexcept{};
|
|
|
+
|
|
|
+ virtual void policy_print(){} //输出对应的计算公式
|
|
|
+
|
|
|
+ #ifdef NANXING_DEBUG_
|
|
|
+ virtual void parameter_print(){} //输出过滤器的参数
|
|
|
+ #endif
|
|
|
+ virtual void insert(K key)noexcept{} //当向数据库插入数据后对过滤器进行调整
|
|
|
+
|
|
|
+ [[nodiscard]]
|
|
|
+ //cppcheck还不能识别C++17引入的属性
|
|
|
+ virtual bool check(K key)noexcept{}
|
|
|
//两个工厂函数用于生成不同的过滤器
|
|
|
- FilterPolicy* creat_Bloomfilter(int N,int P);
|
|
|
+ FilterPolicy* creat_Bloomfilter(int N,float P);
|
|
|
FilterPolicy* creat_Cuckoofilter();
|
|
|
virtual void init_filter(){} //初始化过滤器
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ #ifdef NANXING_DEBUG_
|
|
|
+ virtual auto get_k()->uint64_t{}
|
|
|
+
|
|
|
+ virtual auto get_m()->uint64_t{}
|
|
|
+ #endif
|
|
|
virtual ~FilterPolicy(){
|
|
|
if(producter!=nullptr)
|
|
|
{
|
|
@@ -56,9 +70,9 @@ namespace nanxing_extend
|
|
|
struct param{
|
|
|
float P; //概率参数
|
|
|
int k=0; //哈希函数个数
|
|
|
- int n; //n数据长度
|
|
|
- int m=0; //bloomfilter长度
|
|
|
- param(float _p,int _n):P(_p),n(_n){}
|
|
|
+ uint64_t n; //n数据长度
|
|
|
+ uint64_t m=0; //bloomfilter长度
|
|
|
+ param(float _p,uint64_t _n):P(_p),n(_n){}
|
|
|
};
|
|
|
private:
|
|
|
char* bitarray; //bloomfilter的核心数据结构,一个比特数组
|
|
@@ -70,22 +84,23 @@ namespace nanxing_extend
|
|
|
bloomfilter& operator=(bloomfilter)=delete; //不允许复制构造
|
|
|
void caculater()noexcept //计算bloomfilter的参数
|
|
|
{
|
|
|
- this->parameter.m=static_cast<int>(-(parameter.n*std::log(parameter.P)/0.4804530139));
|
|
|
- this->parameter.k=static_cast<int>(0.6931471806*(parameter.m/parameter.n));
|
|
|
+ this->parameter.m=static_cast<uint64_t>(-(parameter.n*std::log(parameter.P)/0.48045301)); //这两个数字分别是ln2和(ln2)^2,位公式中的常数
|
|
|
+ this->parameter.k=static_cast<uint64_t>(0.693147*(parameter.m/parameter.n)+1);
|
|
|
+
|
|
|
}
|
|
|
int hash_function(int i,K data) //i代表第i个哈希函数,返回在bloomfilter中的位置
|
|
|
{
|
|
|
return ((static_cast<int>(data))*(this->hash_prime_number1[i])+(this->hash_prime_number2[i]))%(this->parameter.m);
|
|
|
}
|
|
|
public:
|
|
|
- bloomfilter(float _p,int _n):bitarray(nullptr),parameter(_p,_n){}
|
|
|
+ bloomfilter(float _p,uint64_t _n):bitarray(nullptr),parameter(_p,_n){}
|
|
|
|
|
|
void init_filter()override{
|
|
|
LOOP:
|
|
|
caculater();
|
|
|
LOOP1:
|
|
|
try{
|
|
|
- bitarray=new char[static_cast<int>(parameter.m/8)+1]; //构建数组
|
|
|
+ bitarray=new char[static_cast<uint64_t>(parameter.m/8)+1]; //构建数组
|
|
|
}
|
|
|
catch(std::bad_alloc)
|
|
|
{
|
|
@@ -110,9 +125,9 @@ namespace nanxing_extend
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- std::memset(bitarray,0,sizeof(char)*static_cast<int>(parameter.m/8)+1); //初始化
|
|
|
+ std::memset(bitarray,0,sizeof(char)*static_cast<u_int64_t>(parameter.m/8)+1); //初始化
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
void policy_print()override //打印出使用的公式
|
|
|
{
|
|
|
std::cout<<"m=-((nlnP)/((ln2)^2))"<<"//m为bloomfilter的长度"<<std::endl;
|
|
@@ -129,7 +144,7 @@ namespace nanxing_extend
|
|
|
for(int i=0;i<this->parameter.k;i++)
|
|
|
{
|
|
|
int tmp=this->hash_function(i,key);
|
|
|
- int filter_u=static_cast<int>(tmp/8);
|
|
|
+ uint64_t filter_u=static_cast<uint64_t>(tmp/8);
|
|
|
int move=tmp%8;
|
|
|
this->bitarray[filter_u]=this->bitarray[filter_u]|('1'<<(7-move));
|
|
|
}
|
|
@@ -145,7 +160,7 @@ namespace nanxing_extend
|
|
|
for(int i=0;i<this->parameter.k;i++)
|
|
|
{
|
|
|
int tmp=this->hash_function(i,key);
|
|
|
- int filter_u=static_cast<int>(tmp/8);
|
|
|
+ uint64_t filter_u=static_cast<uint64_t>(tmp/8);
|
|
|
int move=tmp%8;
|
|
|
if((this->bitarray[filter_u]&('1'<<(7-move)))==0) //若对应位为0
|
|
|
{
|
|
@@ -154,7 +169,23 @@ namespace nanxing_extend
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
+ #ifdef NANXING_DEBUG_
|
|
|
+ void parameter_print()override
|
|
|
+ {
|
|
|
+ std::cout<<"(m,n,k,p) = "<<"("<<this->parameter.m<<","<<parameter.n<<","<<parameter.k<<","<<parameter.P<<")";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ auto get_k()->uint64_t override
|
|
|
+ {
|
|
|
+ return this->parameter.k;
|
|
|
+ }
|
|
|
|
|
|
+ auto get_m()->uint64_t override
|
|
|
+ {
|
|
|
+ return this->parameter.m;
|
|
|
+ }
|
|
|
+ #endif
|
|
|
virtual ~bloomfilter()
|
|
|
{
|
|
|
if(bitarray!=nullptr)
|
|
@@ -172,13 +203,13 @@ namespace nanxing_extend
|
|
|
};
|
|
|
|
|
|
template<typename K>
|
|
|
- FilterPolicy<K>* FilterPolicy<K>::creat_Bloomfilter(int N,int P)
|
|
|
+ FilterPolicy<K>* FilterPolicy<K>::creat_Bloomfilter(int N,float P)
|
|
|
{
|
|
|
if(producter!=nullptr)
|
|
|
{
|
|
|
delete producter;
|
|
|
}
|
|
|
- producter=new bloomfilter<K>(N,P);
|
|
|
+ producter=new bloomfilter<K>(P,N);
|
|
|
return producter;
|
|
|
}
|
|
|
|