Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <cstddef>
00010 #include <algorithm>
00011 #include <cmath>
00012 #include <limits>
00013 #include <string>
00014 #include <vector>
00015 #include <list>
00016
00017 #ifndef BLOOMFILTER_H_
00018 #define BLOOMFILTER_H_
00019
00020 namespace ibrcommon
00021 {
00022 typedef unsigned int bloom_type;
00023 typedef unsigned char cell_type;
00024
00025 class HashProvider
00026 {
00027 public:
00032 virtual size_t count() const = 0;
00033
00034 virtual void clear() = 0;
00035 virtual const std::list<bloom_type> hash(const unsigned char* begin, std::size_t remaining_length) const = 0;
00036 };
00037
00038 class DefaultHashProvider : public HashProvider
00039 {
00040 public:
00041 DefaultHashProvider(size_t salt_count);
00042 virtual ~DefaultHashProvider();
00043
00044 bool operator==(const DefaultHashProvider &provider) const;
00045 size_t count() const;
00046 void clear();
00047
00048 const std::list<bloom_type> hash(const unsigned char* begin, std::size_t remaining_length) const;
00049
00050 private:
00051 void add(bloom_type hash);
00052 void generate_salt();
00053 bloom_type hash_ap(const unsigned char* begin, std::size_t remaining_length, bloom_type hash) const;
00054
00055 std::vector<bloom_type> _salt;
00056 std::size_t salt_count_;
00057 };
00058
00059 class BloomFilter
00060 {
00061 protected:
00062 static const std::size_t bits_per_char = 0x08;
00063 static const unsigned char bit_mask[bits_per_char];
00064
00065 public:
00066 BloomFilter(std::size_t table_size = 8196, std::size_t salt_count = 2);
00067 BloomFilter(const BloomFilter& filter);
00068 virtual ~BloomFilter();
00069
00070 void load(const cell_type* data, size_t len);
00071
00072 BloomFilter& operator=(const BloomFilter& filter);
00073
00074 bool operator!() const;
00075 void clear();
00076
00077 void insert(const unsigned char* key_begin, const std::size_t length);
00078
00079 template<typename T>
00080 void insert(const T& t)
00081 {
00082 insert(reinterpret_cast<const unsigned char*>(&t),sizeof(T));
00083 }
00084
00085 void insert(const std::string& key);
00086
00087 void insert(const char* data, const std::size_t& length);
00088
00089 template<typename InputIterator>
00090 void insert(const InputIterator begin, const InputIterator end)
00091 {
00092 InputIterator it = begin;
00093 while(it != end)
00094 {
00095 insert(*(it++));
00096 }
00097 }
00098
00099 virtual bool contains(const unsigned char* key_begin, const std::size_t length) const;
00100
00101 template<typename T>
00102 bool contains(const T& t) const
00103 {
00104 return contains(reinterpret_cast<const unsigned char*>(&t),static_cast<std::size_t>(sizeof(T)));
00105 }
00106
00107 bool contains(const std::string& key) const;
00108
00109 bool contains(const char* data, const std::size_t& length) const;
00110
00111 template<typename InputIterator>
00112 InputIterator contains_all(const InputIterator begin, const InputIterator end) const
00113 {
00114 InputIterator it = begin;
00115 while(it != end)
00116 {
00117 if (!contains(*it))
00118 {
00119 return it;
00120 }
00121 ++it;
00122 }
00123 return end;
00124 }
00125
00126 template<typename InputIterator>
00127 InputIterator contains_none(const InputIterator begin, const InputIterator end) const
00128 {
00129 InputIterator it = begin;
00130 while(it != end)
00131 {
00132 if (contains(*it))
00133 {
00134 return it;
00135 }
00136 ++it;
00137 }
00138 return end;
00139 }
00140
00141 virtual std::size_t size() const;
00142
00143 BloomFilter& operator &= (const BloomFilter& filter);
00144 BloomFilter& operator |= (const BloomFilter& filter);
00145 BloomFilter& operator ^= (const BloomFilter& filter);
00146
00147 const cell_type* table() const;
00148
00149 float getAllocation() const;
00150
00151 protected:
00152 virtual void compute_indices(const bloom_type& hash, std::size_t& bit_index, std::size_t& bit) const;
00153 DefaultHashProvider _hashp;
00154
00155 unsigned char* bit_table_;
00156 std::size_t table_size_;
00157
00158 unsigned int _itemcount;
00159 std::size_t salt_count_;
00160 };
00161 }
00162
00163
00164 #endif