00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef WIFI_FRAME_FILTER_FAST_INTERSECTOR_HXX_
00023 # define WIFI_FRAME_FILTER_FAST_INTERSECTOR_HXX_
00024
00025 # include <iostream>
00026 # include <boost/foreach.hpp>
00027
00028 # include "fast_intersector.hh"
00029
00030 # include <wipal/wifi/frame/filter/non_noisy_prism.hh>
00031 # include <wipal/wifi/frame/filter/uniquely_identifiable.hh>
00032
00033 namespace wifi
00034 {
00035 namespace frame
00036 {
00037 namespace filter
00038 {
00039
00040 namespace internals
00041 {
00042
00043 template <class I1, class I2, class B1, class B2>
00044 fast_intersector_iterator<I1, I2, B1, B2>::
00045 fast_intersector_iterator(const iterable_type& i, bool end):
00046 super_type (),
00047 iterable_ (&i),
00048 next_ (end ? i.last_ : i.first_)
00049 # ifdef ENABLE_INFO
00050 , rhs_total_ (0),
00051 ref_total_ (0)
00052 # endif
00053 {
00054 if (not end)
00055 increment();
00056 }
00057
00058 template <class I1, class I2, class B1, class B2>
00059 bool
00060 fast_intersector_iterator<I1, I2, B1, B2>::
00061 equal(const fast_intersector_iterator& rhs) const
00062 {
00063 if (not rhs.value())
00064 return not this->value();
00065 return next_ == rhs.next_;
00066 }
00067
00068 template <class I1, class I2, class B1, class B2>
00069 void
00070 fast_intersector_iterator<I1, I2, B1, B2>::increment()
00071 {
00072 const I2& last = this->iterable_->last_;
00073 bool found (false);
00074
00075 while (next_ != last and not found)
00076 {
00077 found = check();
00078 ++next_;
00079 # ifdef ENABLE_INFO
00080 ++rhs_total_;
00081 # endif // ENABLE_INFO
00082 }
00083
00084 if (not found)
00085 {
00086 this->value() = lookahead_;
00087 lookahead_ = boost::none_t ();
00088 }
00089
00090 # ifdef ENABLE_INFO
00091 if (not found and not this->value())
00092 {
00093 const unsigned lhs_total = this->iterable_->arrivals_.size();
00094
00095 std::cerr << "INFO: Trace 2 has " << rhs_total_
00096 << " unique frames.\n"
00097 << "INFO: " << ref_total_ << " reference frames.\n"
00098 << "INFO: " << (ref_total_ * 100.f / lhs_total)
00099 << "% of trace 1's unique frames.\n"
00100 << "INFO: " << (ref_total_ * 100.f / rhs_total_)
00101 << "% of trace 2's unique frames." << std::endl;
00102 }
00103 else
00104 ++ref_total_;
00105 # endif // ENABLE_INFO
00106 }
00107
00108 template <class I1, class I2, class B1, class B2>
00109 bool
00110 fast_intersector_iterator<I1, I2, B1, B2>::check()
00111 {
00112 typedef typename iterable_type::arrivals_type arrivals_type;
00113 typedef typename arrivals_type::const_iterator iterator;
00114
00115 const arrivals_type& arrivals = iterable_->arrivals_;
00116 const iterator i = arrivals.find(*next_);
00117
00118 if (i == arrivals.end())
00119 return false;
00120
00121 if (not lookahead_)
00122 {
00123
00124
00125
00126 lookahead_ = value_type (*i, *next_);
00127 return false;
00128 }
00129 assert(lookahead_);
00130
00131 value_type& lookahead = lookahead_.get();
00132 const tool::microseconds dt1 (i->microseconds() -
00133 lookahead.first.microseconds());
00134 const tool::microseconds dt2 (next_->microseconds() -
00135 lookahead.second.microseconds());
00136 const tool::microseconds drift (dt1 - dt2);
00137
00138 if (drift < -drift_warn_threshold or drift_warn_threshold < drift)
00139 {
00140 std::cerr << "WARNING: Dubious drift of " << (drift / 1000000.f)
00141 << "s for "
00142 << i->frame_id() << '-' << next_->frame_id();
00143 if (this->value())
00144 {
00145
00146
00147 std::cerr << " (ignoring reference)." << std::endl;
00148 return false;
00149 }
00150 else
00151 {
00152
00153
00154
00155 std::cerr << ".\n" "WARNING: Ignoring the potentially "
00156 "invalid previous reference "
00157 << lookahead.first.frame_id() << '-'
00158 << lookahead.second.frame_id() << '.' << std::endl;
00159
00160 lookahead = value_type (*i, *next_);
00161 return false;
00162 }
00163 }
00164
00165 if (i->microseconds() < lookahead.first.microseconds())
00166 std::cerr << "WARNING: Reference " << i->frame_id() << '-'
00167 << next_->frame_id() << " anterior to "
00168 << lookahead.first.frame_id() << '-'
00169 << lookahead.second.frame_id() << '.' << std::endl;
00170 else if (dt1 > dt_warn_threshold or dt2 > dt_warn_threshold)
00171 std::cerr << "WARNING: " << (dt1 / 1000000.f) << "s and "
00172 << (dt2 / 1000000.f) << "s between "
00173 << lookahead.first.frame_id() << '-'
00174 << lookahead.second.frame_id() << " and "
00175 << i->frame_id() << '-' << next_->frame_id()
00176 << '.' << std::endl;
00177
00178 this->value() = lookahead;
00179 lookahead = value_type (*i, *next_);
00180 return true;
00181 }
00182
00183 }
00184
00185
00186 template <class I1, class I2, class B>
00187 fast_intersector<I1, I2, B>::
00188 fast_intersector(const I1& first1, const I1& last1,
00189 const I2& first2, const I2& last2):
00190 first_ (first2),
00191 last_ (last2)
00192 # ifndef DONT_USE_HASH
00193 , arrivals_ (hash_bucket_count)
00194 # endif
00195 {
00196 arrivals_type collisions;
00197
00198 for (I1 i = first1; i != last1; ++i)
00199 {
00200 typedef typename arrivals_type::iterator iterator;
00201
00202 std::pair<iterator, bool> r = arrivals_.insert(*i);
00203
00204 if (not r.second)
00205 {
00206 collisions.insert(*i);
00207 std::cerr << "WARNING: Unique frame " << i->frame_id()
00208 << " actually a duplicate of "
00209 << r.first->frame_id() << " (ignoring both)."
00210 << std::endl;
00211 }
00212 }
00213
00214 BOOST_FOREACH(const typename I1::value_type& v, collisions)
00215 arrivals_.erase(v);
00216
00217 # ifdef ENABLE_INFO
00218 std::cerr << "INFO: Trace 1's unique frames successfuly loaded.\n"
00219 << "INFO: Trace 1 has " << arrivals_.size()
00220 << " unique frames." << std::endl;
00221 # endif // ENABLE_INFO
00222
00223 }
00224
00225 }
00226
00227 }
00228
00229 }
00230
00231 #endif // ! WIFI_FRAME_FILTER_FAST_INTERSECTOR_HXX_