IBR-DTNSuite  0.8
ibrcommon/ibrcommon/data/BloomFilter.h
Go to the documentation of this file.
00001 /*
00002  * BloomFilter.h
00003  *
00004  * This bloom filter implementation is based on
00005  * Open Bloom Filter (http://www.partow.net) written by Arash Partow.
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;    // 8 bits in 1 char(unsigned)
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 /* BLOOMFILTER_H_ */