filter.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include<iostream>
  2. #include<cmath>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include"../basic/nanxing_operator_check.h"
  6. namespace nanxing_extend
  7. {
  8. //这是个意外,本来是想工厂类和不同的过滤器划分到不同文件的,但是由于贯彻head_only,还没想出来怎么组织文件,只能丢在一起了
  9. //同时也是一个控制类,即这个类本身带有控制功能,只允许一次产生持有唯一的filter
  10. //如果不对产生的类进行管控,最后的结果很可能是完全无法处理,因为C++中内存分配方式过于多样,malloc,new,new[],数组。。。。乱七八糟,最后类内生成的空间完全无法析构,因为根本不知道类内怎么实现的
  11. //当然也可以通过返回智能指针的方式进行管控,但是没有选择那么做的原因在于过滤器本身不会大量存在
  12. //一个程序中最多一到两个过滤器
  13. //但是但是相信我不会有God class
  14. template<typename K>
  15. class FilterPolicy
  16. {
  17. static_assert(NANXING_BASIC_OPERATOR_(K,compare),"the type of key cannot compare");
  18. private:
  19. FilterPolicy& operator=(FilterPolicy const&)=delete;
  20. FilterPolicy(FilterPolicy const&)=delete;
  21. FilterPolicy* producter=nullptr; //用于管控生成的类
  22. public:
  23. //限制当主动生成一个工厂类后,不管怎么赋值,最后只有一个工厂
  24. //move-only
  25. FilterPolicy(){};
  26. FilterPolicy(FilterPolicy&&){}
  27. virtual void policy_print(){producter->policy_print();} //输出对应的计算公式
  28. virtual void parameter_print(){producter->parameter_print();} //输出过滤器的参数
  29. //两个工厂函数用于生成不同的过滤器
  30. FilterPolicy* creat_Bloomfilter(int N,int P);
  31. FilterPolicy* creat_Cuckoofilter();
  32. virtual void init_filter(){producter->init_filter();}
  33. virtual ~FilterPolicy(){};
  34. };
  35. template<typename K>
  36. class bloomfilter:public FilterPolicy
  37. {
  38. static_assert(NANXING_BASIC_OPERATOR_(K,compare),"the type of key cannot compare");
  39. private:
  40. //这里使用线性混合同余来构造哈希函数,因为线性混合同余的随机性和运算效率的平衡比较好
  41. constexpr static const int hash_prime_number1[10]={52223,52237,79939,19937,8243,24133,12647,13147,62459,94547}; //给出10个大素数作为哈希函数的素数种子
  42. constexpr static const int hash_prime_number2[10]={94399,94421,94427,94433,94439,94441,94447,94463,94477,94483}; //哈希函数的置偏值
  43. struct param{
  44. float P; //概率参数
  45. int k; //哈希函数个数
  46. int n; //n数据长度
  47. int m; //bloomfilter长度
  48. param(float _p,int _n):P(_p),n(_n){}
  49. };
  50. private:
  51. u_int64_t* bitarray; //bloomfilter的核心数据结构,一个比特数组
  52. param parameter;
  53. protected:
  54. bloomfilter()=delete;
  55. bloomfilter(bloomfilter&)=delete;
  56. bloomfilter& operator=(bloomfilter)=delete; //不允许复制构造
  57. void caculater()noexcept //计算bloomfilter的参数
  58. {
  59. parameter.m=static_cast<int>(-(parameter.n*std::log(parameter.P)/0.4804530139));
  60. parameter.k=static_cast<int>(0.6931471806*(parameter.m/parameter.n));
  61. }
  62. int hash_function(int i,K data) //i代表第i个哈希函数,返回在bloomfilter中的位置
  63. {
  64. return ((static_cast<int>(data))*(this->hash_prime_number1[i])+(this->hash_prime_number2[i]))%(this->parameter.m);
  65. }
  66. public:
  67. bloomfilter(float _p,int _n):bitarray(0),parameter(_p,_n){}
  68. void init_filter()override{
  69. caculater();
  70. bitarray=new u_int64_t[static_cast<int>(parameter.m/64)+1]; //构建数组
  71. std::memset(bitarray,0,sizeof(u_int64_t)*static_cast<int>(parameter.m/64)+1); //初始化
  72. }
  73. void policy_print()override //打印出使用的公式
  74. {
  75. std::cout<<"m=-((nlnP)/((ln2)^2))"<<"//m为bloomfilter的长度"<<std::endl;
  76. std::cout<<"k=ln2*(m/n)"<<"//k为所需的哈希函数的个数"<<std::endl;
  77. }
  78. virtual ~bloomfilter()
  79. {
  80. if(bitarray!=nullptr)
  81. {
  82. delete[] bitarray;
  83. }
  84. }
  85. };
  86. template<typename K>
  87. class Cuckoofilter:public FilterPolicy
  88. {
  89. static_assert(NANXING_BASIC_OPERATOR_(K,compare),"the type of key cannot compare");
  90. };
  91. template<typename K>
  92. FilterPolicy<K>* FilterPolicy<K>::creat_Bloomfilter(int N,int P)
  93. {
  94. if(producter!=nullptr)
  95. {
  96. delete producter;
  97. }
  98. producter=new bloomfilter(N,P);
  99. return producter;
  100. }
  101. template<typename K>
  102. FilterPolicy<K>* FilterPolicy<K>::creat_Cuckoofilter()
  103. {
  104. if(producter!=nullptr)
  105. {
  106. delete producter;
  107. }
  108. producter=new Cuckoofilter;
  109. return producter;
  110. }
  111. }