00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef QOLYESTER_DAEMON_ALG_MPRSELECTION_HXX
00020 # define QOLYESTER_DAEMON_ALG_MPRSELECTION_HXX 1
00021
00022 # include "set/neighbors.hh"
00023
00024 # include "mprselection.hh"
00025
00026 namespace olsr {
00027
00028 extern thnset_t thn_set;
00029 extern utl::Mark advset_changed;
00030
00031 namespace alg {
00032
00033
00034
00035
00036 void mprselection()
00037 {
00038 debug << "SELECTING MPRs" << std::endl;
00039
00040
00041
00042
00043 typedef std::set<address_t> aset_t;
00044
00045
00046 typedef std::map<address_t, aset_t> thnsimpleset_t;
00047
00048
00049
00050 typedef std::set<const set::Neighbor*, utl::pless<set::Neighbor> >
00051 nset_t;
00052
00053
00054
00055 typedef utl::DerefIterator<nset_t::const_iterator>
00056 nset_const_iterator;
00057
00058
00059
00060 typedef std::map<address_t, unsigned> degreemap_t;
00061
00062
00063
00064 typedef std::map<address_t, aset_t> coverermap_t;
00065
00066 aset_t mprs;
00067 aset_t total_n2;
00068 nset_t rcandidates;
00069 thnsimpleset_t thns;
00070
00071
00072
00073
00074
00075
00076
00077 for (thnset_t::thnset_t::iterator t = thn_set.thnset().begin();
00078 t != thn_set.thnset().end(); ++t) {
00079 cproxy_t::sym_neighborset_t::iterator n =
00080 cproxy.sym_neighborset().find(set::Neighbor::make_key(t->main_addr()));
00081 if (n == cproxy.sym_neighborset().end() ||
00082 n->willingness() == WILL_NEVER)
00083 continue;
00084 if (cproxy.sym_neighborset().find(set::Neighbor::make_key(t->twohop_addr())) !=
00085 cproxy.sym_neighborset().end())
00086 continue;
00087 thns[t->main_addr()].insert(t->twohop_addr());
00088 total_n2.insert(t->twohop_addr());
00089 }
00090
00091 # ifdef QOLYESTER_ENABLE_MID
00092
00093
00094 for (ifaceset_t::const_iterator i = iface_set.begin();
00095 i != iface_set.end();
00096 ++i) {
00097
00098 # else // ! QOLYESTER_ENABLE_MID
00099
00100 {
00101 iface_t* i = &this_interface;
00102
00103 # endif
00104
00105 thnsimpleset_t lthns;
00106 nset_t candidates;
00107
00108
00109 for (thnsimpleset_t::const_iterator oh = thns.begin();
00110 oh != thns.end(); ++oh) {
00111 cproxy_t::sym_neighborset_t::iterator n =
00112 cproxy.sym_neighborset().find(set::Neighbor::make_key(oh->first));
00113 assert(n != cproxy.sym_neighborset().end());
00114 std::pair<set::Neighbor::linkset_t::iterator,
00115 set::Neighbor::linkset_t::iterator> er =
00116 n->find_lifaces(i->addr());
00117 bool sym_found = false;
00118 for (set::Neighbor::linkset_t::iterator l = er.first;
00119 l != er.second; ++l)
00120 if (l->is_sym()) {
00121 sym_found = true;
00122 break;
00123 }
00124 if (!sym_found)
00125 continue;
00126 lthns[oh->first] = oh->second;
00127 candidates.insert(&*n);
00128 }
00129
00130 # ifdef QOLYESTER_ENABLE_MID
00131 aset_t lmprs;
00132 # else // ! QOLYESTER_ENABLE_MID
00133 aset_t& lmprs = mprs;
00134 # endif
00135 degreemap_t degree_map;
00136 coverermap_t coverer_map;
00137 aset_t n2;
00138
00139
00140 for (thnsimpleset_t::const_iterator oh = lthns.begin();
00141 oh != lthns.end(); ++oh) {
00142
00143 degree_map[oh->first] = oh->second.size();
00144
00145 for (aset_t::const_iterator th = oh->second.begin();
00146 th != oh->second.end(); ++th) {
00147 coverer_map[*th].insert(oh->first);
00148 n2.insert(*th);
00149 }
00150 }
00151
00152
00153
00154
00155
00156 for (nset_const_iterator n =
00157 nset_const_iterator::build(candidates.begin());
00158 n != nset_const_iterator::build(candidates.end()); ++n)
00159 if (n->willingness() == WILL_ALWAYS)
00160 lmprs.insert(n->main_addr());
00161
00162
00163 for (coverermap_t::const_iterator c = coverer_map.begin();
00164 c != coverer_map.end(); ++c)
00165 if (c->second.size() <= mprcoverage) {
00166 lmprs.insert(c->second.begin(), c->second.end());
00167 n2.erase(c->first);
00168 }
00169
00170
00171
00172
00173
00174
00175 typedef std::map<address_t, unsigned> reachcount_t;
00176 reachcount_t reachcount;
00177
00178 for (aset_t::const_iterator m = lmprs.begin();
00179 m != lmprs.end(); ++m) {
00180 candidates.erase(&set::Neighbor::make_key(*m));
00181 thnsimpleset_t::const_iterator oh = lthns.find(*m);
00182 assert(oh != lthns.end());
00183 for (aset_t::const_iterator th = oh->second.begin();
00184 th != oh->second.end(); ++th)
00185 if (++reachcount[*th] >= mprcoverage)
00186 n2.erase(*th);
00187 }
00188
00189
00190
00191 thnsimpleset_t rthns;
00192
00193 for (thnsimpleset_t::const_iterator oh = lthns.begin();
00194 oh != lthns.end(); ++oh)
00195 for (aset_t::const_iterator th = oh->second.begin();
00196 th != oh->second.end(); ++th)
00197 if (n2.find(*th) != n2.end())
00198 rthns[oh->first].insert(*th);
00199
00200
00201 while (!n2.empty()) {
00202
00203 typedef std::map<address_t, unsigned> reachmap_t;
00204 reachmap_t reachmap;
00205
00206
00207 for (nset_const_iterator n =
00208 nset_const_iterator::build(candidates.begin());
00209 n != nset_const_iterator::build(candidates.end()); ++n)
00210 reachmap[n->main_addr()] = rthns[n->main_addr()].size();
00211
00212
00213
00214 bool first = true;
00215 const set::Neighbor* maxn = 0;
00216 unsigned r = 0;
00217 unsigned d = 0;
00218
00219 for (nset_const_iterator n =
00220 nset_const_iterator::build(candidates.begin());
00221 n != nset_const_iterator::build(candidates.end()); ++n) {
00222 unsigned n_r = reachmap[n->main_addr()];
00223 if (first ||
00224 n->willingness() > maxn->willingness() ||
00225 (n->willingness() == maxn->willingness() &&
00226 (n_r > r ||
00227 n_r == r && degree_map[n->main_addr()] > d))) {
00228 first = false;
00229 maxn = &*n;
00230 r = n_r;
00231 d = degree_map[n->main_addr()];
00232 }
00233 }
00234
00235 assert(!first);
00236
00237
00238
00239 aset_t& a_thns = lthns[maxn->main_addr()];
00240 for (aset_t::const_iterator th = a_thns.begin();
00241 th != a_thns.end(); ++th) {
00242 if (++reachcount[*th] >= mprcoverage)
00243 n2.erase(*th);
00244 }
00245
00246
00247 lmprs.insert(maxn->main_addr());
00248
00249
00250 rcandidates.insert(maxn);
00251 candidates.erase(maxn);
00252 }
00253
00254 # ifdef QOLYESTER_ENABLE_MID
00255
00256 mprs.insert(lmprs.begin(), lmprs.end());
00257 # endif
00258
00259 }
00260
00261
00262
00263
00264 std::map<address_t, unsigned> covcount_map;
00265 for (aset_t::const_iterator m = mprs.begin(); m != mprs.end(); ++m) {
00266 const aset_t& m_thns = thns[*m];
00267 for (aset_t::const_iterator th = m_thns.begin(); th != m_thns.end(); ++th)
00268 ++covcount_map[*th];
00269 }
00270
00271
00272
00273 typedef std::multimap<unsigned, address_t> wmap_t;
00274 wmap_t wmap;
00275 for (nset_const_iterator rc =
00276 nset_const_iterator::build(rcandidates.begin());
00277 rc != nset_const_iterator::build(rcandidates.end()); ++rc)
00278 wmap.insert(wmap_t::value_type(rc->willingness(), rc->main_addr()));
00279
00280
00281
00282
00283
00284 for (wmap_t::const_iterator rc = wmap.begin(); rc != wmap.end(); ++rc) {
00285 aset_t& rc_thns = thns[rc->second];
00286 bool remove = true;
00287 for (aset_t::const_iterator th = rc_thns.begin(); th != rc_thns.end(); ++th)
00288 if (covcount_map[*th] <= mprcoverage) {
00289 remove = false;
00290 break;
00291 }
00292 if (remove)
00293 mprs.erase(rc->second);
00294 }
00295
00296 bool changed = false;
00297
00298
00299 for (cproxy_t::sym_neighborset_t::iterator n =
00300 cproxy.sym_neighborset().begin();
00301 n != cproxy.sym_neighborset().end(); ++n) {
00302 if (n->is_mpr()) {
00303 if (mprs.find(n->main_addr()) == mprs.end()) {
00304 cproxy.unset_mpr(n);
00305 changed = true;
00306 }
00307 } else
00308 if (mprs.find(n->main_addr()) != mprs.end()) {
00309 cproxy.set_mpr(n);
00310 changed = true;
00311 }
00312 }
00313
00314 if (changed) {
00315 routes_recomp.set_mark();
00316 if (tc_redundancy >= mprselset_mprset)
00317 advset_changed.set_mark();
00318 }
00319 }
00320
00321 }
00322
00323 }
00324
00325 #endif // !QOLYESTER_DAEMON_ALG_MPRSELECTION_HXX