00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef WIFI_STATS_STA_COUNTERS_HXX_
00023 # define WIFI_STATS_STA_COUNTERS_HXX_
00024
00025 # include <boost/foreach.hpp>
00026 # include <boost/format.hpp>
00027
00028 # include <wipal/wifi/stats/sta_counters.hh>
00029
00030 namespace wpl
00031 {
00032
00033 namespace wifi
00034 {
00035
00036 namespace stats
00037 {
00038
00039 inline
00040 sta_counters::sta_counters(const on_off_data* ood): ood_ (ood)
00041 {
00042 }
00043
00044 template <class Frame>
00045 void
00046 sta_counters::account_frame(const Frame& ,
00047 const size_t& len80211,
00048 const type::frame_type& ,
00049 const unsigned& ,
00050 const bool& ,
00051 const addr* const& ,
00052 const addr* const& transmitter,
00053 const bool& )
00054 {
00055 if (not transmitter)
00056 return;
00057
00058 counters& s = states_[*transmitter];
00059
00060 ++s.count;
00061 s.size += len80211;
00062 }
00063
00064 inline
00065 std::ostream&
00066 sta_counters::print(std::ostream& os) const
00067 {
00068 os << "begin per STA counters\n\n";
00069
00070 print(os, "STA counters sorted by traffic",
00071 sorted_states<size_less>()) << '\n';
00072
00073 print(os, "STA counters sorted by on time",
00074 sorted_states<time_on_less>(ood_)) << '\n';
00075
00076 print(os, "STA counters sorted by avg. rate when on",
00077 sorted_states<avg_rate_less>(ood_));
00078
00079 return os << "end per STA counters" << std::endl;
00080 }
00081
00082 inline
00083 sta_counters::counters::counters(): count (0), size (0)
00084 {
00085 }
00086
00087 inline
00088 bool
00089 sta_counters::
00090 size_less::operator () (const states::const_iterator& lhs,
00091 const states::const_iterator& rhs) const
00092 {
00093 const uint64_t l = lhs->second.size;
00094 const uint64_t r = rhs->second.size;
00095
00096 if (l < r)
00097 return true;
00098 return l == r? lhs->first < rhs->first: false;
00099 }
00100
00101 inline
00102 sta_counters::
00103 avg_rate_less::avg_rate_less(const on_off_data* ood): ood_ (ood)
00104 {
00105 }
00106
00107 inline
00108 bool
00109 sta_counters::
00110 avg_rate_less::operator () (const states::const_iterator& lhs,
00111 const states::const_iterator& rhs) const
00112 {
00113 const double dmax = std::numeric_limits<double>::max();
00114
00115 const double l_on = ood_->time_on(lhs->first).get_d();
00116 const double r_on = ood_->time_on(rhs->first).get_d();
00117
00118 const double l = l_on? lhs->second.size / l_on: dmax;
00119 const double r = r_on? rhs->second.size / r_on: dmax;
00120
00121 if (l < r)
00122 return true;
00123 return l == r? lhs->first < rhs->first: false;
00124 }
00125
00126 inline
00127 sta_counters::
00128 time_on_less::time_on_less(const on_off_data* ood): ood_ (ood)
00129 {
00130 }
00131
00132 inline
00133 bool
00134 sta_counters::
00135 time_on_less::operator () (const states::const_iterator& lhs,
00136 const states::const_iterator& rhs) const
00137 {
00138 const tool::microseconds l = ood_->time_on(lhs->first);
00139 const tool::microseconds r = ood_->time_on(rhs->first);
00140
00141 if (l < r)
00142 return true;
00143 return l == r? lhs->first < rhs->first: false;
00144 }
00145
00146 template <class Set>
00147 std::ostream&
00148 sta_counters::print(std::ostream& os,
00149 const std::string& name,
00150 const Set& set) const
00151 {
00152 const double step = 1 / double (set.size());
00153
00154 boost::format fmt ("%17s %11s %11s %11s %11s %11s %11s"
00155 " %11s %11s\n");
00156 double prop = 0;
00157 double size_cumul = 0;
00158 double avg_rate_cumul = 0;
00159
00160 os << " begin " << name << '\n';
00161
00162 for (typename Set::const_reverse_iterator i = set.rbegin();
00163 i != set.rend();
00164 ++i)
00165 {
00166 const double ton = ood_->time_on((*i)->first).get_d();
00167 const double size = (*i)->second.size;
00168 const double count = (*i)->second.count;
00169
00170 assert(size);
00171
00172
00173
00174
00175
00176 const double avg_rate = size / ton;
00177 const double avg_fptu = count / ton;
00178
00179 prop += step;
00180 size_cumul += size;
00181 avg_rate_cumul += avg_rate;
00182
00183 os << (fmt % (*i)->first % size % avg_rate % ton
00184 % prop % size_cumul % avg_rate_cumul
00185 % count % avg_fptu);
00186 }
00187 return os << " end " << name << '\n';
00188 }
00189
00190 template <class Less>
00191 std::set<sta_counters::states::const_iterator, Less>
00192 sta_counters::sorted_states(const Less& less) const
00193 {
00194 std::set<states::const_iterator, Less> r (less);
00195
00196 for (states::const_iterator i = states_.begin();
00197 i != states_.end();
00198 ++i)
00199 r.insert(i);
00200
00201 return r;
00202 }
00203
00204 }
00205
00206 }
00207
00208 }
00209
00210 #endif // ! WIFI_STATS_STA_COUNTERS_HXX_