00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef QOLYESTER_DAEMON_SET_NEIGHBORS_HXX
00020 # define QOLYESTER_DAEMON_SET_NEIGHBORS_HXX 1
00021
00022 # include "alg/mainaddrof.hh"
00023 # include "gra/graph.hh"
00024 # include "utl/mark.hh"
00025
00026 namespace olsr {
00027
00028 extern sched_t scheduler;
00029 extern utl::Mark mprset_recomp;
00030 extern utl::Mark advset_changed;
00031 extern pathnet_t path_net;
00032 extern cproxy_t cproxy;
00033
00034 namespace set {
00035
00036 # ifdef QOLYESTER_ENABLE_LINKHYS
00037 Link::LinkQuality::LinkQuality(Link& i, float v)
00038 : value_(v),
00039 instance_(i),
00040 expired_(0),
00041 blocked_(false) {
00042 assert(0.f <= v && v <= 1.f);
00043 }
00044
00045 Link::LinkQuality&
00046 Link::LinkQuality::operator++() {
00047
00048 debug << up << "LinkQuality::++(): " << instance_.main_addr()
00049 << " " << of(value_) << " -> ";
00050 value_ *= 1 - HYST_SCALING;
00051 value_ += HYST_SCALING;
00052 debug << of(value_) << std::endl;
00053 update();
00054 return *this;
00055 }
00056
00057 Link::LinkQuality&
00058 Link::LinkQuality::operator--() {
00059 if (blocked_) {
00060 debug << up << "LinkQuality::--(): " << instance_.main_addr()
00061 << " " << of(value_) << " not changed since blocked"
00062 << std::endl;
00063 blocked_ = false;
00064 return *this;
00065 }
00066
00067 debug << up << "LinkQuality::--(): " << instance_.main_addr()
00068 << " " << of(value_) << " -> ";
00069 value_ *= 1 - HYST_SCALING;
00070 debug << of(value_) << std::endl;
00071 update();
00072 return *this;
00073 }
00074
00075 void
00076 Link::LinkQuality:: update() {
00077 if (value_ > HYST_THRESHOLD_HIGH) {
00078 instance_.set_pending(false);
00079 instance_.set_losttime(timeval_t::now() - 1000);
00080 } else if (value_ < HYST_THRESHOLD_LOW && !instance_.pending()) {
00081 instance_.set_pending(true);
00082 instance_.set_losttime(timeval_t::now() + cst::neighb_hold_time);
00083 if (instance_.time() < instance_.losttime())
00084 instance_.set_losttime(instance_.time());
00085 }
00086 }
00087
00088 Link::Link()
00089 : l_addr_(),
00090 r_addr_(),
00091 m_addr_(),
00092 asymtime_(0),
00093 symtime_(0),
00094 time_(0),
00095 losttime_(0),
00096 nexttime_(0),
00097 htime_(0),
00098 pending_(false),
00099 quality_(*this, 0),
00100 last_seqnum_(0)
00101 {}
00102
00103 Link::Link(const address_t& l, const address_t& r, const address_t& m,
00104 const timeval_t& v, const seqnum_t& s, const timeval_t& ht)
00105 : l_addr_(l),
00106 r_addr_(r),
00107 m_addr_(m),
00108 asymtime_(0),
00109 symtime_(timeval_t::now() - 1000),
00110 time_(timeval_t::in(v)),
00111 losttime_(timeval_t::now() - 1000),
00112 nexttime_(timeval_t::now() - 1000),
00113 htime_(ht),
00114 pending_(true),
00115 quality_(*this),
00116 last_seqnum_(s)
00117 {}
00118
00119 Link::Link(const This& other)
00120 : Super(other),
00121 l_addr_(other.l_addr_),
00122 r_addr_(other.r_addr_),
00123 m_addr_(other.m_addr_),
00124 asymtime_(other.asymtime_),
00125 symtime_(other.symtime_),
00126 time_(other.time_),
00127 losttime_(other.losttime_),
00128 nexttime_(other.nexttime_),
00129 htime_(other.htime_),
00130 pending_(other.pending_),
00131 quality_(*this, other.quality_),
00132 last_seqnum_(other.last_seqnum_)
00133 {}
00134
00135 void
00136 Link::set_last_seqnum(const seqnum_t& s) {
00137 if (s != ++last_seqnum_) {
00138 debug << "--quality(" << m_addr_ << "): lost packet (expected "
00139 << last_seqnum_ << ", but got " << s << ")" << std::endl;
00140 quality_.lost(s > last_seqnum_ ? s - last_seqnum_ : 0);
00141 --quality_;
00142 cproxy.update_state(main_addr());
00143 last_seqnum_ = s;
00144 } else
00145 quality_.lost(0);
00146
00147 ++quality_;
00148 cproxy.update_state(main_addr());
00149 }
00150 # else // !QOLYESTER_ENABLE_LINKHYS
00151 Link::Link()
00152 : l_addr_(),
00153 r_addr_(),
00154 m_addr_(),
00155 asymtime_(0),
00156 symtime_(0),
00157 time_(0)
00158 {}
00159
00160 Link::Link(const address_t& l, const address_t& r, const address_t& m,
00161 const timeval_t& v)
00162 : l_addr_(l),
00163 r_addr_(r),
00164 m_addr_(m),
00165 asymtime_(0),
00166 symtime_(timeval_t::now() - 1000),
00167 time_(timeval_t::in(v))
00168 {}
00169
00170 Link::Link(const This& other)
00171 : Super(other),
00172 l_addr_(other.l_addr_),
00173 r_addr_(other.r_addr_),
00174 m_addr_(other.m_addr_),
00175 asymtime_(other.asymtime_),
00176 symtime_(other.symtime_),
00177 time_(other.time_)
00178 {}
00179 # endif
00180
00181
00182 bool
00183 Link::is_valid() const { return !time_.is_past(); }
00184
00185 bool
00186 Link::is_sym() const {
00187 # ifdef QOLYESTER_ENABLE_LINKHYS
00188 return losttime_.is_past() && !pending_ && !symtime_.is_past();
00189 # else // !QOLYESTER_ENABLE_LINKHYS
00190 return !symtime_.is_past();
00191 # endif
00192 }
00193
00194
00195 bool
00196 Link::operator<(const This& rhs) const {
00197 if (l_addr_ == rhs.l_addr_)
00198 return r_addr_ < rhs.r_addr_;
00199 return l_addr_ < rhs.l_addr_;
00200 }
00201
00202
00203 const Link&
00204 Link::make_key(const address_t& local, const address_t& remote) {
00205 const_cast<address_t&>(dummy_for_find_.l_addr_) = local;
00206 const_cast<address_t&>(dummy_for_find_.r_addr_) = remote;
00207 return dummy_for_find_;
00208 }
00209
00210 const Link&
00211 Link::make_key_local(const address_t& local) {
00212 const_cast<address_t&>(dummy_for_find_.l_addr_) = local;
00213 return dummy_for_find_;
00214 }
00215
00216 namespace upd {
00217
00218 void
00219 LinkUpdater::operator()() {
00220 # ifdef QOLYESTER_ENABLE_LINKHYS
00221 if (iter_->nexttime().is_past()) {
00222 debug << up << "--quality(" << iter_->main_addr()
00223 << "): expired nexttime by "
00224 << iter_->nexttime().diff() << std::endl;
00225 const_cast<elem_t&>(*iter_).quality().expire();
00226 --const_cast<elem_t&>(*iter_).quality();
00227 const_cast<elem_t&>(*iter_).set_nexttime(iter_->nexttime() +
00228 iter_->htime() * 1.1);
00229 }
00230 # endif // !QOLYESTER_ENABLE_LINKHYS
00231 if (iter_->is_valid()) {
00232 set_.update_state(iter_->main_addr());
00233 sch::TimedEvent* e = iter_->updater();
00234 scheduler.erase(e);
00235 e->set_next(min_time(*iter_));
00236 scheduler.insert(e);
00237 } else
00238 set_.erase(iter_);
00239 }
00240
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 Neighbor::Neighbor()
00370 : m_addr_(),
00371 lset_(),
00372 val_lset_(*this, lset_),
00373 sym_(false),
00374 mpr_(false),
00375 mprsel_time_(0, 0),
00376 was_mprsel_(false),
00377 willingness_(0)
00378 {}
00379
00380 Neighbor::Neighbor(const address_t& maddr,
00381 const std::set<ulink_t>::iterator& i,
00382 unsigned w)
00383 : m_addr_(maddr),
00384 lset_(),
00385 val_lset_(*this, lset_),
00386 sym_(false),
00387 mpr_(false),
00388 mprsel_time_(timeval_t::now() - 1000),
00389 was_mprsel_(false),
00390 willingness_(w) {
00391 lset_.insert(i);
00392 }
00393
00394 Neighbor::Neighbor(const This& other)
00395 : Super(other),
00396 m_addr_(other.m_addr_),
00397 lset_(other.lset_),
00398 val_lset_(*this, lset_),
00399 sym_(other.sym_),
00400 mpr_(other.mpr_),
00401 mprsel_time_(other.mprsel_time_),
00402 was_mprsel_(other.was_mprsel_),
00403 willingness_(other.willingness_)
00404 {}
00405
00406 void
00407 Neighbor::set_willingness(unsigned w) {
00408 willingness_ = w;
00409 }
00410
00411 bool
00412 Neighbor::is_mprsel() const {
00413 return !mprsel_time_.is_past();
00414 }
00415
00416 bool
00417 Neighbor::was_mprsel() {
00418 if (was_mprsel_) {
00419 was_mprsel_ = false;
00420 return true;
00421 }
00422 return false;
00423 }
00424
00425 void
00426 Neighbor::set_mprsel(const timeval_t& validity) {
00427 mprsel_time_ = timeval_t::in(validity);
00428 if (is_mprsel())
00429 was_mprsel_ = true;
00430 }
00431
00432 void
00433 Neighbor::unset_mprsel() {
00434 mprsel_time_ = timeval_t::now() - 1000;
00435 }
00436
00437 std::pair<Neighbor::linkset_t::const_iterator,
00438 Neighbor::linkset_t::const_iterator>
00439 Neighbor::find_lifaces(const address_t& laddr) const {
00440 return const_cast<linkset_t&>(val_lset_).equal_range(Link::make_key_local(laddr));
00441 }
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453 void
00454 Neighbor::insert(const std::set<ulink_t>::iterator& pos) {
00455 lset_.insert(pos);
00456 }
00457
00458 void
00459 Neighbor::erase(const lset_t::iterator& pos) {
00460 lset_.erase(pos);
00461 }
00462
00463 void
00464 Neighbor::erase(const std::set<ulink_t>::iterator& pos) {
00465 lset_.erase(pos);
00466 }
00467
00468 bool
00469 Neighbor::operator<(const This& rhs) const {
00470 return m_addr_ < rhs.m_addr_;
00471 }
00472
00473 const Neighbor&
00474 Neighbor::make_key(const address_t& m) {
00475 const_cast<address_t&>(dummy_for_find_.m_addr_) = m;
00476 return dummy_for_find_;
00477 }
00478
00479 namespace upd {
00480
00481 void
00482 NeighborUpdater::operator()() {
00483 set_.unset_mprsel(iter_);
00484 }
00485
00486 }
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585 CoherenceProxy::CoherenceProxy()
00586 : lset_(),
00587 nset_(),
00588 linkset_(lset_),
00589 idx_lset_(lset_),
00590 hello_linkset_(idx_lset_),
00591 neighborset_(*this, nset_),
00592 sym_neighborset_(neighborset_),
00593 idx_nset_(nset_),
00594 val_idx_nset_(*this, idx_nset_),
00595 tc_neighborset_(val_idx_nset_),
00596 advset_seqnum_(0),
00597 advset_changed_(false),
00598 sym_count_(0),
00599 mpr_count_(0),
00600 mprsel_empty_(true)
00601 {}
00602
00603 CoherenceProxy::~CoherenceProxy() {
00604 while (!lset_.empty())
00605 erase(lset_.begin());
00606 }
00607
00608 # ifdef QOLYESTER_ENABLE_LINKHYS
00609 std::pair<CoherenceProxy::neighborset_t::iterator, bool>
00610 CoherenceProxy::insert_link(const msg::Message::header& mh,
00611 const int linktype,
00612 const int will,
00613 const timeval_t& htime) {
00614
00615
00616 std::pair<lset_t::iterator, bool> lp =
00617 lset_.insert(Link(mh.receiver, mh.sender,
00618 mh.originator, mh.validity,
00619 mh.pseqnum, htime));
00620 # else // !QOLYESTER_ENABLE_LINKHYS
00621 std::pair<CoherenceProxy::neighborset_t::iterator, bool>
00622 CoherenceProxy::insert_link(const msg::Message::header& mh,
00623 const int linktype,
00624 const int will) {
00625
00626
00627 std::pair<lset_t::iterator, bool> lp =
00628 lset_.insert(Link(mh.receiver, mh.sender,
00629 mh.originator, mh.validity));
00630 # endif
00631 std::pair<nset_t::iterator, bool> np =
00632 nset_.insert(Neighbor(mh.originator, lp.first, will));
00633
00634 Link& l = const_cast<Link&>(static_cast<const Link&>(*lp.first));
00635
00636
00637
00638
00639
00640
00641
00642
00643 if (lp.second) {
00644 idx_lset_.insert(lp.first);
00645 if (np.second) {
00646 idx_nset_.insert(np.first);
00647 } else
00648 const_cast<uneighbor_t&>(*np.first).insert(lp.first);
00649 } else {
00650 # ifdef QOLYESTER_ENABLE_LINKHYS
00651 l.set_htime(htime);
00652 # endif // !QOLYESTER_ENABLE_LINKHYS
00653 }
00654
00655 if (!np.second)
00656 set_willingness(np.first, will);
00657
00658
00659 l.set_asymtime(timeval_t::in(mh.validity));
00660
00661
00662 switch (linktype) {
00663 case LOST_LINK:
00664 l.set_symtime(timeval_t::now() - 1000);
00665 break;
00666 case SYM_LINK:
00667 case ASYM_LINK:
00668 l.set_symtime(timeval_t::in(mh.validity));
00669 l.set_time(lp.first->symtime() + cst::neighb_hold_time);
00670 break;
00671 }
00672
00673 if (l.time() < l.asymtime())
00674 l.set_time(l.asymtime());
00675
00676 typedef upd::LinkUpdater lu_t;
00677
00678 sch::TimedEvent* e = lp.first->updater();
00679
00680 if (e == 0) {
00681 e = new link_updater_t(lu_t::min_time(l),
00682 lu_t(*this, lp.first));
00683 const_cast<ulink_t&>(*lp.first).set_updater(e);
00684 } else {
00685 scheduler.erase(e);
00686 e->set_next(lu_t::min_time(l));
00687 }
00688 scheduler.insert(e);
00689
00690 update_state(np.first);
00691
00692 typedef std::pair<neighborset_t::iterator, bool> ret_t;
00693
00694
00695
00696
00697 return ret_t(neighborset_t::iterator::
00698 build(neighborset_t::mask_iterator(np.first, nset_, *this)),
00699 np.second);
00700
00701 }
00702
00703 void
00704 CoherenceProxy::set_willingness(const nset_t::iterator& pos,
00705 unsigned w) {
00706 if (pos->willingness() != w) {
00707 mprset_recomp.set_mark();
00708 const_cast<uneighbor_t&>(*pos).set_willingness(w);
00709 update_graph(pos);
00710 }
00711 }
00712
00713 void
00714 CoherenceProxy::update_graph(const nset_t::iterator& pos) {
00715 unsigned w = pos->willingness();
00716 if (pos->is_sym() && w > WILL_NEVER) {
00717 unsigned new_weight = w + pos->is_mpr() ? WILL_DEFAULT : 0;
00718 std::pair<gra::AdjGraph::nset_t::const_iterator, bool> p =
00719 path_net.insert_node(gra::AdjNode(pos->main_addr(), new_weight));
00720 if (!p.second)
00721 const_cast<gra::AdjNode&>(*p.first).set_weight(new_weight);
00722 } else {
00723 gra::AdjGraph::nset_t::iterator x =
00724 gra::AdjGraph::nset_t::iterator::build(path_net.nodes().find(gra::AdjNode::make_key(pos->main_addr())));
00725 if (x != path_net.nodes().end()) {
00726 x->set_weight(pos->is_sym() ? w : 1);
00727 if (!pos->is_sym())
00728 path_net.remove_node_if_alone(x);
00729 }
00730 }
00731 }
00732
00733 bool
00734 CoherenceProxy::update_state(const nset_t::iterator& pos) {
00735 assert(pos != nset_.end());
00736 bool sym = false;
00737 bool valid = false;
00738
00739
00740 for (Neighbor::linkset_t::iterator i =
00741 const_cast<uneighbor_t&>(*pos).linkset().begin();
00742 i != const_cast<uneighbor_t&>(*pos).linkset().end(); ++i) {
00743 valid = true;
00744 if (i->is_sym() && !sym)
00745 sym = true;
00746 }
00747 if (sym) {
00748 set_sym(pos);
00749 } else {
00750 unset_sym(pos);
00751 }
00752
00753
00754 return valid;
00755 }
00756
00757 void
00758 CoherenceProxy::update_state(const address_t& maddr) {
00759 nset_t::iterator x = nset_.find(Neighbor::make_key(maddr));
00760 if (x != nset_.end())
00761 update_state(x);
00762 }
00763
00764 void
00765 CoherenceProxy::set_sym(const nset_t::iterator& pos) {
00766 assert(pos != nset_.end());
00767 if (!pos->is_sym()) {
00768 ++sym_count_;
00769 const_cast<uneighbor_t&>(*pos).set_sym(true);
00770 mprset_recomp.set_mark();
00771 routes_recomp.set_mark();
00772 update_graph(pos);
00773 if (tc_redundancy == wholeset) {
00774 advset_changed_ = true;
00775 advset_changed.set_mark();
00776 }
00777 }
00778 }
00779
00780 void
00781 CoherenceProxy::unset_sym(const nset_t::iterator& pos) {
00782 assert(pos != nset_.end());
00783 if (pos->is_sym()) {
00784 unset_mpr(pos);
00785 unset_mprsel(pos);
00786 --sym_count_;
00787 const_cast<uneighbor_t&>(*pos).set_sym(false);
00788 mprset_recomp.set_mark();
00789 routes_recomp.set_mark();
00790 update_graph(pos);
00791 if (tc_redundancy == wholeset) {
00792 advset_changed_ = true;
00793 advset_changed.set_mark();
00794 }
00795 }
00796 }
00797
00798 void
00799 CoherenceProxy::set_mpr(const nset_t::iterator& pos) {
00800 assert(pos != nset_.end());
00801 assert(pos->is_sym());
00802 if (!pos->is_mpr()) {
00803 ++mpr_count_;
00804 const_cast<uneighbor_t&>(*pos).set_mpr(true);
00805 update_graph(pos);
00806 if (tc_redundancy >= mprselset_mprset) {
00807 advset_changed_ = true;
00808 advset_changed.set_mark();
00809 }
00810 }
00811 }
00812
00813 void
00814 CoherenceProxy::set_mpr(const sym_neighborset_t::iterator& pos) {
00815 set_mpr(pos.mask_super().mask_super());
00816 }
00817
00818 void
00819 CoherenceProxy::unset_mpr(const nset_t::iterator& pos) {
00820 assert(pos != nset_.end());
00821 assert(pos->is_sym());
00822 if (pos->is_mpr()) {
00823 --mpr_count_;
00824 const_cast<uneighbor_t&>(*pos).set_mpr(false);
00825 update_graph(pos);
00826 if (tc_redundancy >= mprselset_mprset) {
00827 advset_changed_ = true;
00828 advset_changed.set_mark();
00829 }
00830 }
00831 }
00832
00833 void
00834 CoherenceProxy::unset_mpr(const sym_neighborset_t::iterator& pos) {
00835 unset_mpr(pos.mask_super().mask_super());
00836 }
00837
00838 void
00839 CoherenceProxy::set_mprsel(const nset_t::iterator& pos,
00840 const timeval_t& v) {
00841 assert(pos != nset_.end());
00842
00843 if (!pos->is_sym())
00844 return;
00845 assert(timeval_t(0) < v);
00846 if (!pos->is_mprsel()) {
00847 mprsel_empty_ = false;
00848 advset_changed_ = true;
00849 advset_changed.set_mark();
00850 }
00851 const_cast<uneighbor_t&>(*pos).set_mprsel(v);
00852 typedef upd::NeighborUpdater nu_t;
00853 sch::TimedEvent* e = pos->updater();
00854 if (e == 0) {
00855 e = new neighbor_updater_t(timeval_t::in(v), nu_t(*this, pos));
00856 const_cast<uneighbor_t&>(*pos).set_updater(e);
00857 } else {
00858 scheduler.erase(e);
00859 e->set_next(timeval_t::in(v));
00860 }
00861 scheduler.insert(e);
00862 }
00863
00864 void
00865 CoherenceProxy::unset_mprsel(const nset_t::iterator& pos) {
00866 assert(pos != nset_.end());
00867
00868 sch::TimedEvent* e = pos->updater();
00869 if (pos->is_mprsel()) {
00870 assert(e != 0);
00871 scheduler.destroy(e);
00872 const_cast<uneighbor_t&>(*pos).set_updater(0);
00873 const_cast<uneighbor_t&>(*pos).unset_mprsel();
00874 } else if (e != 0) {
00875 scheduler.destroy(e);
00876 const_cast<uneighbor_t&>(*pos).set_updater(0);
00877 }
00878
00879 if (const_cast<uneighbor_t&>(*pos).was_mprsel()) {
00880 advset_changed_ = true;
00881 advset_changed.set_mark();
00882 }
00883
00884
00885
00886
00887
00888
00889
00890 }
00891
00892 bool
00893 CoherenceProxy::is_advset_empty() {
00894 if (mprsel_empty_)
00895 return true;
00896 mprsel_empty_ = true;
00897 for (sym_neighborset_t::iterator i = sym_neighborset_.begin();
00898 i != sym_neighborset_.end(); ++i)
00899 if (i->is_mprsel()) {
00900 mprsel_empty_ = false;
00901 break;
00902 }
00903 return mprsel_empty_;
00904 }
00905
00906 bool
00907 CoherenceProxy::is_valid(const nset_t::iterator& pos) {
00908 return update_state(pos);
00909 }
00910
00911 bool
00912 CoherenceProxy::is_valid(const idx_nset_t::iterator& pos) {
00913 return update_state(*pos.deref_super());
00914 }
00915
00916 void
00917 CoherenceProxy::erase(lset_t::iterator pos) {
00918 nset_t::iterator npos =
00919 nset_.find(Neighbor::make_key(pos->main_addr()));
00920 if (npos != nset_.end()) {
00921 const_cast<uneighbor_t&>(*npos).erase(pos);
00922 if (!is_valid(npos))
00923 erase_from_all(npos);
00924 }
00925
00926
00927
00928 idx_lset_.erase(pos);
00929 lset_.erase(pos);
00930 }
00931
00932 void
00933 CoherenceProxy::erase_from_all(nset_t::iterator pos) {
00934
00935
00936 unset_sym(pos);
00937
00938 idx_nset_.erase(pos);
00939
00940 nset_.erase(pos);
00941 }
00942
00943 void
00944 CoherenceProxy::add_interface(const address_t& a) {
00945 idx_lset_.add_key(a);
00946 idx_nset_.add_key(a);
00947 }
00948
00949 void
00950 CoherenceProxy::remove_interface(const address_t& a) {
00951 for (linkset_t::iterator i = linkset_.begin(); i != linkset_.end();
00952 )
00953 if (i->local_addr() == a) {
00954 linkset_t::iterator tmp = i++;
00955 erase(tmp);
00956 }
00957 idx_lset_.remove_key(a);
00958 idx_nset_.remove_key(a);
00959 }
00960
00961
00962
00963
00964
00965
00966 TwoHopNeighbor::TwoHopNeighbor() :
00967 mainaddr_(),
00968 twohopaddr_(),
00969 time_(0, 0)
00970 {}
00971
00972 TwoHopNeighbor::TwoHopNeighbor(const address_t& a,
00973 const address_t& tha,
00974 const timeval_t& validity) :
00975 mainaddr_(a),
00976 twohopaddr_(tha),
00977 time_(timeval_t::in(validity))
00978 {}
00979
00980 bool
00981 TwoHopNeighbor::operator<(const This& rhs) const {
00982 if (mainaddr_ == rhs.mainaddr_)
00983 return twohopaddr_ < rhs.twohopaddr_;
00984 return mainaddr_ < rhs.mainaddr_;
00985 }
00986
00987 TwoHopNeighbor&
00988 TwoHopNeighbor::operator=(const This& other) {
00989 assert(mainaddr_ == other.mainaddr_);
00990 assert(twohopaddr_ == other.twohopaddr_);
00991 time_ = other.time_;
00992 return *this;
00993 }
00994
00995 const TwoHopNeighbor&
00996 TwoHopNeighbor::make_key(const address_t& ma, const address_t& tha) {
00997 const_cast<address_t&>(dummy_for_find_.mainaddr_) = ma;
00998 const_cast<address_t&>(dummy_for_find_.twohopaddr_) = tha;
00999 return dummy_for_find_;
01000 }
01001
01002 TwoHopNeighborSet::TwoHopNeighborSet()
01003 : tset_(),
01004 thnset_(*this, tset_)
01005 {}
01006
01007 void
01008 TwoHopNeighborSet::insert(const TwoHopNeighbor& x) {
01009 std::pair<tset_t::iterator, bool> p = tset_.insert(x);
01010 if (!p.second) {
01011 sch::TimedEvent* e = p.first->updater();
01012 scheduler.erase(e);
01013 e->set_next(x.time());
01014 scheduler.insert(e);
01015
01016 const_cast<elem_t&>(*p.first).set_time(x.time());
01017 } else {
01018 if (cproxy.sym_neighborset().find(Neighbor::make_key(alg::main_addr_of(x.twohop_addr()))) == cproxy.sym_neighborset().end())
01019 mprset_recomp.set_mark();
01020 routes_recomp.set_mark();
01021 sch::TimedEvent* e = new updater_t(x.time(),
01022 eraser_t(*this, p.first));
01023 const_cast<elem_t&>(*p.first).set_updater(e);
01024 scheduler.insert(e);
01025 path_net.insert_node(gra::AdjNode(x.twohop_addr()));
01026 path_net.insert_arc(gra::AdjInfo(x.main_addr(),
01027 x.twohop_addr(),
01028 twohop));
01029 }
01030 }
01031
01032 void
01033 TwoHopNeighborSet::erase(const tset_t::iterator& pos) {
01034 assert(pos != tset_.end());
01035 bool is_1hop_sym =
01036 cproxy.sym_neighborset().find(Neighbor::make_key(pos->twohop_addr()))
01037 != cproxy.sym_neighborset().end();
01038 path_net.remove_arc(gra::AdjInfo::make_key(pos->main_addr(),
01039 pos->twohop_addr(),
01040 twohop));
01041 if (!is_1hop_sym)
01042 path_net.remove_node_if_alone(gra::AdjNode::make_key(pos->twohop_addr()));
01043 if (!is_1hop_sym)
01044 mprset_recomp.set_mark();
01045 routes_recomp.set_mark();
01046 sch::TimedEvent* e = pos->updater();
01047 tset_.erase(pos);
01048 scheduler.destroy(e);
01049 }
01050
01051 void
01052 TwoHopNeighborSet::erase(const tset_t::value_type& x) {
01053 tset_t::iterator pos = tset_.find(x);
01054 if (pos != tset_.end())
01055 erase(pos);
01056 }
01057
01058 }
01059
01060 }
01061
01062 #endif // ! QOLYESTER_DAEMON_SET_NEIGHBORS_HXX