00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef WIFI_TRACES_EXTENDED_MERGE_HXX_
00023 # define WIFI_TRACES_EXTENDED_MERGE_HXX_
00024
00025 # include "extended_merge.hxx"
00026
00027 # include <set>
00028 # include <map>
00029 # include <utility>
00030 # include <iostream>
00031
00032 # include <boost/lexical_cast.hpp>
00033 # include <boost/tuple/tuple.hpp>
00034 # include <boost/tuple/tuple_comparison.hpp>
00035
00036 # include <wipal/pcap/descriptor.hh>
00037 # include <wipal/wifi/traces/merge.hh>
00038 # include <wipal/wifi/traces/similarity.hh>
00039
00040 namespace wifi
00041 {
00042
00043 namespace traces
00044 {
00045
00046 namespace merge_helpers
00047 {
00048
00049 template <class Iterator>
00050 struct extended_merge_state
00051 {
00052 typedef std::map<Iterator, std::string> parent_map;
00053
00054 extended_merge_state(addr_mapping& mapping,
00055 bool& filter_noisy_prism,
00056 tool::endian::endianness& endianness):
00057 mapping_ (mapping),
00058 filter_noisy_prism_ (filter_noisy_prism),
00059 endianness_ (endianness),
00060 merge_count_ (0)
00061 {
00062 }
00063
00064 parent_map&
00065 pmap()
00066 {
00067 return pmap_;
00068 }
00069
00070 const parent_map&
00071 pmap() const
00072 {
00073 return pmap_;
00074 }
00075
00076 std::string
00077 output() const
00078 {
00079 return "merge-" + boost::lexical_cast<std::string>(merge_count_);
00080 }
00081
00082 void
00083 update_parent(const std::string& parent_name)
00084 {
00085 const std::string& o = output();
00086
00087 BOOST_FOREACH(typename parent_map::value_type& p, pmap_)
00088 if (p.second == parent_name)
00089 p.second = o;
00090 }
00091
00092 template <class U, class P,
00093 template <class, class, class> class I,
00094 template <class, class, class, class> class M,
00095 class T1, class T2>
00096 void
00097 merge(T1& lhs, T2& rhs)
00098 {
00099 ++merge_count_;
00100
00101 static const std::set< std::pair<unsigned, unsigned> >
00102 empty_blacklist;
00103 const std::string out_name = output();
00104
00105 # ifdef WP_ENABLE_INFO
00106 std::cerr << "INFO: Begining a new merge operation.\n"
00107 << "INFO: Trace 1 is " << lhs.file_name() << ".\n"
00108 << "INFO: Trace 2 is " << rhs.file_name() << ".\n"
00109 << "INFO: Output is " << out_name << "." << std::endl;
00110 # endif // WP_ENABLE_INFO
00111
00112
00113
00114
00115 traces::merge<U, P, I, M>(lhs, rhs, out_name,
00116 mapping_,
00117 filter_noisy_prism_, endianness_,
00118 empty_blacklist);
00119 }
00120
00121 private:
00122 addr_mapping& mapping_;
00123 const bool& filter_noisy_prism_;
00124 const tool::endian::endianness& endianness_;
00125
00126 unsigned merge_count_;
00127 parent_map pmap_;
00128 };
00129
00130 }
00131
00132 template <class U, class P,
00133 template <class, class, class> class I,
00134 template <class, class, class, class> class M,
00135 class C>
00136 std::string
00137 merge(C& traces,
00138 addr_mapping& mapping,
00139 bool filter_noisy_prism,
00140 tool::endian::endianness endianness)
00141 {
00142 typedef typename C::iterator iterator;
00143 typedef merge_helpers::extended_merge_state<iterator> state;
00144 typedef typename state::parent_map parent_map;
00145 typedef boost::tuple<unsigned, iterator, iterator> score;
00146 typedef std::set<score> score_set;
00147
00148 state st (mapping, filter_noisy_prism, endianness);
00149 parent_map& pm = st.pmap();
00150 score_set ss = similarity<U, P, I>(traces, mapping,
00151 filter_noisy_prism,
00152 endianness);
00153
00154 for (typename score_set::reverse_iterator i = ss.rbegin();
00155 i != ss.rend();
00156 ++i)
00157 {
00158 iterator t1 = boost::get<1>(*i);
00159 iterator t2 = boost::get<2>(*i);
00160
00161 typename parent_map::iterator t1_parent = pm.find(t1);
00162 typename parent_map::iterator t2_parent = pm.find(t2);
00163
00164 if (t1_parent != pm.end())
00165 {
00166 if (t2_parent != pm.end())
00167 {
00168 const std::string t1_trace_name = t1_parent->second;
00169 const std::string t2_trace_name = t2_parent->second;
00170
00171 if (t1_trace_name == t2_trace_name)
00172 continue;
00173
00174 pcapxx::descriptor<> t1_trace (t1_trace_name);
00175 pcapxx::descriptor<> t2_trace (t2_trace_name);
00176
00177 if (t1_trace.file_size() < t2_trace.file_size())
00178 st.merge<U, P, I, M>(t1_trace, t2_trace);
00179 else
00180 st.merge<U, P, I, M>(t2_trace, t1_trace);
00181 st.update_parent(t1_trace_name);
00182 st.update_parent(t2_trace_name);
00183 }
00184 else
00185 {
00186 const std::string t1_trace_name = t1_parent->second;
00187 pcapxx::descriptor<> t1_trace (t1_trace_name);
00188
00189 st.merge<U, P, I, M>(*t2, t1_trace);
00190 st.update_parent(t1_trace_name);
00191 pm[t2] = st.output();
00192 }
00193 }
00194 else
00195 {
00196 if (t2_parent != pm.end())
00197 {
00198 const std::string t2_trace_name = t2_parent->second;
00199 pcapxx::descriptor<> t2_trace (t2_trace_name);
00200
00201 st.merge<U, P, I, M>(*t1, t2_trace);
00202 pm[t1] = st.output();
00203 st.update_parent(t2_trace_name);
00204 }
00205 else
00206 {
00207 st.merge<U, P, I, M>(*t1, *t2);
00208 pm[t1] = st.output();
00209 pm[t2] = st.output();
00210 }
00211 }
00212 }
00213
00214 return st.output();
00215 }
00216
00217 }
00218
00219 }
00220
00221 #endif // ! WIFI_TRACES_EXTENDED_MERGE_HXX_