Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

neighbors.hxx

Go to the documentation of this file.
00001 // Copyright (C) 2003, 2004, 2005 Laboratoire de Recherche en Informatique
00002 
00003 // This file is part of Qolyester.
00004 
00005 // Qolyester is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 // Qolyester is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
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 //       blocked_ = true;
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       } /* else {} */
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     // Simple validity checker
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     // Plain comparison operator
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     // Utility static method for the creation of dummy objects to search sets
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     } // namespace upd
00242 
00243 //     namespace internal {
00244 
00245 // # ifdef DEBUG
00246 //       nested_type_traits<CoherenceProxy>::
00247 //       LinkUpdater::LinkUpdater(const timeval_t& t, Set& s, const Iter& pos)
00248 //      : Super("Link", t, true),
00249 //        set_(s),
00250 //        pos_(pos)
00251 //       {}
00252 // # else // !DEBUG
00253 //       nested_type_traits<CoherenceProxy>::
00254 //       LinkUpdater::LinkUpdater(const timeval_t& t, Set& s, const Iter& pos)
00255 //      : Super(t, true),
00256 //        set_(s),
00257 //        pos_(pos)
00258 //       {}
00259 // # endif
00260 
00261 //       void
00262 //       nested_type_traits<CoherenceProxy>::
00263 //       LinkUpdater::execute() {
00264 // # ifdef QOLYESTER_ENABLE_LINKHYS
00265 //      if (pos_->nexttime().is_past()) {
00266 //        debug << up << "--quality(" << pos_->main_addr()
00267 //              << "): expired nexttime by "
00268 //              << pos_->nexttime().diff() << std::endl;
00269 //        const_cast<lelem_&>(*pos_).quality().unblock();
00270 //        --const_cast<lelem_&>(*pos_).quality();
00271 //        const_cast<lelem_&>(*pos_).quality().block();
00272 //        const_cast<lelem_&>(*pos_).set_nexttime(pos_->nexttime() +
00273 //                                                pos_->htime() * 1.1);
00274 //      }
00275 // # endif // !QOLYESTER_ENABLE_LINKHYS
00276 //      if (pos_->is_valid()) {
00277 //        set_.update_state(pos_->main_addr());
00278 // //     set_.sym_neighborset().find(Neighbor::make_key(pos_->main_addr()));
00279 //        const_cast<lelem_&>(*pos_).update();
00280 //      } else {
00281 //        set_.erase(pos_);
00282 //        //    delete this;
00283 //      }
00284 //       }
00285 
00286 //       nested_type_traits<CoherenceProxy>::
00287 //       UpdatableLink::UpdatableLink(const Super& other, Set& s)
00288 //      : Super(other),
00289 //        pos_(),
00290 //        set_instance_(&s),
00291 //        used_(false)
00292 //       {}
00293 
00294 //       nested_type_traits<CoherenceProxy>::
00295 //       UpdatableLink::UpdatableLink(const Super& other)
00296 //      : Super(other),
00297 //        pos_(),
00298 //        set_instance_(0),
00299 //        used_(false)
00300 //       {}
00301 
00302 //       nested_type_traits<CoherenceProxy>::
00303 //       UpdatableLink::~UpdatableLink() {
00304 //      if (used_) {
00305 //        Deleter*      tmp = &*pos_;
00306 //        del_set.erase(pos_);
00307 //        delete tmp;
00308 //      }
00309 //       }
00310 
00311 //       timeval_t
00312 //       nested_type_traits<CoherenceProxy>::
00313 //       UpdatableLink::min_time() const {
00314 //      timeval_t       min_time(0);
00315 //      if (!Super::time().is_past())
00316 //        min_time = Super::time();
00317 //      if (!Super::asymtime().is_past() &&
00318 //          (min_time == 0 ||
00319 //           Super::asymtime() < min_time))
00320 //        min_time = Super::asymtime();
00321 //      if (!Super::symtime().is_past() &&
00322 //          (min_time == 0 ||
00323 //           Super::symtime() < min_time))
00324 //        min_time = Super::symtime();
00325 // # ifdef QOLYESTER_ENABLE_LINKHYS
00326 //      if (!Super::losttime().is_past() &&
00327 //          (min_time == 0 ||
00328 //           Super::losttime() < min_time))
00329 //        min_time = Super::losttime();
00330 //      if (!Super::nexttime().is_past() &&
00331 //          (min_time == 0 ||
00332 //           Super::nexttime() < min_time))
00333 //        min_time = Super::nexttime();
00334 // # endif // !QOLYESTER_ENABLE_LINKHYS
00335 //      return min_time;
00336 //       }
00337 
00338 //       void
00339 //       nested_type_traits<CoherenceProxy>::
00340 //       UpdatableLink::update() {
00341 //      assert(set_instance_ != 0);
00342 //      delset_t::iterator      new_pos =
00343 //        del_set.insert(new CDel(min_time(), *set_instance_,
00344 //                                static_cast<CDel&>(*pos_).pos()));
00345 //      if (used_) {
00346 //        Deleter*      tmp = &*pos_;
00347 //        del_set.erase(pos_);
00348 //        delete tmp;
00349 //      }
00350 //      used_ = true;
00351 //      pos_ = new_pos;
00352 //       }
00353 
00354 //       void
00355 //       nested_type_traits<CoherenceProxy>::
00356 //       UpdatableLink::set_pos(const Iter& pos) {
00357 //      assert(set_instance_ != 0);
00358 //      assert(!used_);
00359 //      used_ = true;
00360 //      pos_ = del_set.insert(new CDel(min_time(), *set_instance_, pos));
00361 //       }
00362 
00363 //     } // namespace internal
00364 
00365     //********************************
00366     //*  The Neighbor class
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 //     Neighbor::linkset_t::const_iterator
00444 //     Neighbor::find_liface(const address_t& laddr) const {
00445 //       return const_cast<linkset_t&>(val_lset_).find(Link::make_key_local(laddr));
00446 //     }
00447 
00448 //     bool
00449 //     Neighbor::is_liface(const address_t& iaddr) const {
00450 //       return find_liface(iaddr) != const_cast<linkset_t&>(val_lset_).end();
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     } // namespace upd
00487 
00488 //     CoherenceProxy::
00489 // # ifdef DEBUG
00490 //     NeighborUpdater::NeighborUpdater(const timeval_t& t,
00491 //                                   Set& s,
00492 //                                   const Iter& pos)
00493 //       : Super("Neighbor", t, true),
00494 //      set_(s),
00495 //      pos_(pos)
00496 //     {}
00497 // # else // !DEBUG
00498 //     NeighborUpdater::NeighborUpdater(const timeval_t& t,
00499 //                                   Set& s,
00500 //                                   const Iter& pos)
00501 //       : Super(t, true),
00502 //      set_(s),
00503 //      pos_(pos)
00504 //     {}
00505 // # endif
00506 
00507 //     void
00508 //     CoherenceProxy::
00509 //     NeighborUpdater::execute() {
00510 //       set_.unset_mprsel(pos_);
00511 //     }
00512 
00513 //     CoherenceProxy::
00514 //     UpdatableNeighbor::UpdatableNeighbor(const This& other)
00515 //       : Super(other),
00516 //      pos_(other.pos_),
00517 //      set_instance_(other.set_instance_),
00518 //      used_(other.used_)
00519 //     {}
00520 
00521 //     CoherenceProxy::
00522 //     UpdatableNeighbor::UpdatableNeighbor(const Super& other, Set& s)
00523 //       : Super(other),
00524 //      pos_(),
00525 //      set_instance_(&s),
00526 //      used_(false)
00527 //     {}
00528 
00529 //     CoherenceProxy::
00530 //     UpdatableNeighbor::UpdatableNeighbor(const Super& other)
00531 //       : Super(other),
00532 //      pos_(),
00533 //      set_instance_(0),
00534 //      used_(false)
00535 //     {}
00536 
00537 //     CoherenceProxy::
00538 //     UpdatableNeighbor::~UpdatableNeighbor() {
00539 //       assert(!used_);
00540 //     }
00541 
00542 //     void
00543 //     CoherenceProxy::
00544 //     UpdatableNeighbor::update() {
00545 //       assert(set_instance_ != 0);
00546 //       delset_t::iterator     new_pos =
00547 //      del_set.insert(new CDel(Super::mprsel_time(), *set_instance_,
00548 //                              static_cast<CDel&>(*pos_).pos()));
00549 //       if (used_) {
00550 //      Deleter*        tmp = &*pos_;
00551 //      del_set.erase(pos_);
00552 //      delete tmp;
00553 //       }
00554 //       used_ = true;
00555 //       pos_ = new_pos;
00556 //     }
00557 
00558 //     const delset_t::iterator&
00559 //     CoherenceProxy::
00560 //     UpdatableNeighbor::del_pos() const {
00561 //       assert(used_);
00562 //       return pos_;
00563 //     }
00564 
00565 //     void
00566 //     CoherenceProxy::
00567 //     UpdatableNeighbor::set_pos(const Iter& pos) {
00568 //       assert(set_instance_ != 0);
00569 //       assert(!used_);
00570 //       used_ = true;
00571 //       pos_ = del_set.insert(new CDel(Super::mprsel_time(),
00572 //                                   *set_instance_, pos));
00573 //     }
00574 
00575 //     void
00576 //     CoherenceProxy::
00577 //     UpdatableNeighbor::unuse() {
00578 //       assert(used_);
00579 //       Deleter*       tmp = &*pos_;
00580 //       del_set.erase(pos_);
00581 //       delete tmp;
00582 //       used_ = false;
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       // Insertion/search of the link and neighbor.
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       // Insertion/search of the link and neighbor.
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       // If the previous operation appears to have been an
00637       // insertion, insert the new neighbor into idx0_nset and
00638       // idx1_nset (the sets on which HELLO::dump() and TC::dump()
00639       // will actually iterate.
00640       // Otherwise, update validity and insert the link into the
00641       // "already known" neighbor.
00642 
00643       if (lp.second) { // link is new
00644         idx_lset_.insert(lp.first);
00645         if (np.second) { // neighbor is new
00646           idx_nset_.insert(np.first);
00647         } else
00648           const_cast<uneighbor_t&>(*np.first).insert(lp.first);
00649       } else { // link is not new
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       // Update L_ASYM_time
00659       l.set_asymtime(timeval_t::in(mh.validity));
00660 
00661       // Update L_SYM_time and L_time
00662       switch (linktype) {
00663       case LOST_LINK:
00664         l.set_symtime(timeval_t::now() - 1000); // expired
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       // neighborset_t is a MaskIterator, but we don't call check()
00695       // on return, because we assume it would never erase the
00696       // freshly created/update element.
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       // The following loop has to be executed entirely without
00739       // breaking out as soon as a symmetric link is found (cleanup).
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       // Don't touch the graph here as it's taken care of in
00753       // {,un}set_{sym,mpr,mprsel} methods.
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       // This used to be an assertion, but ought to be a check.
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       //assert(pos->is_sym());
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 //       if (pos->is_used()) {
00884 // //   const NeighborUpdater&  nu = *pos->del_pos();
00885 // //   del_set.erase(pos->del_pos());
00886 // //   delete &nu;
00887 // //   del_set.shift();
00888 //      const_cast<nelem_&>(*pos).unuse();
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 //       const LinkUpdater&     lu = *pos->del_pos();
00926 //       del_set.erase(pos->del_pos());
00927 //       delete &lu;
00928       idx_lset_.erase(pos);
00929       lset_.erase(pos);
00930     }
00931 
00932     void
00933     CoherenceProxy::erase_from_all(nset_t::iterator pos) {
00934       // First call CoherenceProxy::unset_sym() to update counters
00935       // and remove the node from the graph.
00936       unset_sym(pos);
00937       // Second remove the neighbor from the indices.
00938       idx_nset_.erase(pos);
00939       // Third remove the node /per se/.
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            /* ++i */)
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     //* TwoHopNeighbor definition
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   } // namespace set
01059 
01060 } // namespace olsr
01061 
01062 #endif // ! QOLYESTER_DAEMON_SET_NEIGHBORS_HXX

Generated on Thu Jul 28 21:21:48 2005 for Qolyester daemon by  doxygen 1.4.1