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_STATS_STA_COUNTERS_HXX_
00023 # define WIFI_FRAME_STATS_STA_COUNTERS_HXX_
00024
00025 # include <boost/foreach.hpp>
00026 # include <boost/format.hpp>
00027
00028 # include <wipal/wifi/frame/stats/sta_counters.hh>
00029
00030 namespace wifi
00031 {
00032
00033 namespace frame
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\n");
00155 double prop = 0;
00156 double size_cumul = 0;
00157 double avg_rate_cumul = 0;
00158
00159 os << " begin " << name << '\n';
00160
00161 for (typename Set::const_reverse_iterator i = set.rbegin();
00162 i != set.rend();
00163 ++i)
00164 {
00165 const double ton = ood_->time_on((*i)->first).get_d();
00166 const double size = (*i)->second.size;
00167
00168 assert(size);
00169
00170
00171
00172
00173
00174 const double avg_rate = size / ton;
00175
00176 prop += step;
00177 size_cumul += size;
00178 avg_rate_cumul += avg_rate;
00179
00180 os << (fmt % (*i)->first % size % avg_rate % ton
00181 % prop % size_cumul % avg_rate_cumul);
00182 }
00183 return os << " end " << name << '\n';
00184 }
00185
00186 template <class Less>
00187 std::set<sta_counters::states::const_iterator, Less>
00188 sta_counters::sorted_states(const Less& less) const
00189 {
00190 std::set<states::const_iterator, Less> r (less);
00191
00192 for (states::const_iterator i = states_.begin();
00193 i != states_.end();
00194 ++i)
00195 r.insert(i);
00196
00197 return r;
00198 }
00199
00200 }
00201
00202 }
00203
00204 }
00205
00206 #endif // ! WIFI_FRAME_STATS_STA_COUNTERS_HXX_