libBf 0.1
|
00001 #ifndef DETAIL_BITWISE_H 00002 #define DETAIL_BITWISE_H 00003 00004 #include "detail/basic.h" 00005 #include "detail/spectral.h" 00006 00007 namespace bf { 00008 namespace detail { 00009 namespace bitwise { 00010 00011 template <typename T, typename V> 00012 void add(const T& x, V& levels, unsigned min_size) 00013 { 00014 typedef std::vector<typename V::value_type::store_type::pos_vector> vector; 00015 vector pos; 00016 for (typename V::size_type i = 0; i < levels.size(); ++i) 00017 { 00018 pos.push_back(levels[i].positions(x)); 00019 auto cnt = detail::spectral::minimum(pos[i], levels[i].store); 00020 if (cnt < levels[i].store.max()) 00021 { 00022 for (auto j : pos[i]) 00023 levels[i].store.increment(j); 00024 00025 return; 00026 } 00027 00028 for (auto j : pos[i]) 00029 levels[i].store.reset(j); 00030 } 00031 00032 auto z = levels.back(); 00033 auto cells = z.store.size() / 2; // TODO: make growth rate configurable. 00034 if (cells < min_size) 00035 cells = min_size; 00036 00037 levels.push_back({ cells, z.hash.k(), z.store.width(), z.part.parts() }); 00038 detail::basic::add(x, levels.back()); 00039 } 00040 00041 template <typename T, typename V> 00042 void remove(const T& x, V& levels) 00043 { 00044 typedef std::vector<typename V::value_type::store_type::pos_vector> vector; 00045 vector pos; 00046 for (typename V::size_type i = 0; i < levels.size(); ++i) 00047 { 00048 pos.push_back(levels[i].positions(x)); 00049 auto cnt = detail::spectral::minimum(pos[i], levels[i].store); 00050 if (cnt > 0) 00051 { 00052 for (auto j : pos[i]) 00053 levels[i].store.decrement(j); 00054 00055 if (levels.size() > 1 && levels.back().store.none()) 00056 levels.pop_back(); 00057 00058 return; 00059 } 00060 00061 if (levels.size() > 1) 00062 for (auto j : pos[i]) 00063 levels[i].store.set(j); 00064 } 00065 } 00066 00067 template <typename T, typename V> 00068 unsigned count(const T& x, V& levels) 00069 { 00070 unsigned width = 0; 00071 unsigned result = 0; 00072 for (typename V::size_type i = 0; i < levels.size(); ++i) 00073 { 00074 auto& core = levels[i]; 00075 auto cnt = detail::spectral::minimum(core.positions(x), core.store); 00076 00077 if (cnt) 00078 result += cnt << width; 00079 00080 width += core.store.width(); 00081 } 00082 00083 return result; 00084 } 00085 00086 } // namespace bitwise 00087 } // namespace detail 00088 } // namespace bf 00089 00090 #endif