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