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 degreemap_t degree_map;
00108 coverermap_t coverer_map;
00109 aset_t n2;
00110
00111
00112 for (thnsimpleset_t::const_iterator oh = thns.begin();
00113 oh != thns.end(); ++oh) {
00114 cproxy_t::sym_neighborset_t::iterator n =
00115 cproxy.sym_neighborset().find(set::Neighbor::make_key(oh->first));
00116 assert(n != cproxy.sym_neighborset().end());
00117 std::pair<set::Neighbor::linkset_t::iterator,
00118 set::Neighbor::linkset_t::iterator> er =
00119 n->find_lifaces(i->addr());
00120 bool sym_found = false;
00121 for (set::Neighbor::linkset_t::iterator l = er.first;
00122 l != er.second; ++l)
00123 if (l->is_sym()) {
00124 sym_found = true;
00125 break;
00126 }
00127 if (!sym_found)
00128 continue;
00129 candidates.insert(&*n);
00130 lthns.insert(*oh);
00131 degree_map[oh->first] = oh->second.size();
00132 for (aset_t::const_iterator th = oh->second.begin();
00133 th != oh->second.end(); ++th) {
00134 coverer_map[*th].insert(oh->first);
00135 n2.insert(*th);
00136 }
00137 }
00138
00139 # ifdef QOLYESTER_ENABLE_MID
00140 aset_t lmprs;
00141 # else // ! QOLYESTER_ENABLE_MID
00142 aset_t& lmprs = mprs;
00143 # endif
00144
00145
00146
00147
00148
00149 for (nset_const_iterator n =
00150 nset_const_iterator::build(candidates.begin());
00151 n != nset_const_iterator::build(candidates.end()); ++n)
00152 if (n->willingness() == WILL_ALWAYS)
00153 lmprs.insert(n->main_addr());
00154
00155
00156
00157 for (coverermap_t::const_iterator c = coverer_map.begin();
00158 c != coverer_map.end(); ++c)
00159 if (c->second.size() <= mprcoverage) {
00160 lmprs.insert(c->second.begin(), c->second.end());
00161 n2.erase(c->first);
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171 typedef std::map<address_t, unsigned> reachcount_t;
00172 reachcount_t reachcount;
00173 thnsimpleset_t rthns = lthns;
00174
00175 for (aset_t::const_iterator m = lmprs.begin();
00176 m != lmprs.end(); ++m) {
00177 candidates.erase(&set::Neighbor::make_key(*m));
00178 thnsimpleset_t::const_iterator oh = rthns.find(*m);
00179 assert(oh != rthns.end());
00180 const aset_t& to_update = oh->second;
00181 for (aset_t::const_iterator th = to_update.begin();
00182 th != to_update.end(); ++th)
00183 if (++reachcount[*th] >= mprcoverage) {
00184 n2.erase(*th);
00185 for (thnsimpleset_t::iterator i = rthns.begin();
00186 i != rthns.end(); ++i)
00187 if (i->first != *m)
00188 i->second.erase(*th);
00189 }
00190 }
00191
00192
00193 while (!n2.empty()) {
00194
00195 typedef std::map<address_t, unsigned> reachmap_t;
00196 reachmap_t reachmap;
00197
00198
00199 for (nset_const_iterator n =
00200 nset_const_iterator::build(candidates.begin());
00201 n != nset_const_iterator::build(candidates.end()); ++n)
00202 reachmap[n->main_addr()] = rthns[n->main_addr()].size();
00203
00204
00205
00206 bool first = true;
00207 const set::Neighbor* maxn = 0;
00208 unsigned r = 0;
00209 unsigned d = 0;
00210
00211 for (nset_const_iterator n =
00212 nset_const_iterator::build(candidates.begin());
00213 n != nset_const_iterator::build(candidates.end()); ++n) {
00214 unsigned n_r = reachmap[n->main_addr()];
00215 if (first ||
00216 n->willingness() > maxn->willingness() ||
00217 (n->willingness() == maxn->willingness() &&
00218 (n_r > r ||
00219 n_r == r && degree_map[n->main_addr()] > d))) {
00220 first = false;
00221 maxn = &*n;
00222 r = n_r;
00223 d = degree_map[n->main_addr()];
00224 }
00225 }
00226
00227 assert(!first);
00228
00229
00230
00231 const aset_t& to_update = rthns[maxn->main_addr()];
00232 for (aset_t::const_iterator th = to_update.begin();
00233 th != to_update.end(); ++th) {
00234 if (++reachcount[*th] >= mprcoverage) {
00235 n2.erase(*th);
00236 for (thnsimpleset_t::iterator i = rthns.begin();
00237 i != rthns.end(); ++i)
00238 if (i->first != maxn->main_addr())
00239 i->second.erase(*th);
00240 }
00241 }
00242
00243
00244 lmprs.insert(maxn->main_addr());
00245
00246
00247 rcandidates.insert(maxn);
00248 candidates.erase(maxn);
00249 }
00250
00251 # ifdef QOLYESTER_ENABLE_MID
00252
00253 mprs.insert(lmprs.begin(), lmprs.end());
00254 # endif
00255
00256 }
00257
00258
00259
00260
00261 std::map<address_t, unsigned> covcount_map;
00262 for (aset_t::const_iterator m = mprs.begin(); m != mprs.end(); ++m) {
00263 const aset_t& m_thns = thns[*m];
00264 for (aset_t::const_iterator th = m_thns.begin(); th != m_thns.end(); ++th)
00265 ++covcount_map[*th];
00266 }
00267
00268
00269
00270 typedef std::multimap<unsigned, address_t> wmap_t;
00271 wmap_t wmap;
00272 for (nset_const_iterator rc =
00273 nset_const_iterator::build(rcandidates.begin());
00274 rc != nset_const_iterator::build(rcandidates.end()); ++rc)
00275 wmap.insert(wmap_t::value_type(rc->willingness(), rc->main_addr()));
00276
00277
00278
00279
00280
00281 for (wmap_t::const_iterator rc = wmap.begin(); rc != wmap.end(); ++rc) {
00282 aset_t& rc_thns = thns[rc->second];
00283 bool remove = true;
00284 for (aset_t::const_iterator th = rc_thns.begin(); th != rc_thns.end(); ++th)
00285 if (covcount_map[*th] <= mprcoverage) {
00286 remove = false;
00287 break;
00288 }
00289 if (remove) {
00290 for (aset_t::const_iterator th = rc_thns.begin();
00291 th != rc_thns.end(); ++th)
00292 --covcount_map[*th];
00293 mprs.erase(rc->second);
00294 }
00295 }
00296
00297 bool changed = false;
00298
00299
00300 for (cproxy_t::sym_neighborset_t::iterator n =
00301 cproxy.sym_neighborset().begin();
00302 n != cproxy.sym_neighborset().end(); ++n) {
00303 if (n->is_mpr()) {
00304 if (mprs.find(n->main_addr()) == mprs.end()) {
00305 cproxy.unset_mpr(n);
00306 changed = true;
00307 }
00308 } else
00309 if (mprs.find(n->main_addr()) != mprs.end()) {
00310 cproxy.set_mpr(n);
00311 changed = true;
00312 }
00313 }
00314
00315 if (changed) {
00316 routes_recomp.set_mark();
00317 if (tc_redundancy >= mprselset_mprset)
00318 advset_changed.set_mark();
00319 }
00320 }
00321
00322 }
00323
00324 }
00325
00326 #endif // !QOLYESTER_DAEMON_ALG_MPRSELECTION_HXX