00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef FILTER_FAST_INTERSECTOR_HH_
00023 # define FILTER_FAST_INTERSECTOR_HH_
00024
00025 # include <utility>
00026
00027 # include <wipal/tool/hash.hh>
00028 # include <wipal/tool/valued_iterator.hh>
00029 # include <wipal/tool/microseconds.hh>
00030 # include <wipal/tool/iterable.hh>
00031 # include <wipal/wifi/addr_mapping.hh>
00032
00033 # include "fast_intersector_fwd.hh"
00034
00035 namespace wpl
00036 {
00037
00038 namespace tool
00039 {
00040
00041 template <class I1, class I2, class B1, class B2>
00042 struct types< wpl::filter::internals::
00043 fast_intersector_iterator<I1, I2, B1, B2> >
00044 {
00045 typedef
00046 std::pair<typename I1::value_type, typename I2::value_type>
00047 value_type;
00048
00049 typedef
00050 wpl::filter::fast_intersector<I1, I2, B1>
00051 iterable_type;
00052 };
00053
00054 template <class I1, class I2, class B>
00055 struct types< wpl::filter::fast_intersector<I1, I2, B> >
00056 {
00057 typedef wpl::filter::internals::
00058 fast_intersector_iterator<I1, I2, B, bottom>
00059 iterator;
00060 };
00061
00062 }
00063
00064 namespace filter
00065 {
00066
00067 namespace internals
00068 {
00069 template <class I1, class I2, class B, class Bottom = tool::bottom>
00070 struct fast_intersector_iterator:
00071 WP_INHERIT(public tool::valued_iterator,
00072 fast_intersector_iterator<I1, I2, B, Bottom>)
00073 {
00074
00076
00077 typedef WP_GET_EXACT(Bottom,
00078 fast_intersector_iterator<I1, I2, B, Bottom>)
00079 exact_type;
00080 typedef tool::valued_iterator<exact_type> super_type;
00081 typedef WP_TYPE(value_type, exact_type) value_type;
00082 typedef WP_TYPE(iterable_type, exact_type) iterable_type;
00083 typedef typename iterable_type::arrivals_type arrivals_type;
00084 typedef typename arrivals_type::const_iterator arrivals_iterator;
00086
00088 fast_intersector_iterator(const iterable_type& i, bool end);
00089
00091
00092 bool equal(const fast_intersector_iterator& rhs) const;
00093 void increment();
00095
00097 unsigned rhs_frame_count() const;
00098
00100 unsigned rhs_uframe_count() const;
00101
00102 private:
00103 enum
00104 {
00112 dt_warn_threshold = 15 * 60 * 1000 * 1000,
00113
00130 drift_warn_threshold = 20 * 1000,
00131 };
00132
00133
00134 bool check();
00135 bool check_drift(const tool::microseconds& dt1,
00136 const tool::microseconds& dt2,
00137 const typename I1::value_type& frame1,
00138 const typename I2::value_type& frame2);
00139 void check_consistency(const tool::microseconds& dt1,
00140 const tool::microseconds& dt2,
00141 const typename I1::value_type& frame1,
00142 const typename I2::value_type& frame2) const;
00143
00144 void ignore(const typename I1::value_type& frame1,
00145 const typename I2::value_type& frame2);
00146 void dont_ignore(const typename I1::value_type& frame1,
00147 const typename I2::value_type& frame2);
00148
00150 struct ignore_info
00151 {
00152 ignore_info(const tool::microseconds& stamp_rhs,
00153 const tool::microseconds& stamp_lhs,
00154 const unsigned total_rhs,
00155 const unsigned total_lhs);
00156
00158 tool::microseconds stamp1_;
00159
00161 tool::microseconds stamp2_;
00162
00164 unsigned total1_;
00165
00167 unsigned total2_;
00168 };
00169
00170 const iterable_type* iterable_;
00171 I2 next_;
00172 boost::optional<ignore_info> ign_;
00173
00174
00175
00176
00177 typename super_type::optional_value lookahead_;
00178
00179 # ifdef WP_ENABLE_INFO
00180 unsigned rhs_total_;
00181 unsigned ref_total_;
00182 # endif // WP_ENABLE_INFO
00183 };
00184
00185 }
00186
00187
00188 template <class InputIterator1,
00189 class InputIterator2,
00190 class Bottom = tool::bottom>
00191 struct fast_intersector:
00192 WP_INHERIT(public tool::iterable, fast_intersector<InputIterator1,
00193 InputIterator2,
00194 Bottom>)
00195 {
00196 fast_intersector(const InputIterator1& first1,
00197 const InputIterator1& last1,
00198 const InputIterator2& first2,
00199 const InputIterator2& last2,
00200 const unsigned precision);
00201
00202 void
00203 reset_lhs(const InputIterator1& first1,
00204 const InputIterator1& last1);
00205
00206 void
00207 reset_rhs(const InputIterator2& first2,
00208 const InputIterator2& last2);
00209
00210
00211 # ifdef WP_DONT_USE_HASH
00212 typedef std::set<typename InputIterator1::value_type> arrivals_type;
00213 # else
00214 typedef
00215 tool::hash_set<typename InputIterator1::value_type> arrivals_type;
00216
00217 enum
00218 {
00228 hash_bucket_count = 1 << 25
00229 };
00230 # endif
00231
00232 private:
00233 InputIterator2 first_;
00234 InputIterator2 last_;
00235 arrivals_type arrivals_;
00236 unsigned precision_;
00237
00238 friend
00239 class internals::fast_intersector_iterator<InputIterator1,
00240 InputIterator2,
00241 Bottom,
00242 tool::bottom>;
00243 };
00244
00245 }
00246
00247 }
00248
00249 # include "fast_intersector.hxx"
00250
00251 #endif // ! FILTER_FAST_INTERSECTOR_HH_