00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef QOLYESTER_DAEMON_GRA_GRAPH_HXX
00020 # define QOLYESTER_DAEMON_GRA_GRAPH_HXX 1
00021
00022 # include "config.hh"
00023 # include <cassert>
00024 # include "graph.hh"
00025 # include "utl/mark.hh"
00026
00027 namespace olsr {
00028
00029 extern utl::Mark routes_recomp;
00030
00031 namespace gra {
00032
00033
00034 AdjInfo::AdjInfo()
00035 : _ep1(),
00036 _ep2(),
00037 _tag(topo)
00038 {}
00039
00040 AdjInfo::AdjInfo(const address_t& ep1, const address_t& ep2, AdjTag tag)
00041 : _ep1(ep1),
00042 _ep2(ep2),
00043 _tag(tag)
00044 {}
00045
00046
00047 bool
00048 AdjInfo::operator==(const This& rhs) const {
00049 return _ep1 == rhs._ep1 && _ep2 == rhs._ep2 && _tag == rhs._tag;
00050 }
00051
00052 const AdjInfo&
00053 AdjInfo::make_key(const address_t& ep1, const address_t& ep2, AdjTag tag) {
00054 const_cast<address_t&>(_dummy_for_find._ep1) = ep1;
00055 const_cast<address_t&>(_dummy_for_find._ep2) = ep2;
00056 const_cast<AdjTag&>(_dummy_for_find._tag) = tag;
00057 return _dummy_for_find;
00058 }
00059
00060 AdjInfo
00061 AdjInfo::invert(const This& x) {
00062 return This(x._ep2, x._ep1, x._tag);
00063 }
00064
00065
00066 AdjNode::AdjNode() : _endpoint(), _weight(0) {}
00067
00068 AdjNode::AdjNode(const address_t& ep, unsigned w)
00069 : _endpoint(ep),
00070 _weight(w)
00071 {}
00072
00073
00074 bool
00075 AdjNode::operator==(const This& rhs) const {
00076 return _endpoint == rhs._endpoint;
00077 }
00078
00079 const AdjNode&
00080 AdjNode::make_key(const address_t& ep) {
00081 const_cast<address_t&>(_dummy_for_find._endpoint) = ep;
00082 return _dummy_for_find;
00083 }
00084
00085
00086 AdjGraph::AdjGraph()
00087 : _aset(),
00088 _nset(),
00089 _apset_map()
00090 {}
00091
00092 AdjGraph::AdjGraph(const This& other)
00093 : _aset(other._aset),
00094 _nset(other._nset),
00095 _apset_map() {
00096
00097 build_asetmap();
00098 }
00099
00100 AdjGraph&
00101 AdjGraph::operator=(const This& other) {
00102 _aset = other._aset;
00103 _nset = other._nset;
00104 _apset_map.clear();
00105
00106 build_asetmap();
00107 return *this;
00108 }
00109
00110 std::pair<AdjGraph::nset_t::const_iterator, bool>
00111 AdjGraph::insert_node(const AdjNode& n) {
00112
00113 std::pair<nset_t::iterator, bool> p =
00114 nset_t::iterator::build(_nset.insert(n));
00115
00116
00117 if (p.second) {
00118 # ifndef NDEBUG
00119 assert(_apset_map.insert(apsetmap_t::value_type(&*p.first,
00120 apset_t())).second);
00121 # else
00122 _apset_map.insert(apsetmap_t::value_type(&*p.first, apset_t()));
00123 # endif
00124 }
00125
00126 assert(_apset_map.find(&*p.first) != _apset_map.end());
00127 return p;
00128 }
00129
00130 std::pair<AdjGraph::aset_t::const_iterator, bool>
00131 AdjGraph::insert_arc(const AdjInfo& a) {
00132
00133 nset_t::const_iterator n1 = _nset.find(AdjNode::make_key(a.endpoint1()));
00134 nset_t::const_iterator n2 = _nset.find(AdjNode::make_key(a.endpoint2()));
00135
00136 assert(n1 != _nset.end());
00137 assert(n2 != _nset.end());
00138
00139 std::pair<aset_t::iterator, bool> p = _aset.insert(a);
00140
00141
00142
00143 if (p.second) {
00144 _apset_map[&*n1].insert(&*p.first);
00145 _apset_map[&*n2].insert(&*p.first);
00146 }
00147 return p;
00148 }
00149
00150
00151
00152 void
00153 AdjGraph::insert_edge(const AdjInfo& a) {
00154 insert_arc(a);
00155 insert_arc(AdjInfo::invert(a));
00156 }
00157
00158 void
00159 AdjGraph::remove_arc(aset_t::iterator pos) {
00160
00161 assert(pos != _aset.end());
00162
00163 nset_t::const_iterator n1 = _nset.find(AdjNode::make_key(pos->endpoint1()));
00164 nset_t::const_iterator n2 = _nset.find(AdjNode::make_key(pos->endpoint2()));
00165
00166 assert(n1 != _nset.end());
00167 assert(n2 != _nset.end());
00168
00169 _apset_map[&*n1].erase(&*pos);
00170 _apset_map[&*n2].erase(&*pos);
00171
00172 _aset.erase(pos);
00173 }
00174
00175
00176
00177 void
00178 AdjGraph::remove_arc(const AdjInfo& a) {
00179 aset_t::iterator pos = _aset.find(a);
00180 if (pos != _aset.end())
00181 remove_arc(pos);
00182 }
00183
00184
00185
00186 void
00187 AdjGraph::remove_edge(aset_t::iterator pos) {
00188 remove_arc(AdjInfo::invert(*pos));
00189 remove_arc(pos);
00190 }
00191
00192
00193
00194 void
00195 AdjGraph::remove_edge(const AdjInfo& a) {
00196 remove_arc(a);
00197 remove_arc(AdjInfo::invert(a));
00198 }
00199
00200
00201
00202
00203 void
00204 AdjGraph::remove_arc_then_node(aset_t::iterator pos) {
00205 nset_t::iterator n1 = _nset.find(AdjNode::make_key(pos->endpoint1()));
00206 nset_t::iterator n2 = _nset.find(AdjNode::make_key(pos->endpoint2()));
00207 assert(n1 != _nset.end());
00208 assert(n2 != _nset.end());
00209 remove_arc(pos);
00210 if (_apset_map[&*n1].size() == 0)
00211 remove_node(n1);
00212 if (_apset_map[&*n2].size() == 0)
00213 remove_node(n2);
00214 }
00215
00216
00217 void
00218 AdjGraph::remove_arc_then_node(const AdjInfo& a) {
00219 aset_t::iterator pos = _aset.find(a);
00220 if (pos != _aset.end())
00221 remove_arc_then_node(pos);
00222 }
00223
00224
00225 void
00226 AdjGraph::remove_edge_then_node(aset_t::iterator pos) {
00227 remove_arc_then_node(AdjInfo::invert(*pos));
00228 remove_arc_then_node(pos);
00229 }
00230
00231
00232 void
00233 AdjGraph::remove_edge_then_node(const AdjInfo& a) {
00234 remove_arc_then_node(a);
00235 remove_arc_then_node(AdjInfo::invert(a));
00236 }
00237
00238
00239
00240 void
00241 AdjGraph::remove_node(nset_t::iterator pos) {
00242
00243 assert(pos != _nset.end());
00244
00245 routes_recomp.set_mark();
00246
00247 apsetmap_t::iterator ap = _apset_map.find(&*pos);
00248
00249 assert(ap != _apset_map.end());
00250
00251 apset_t& pos_as = ap->second;
00252 for (apset_t::iterator i = pos_as.begin(); i != pos_as.end(); ++i) {
00253
00254 nset_t::const_iterator other;
00255 if (pos->endpoint() == (*i)->endpoint1())
00256 other = _nset.find(AdjNode::make_key((*i)->endpoint2()));
00257 else
00258 other = _nset.find(AdjNode::make_key((*i)->endpoint1()));
00259
00260 assert(other != _nset.end());
00261
00262 apsetmap_t::iterator ap2 = _apset_map.find(&*other);
00263
00264 assert(ap2 != _apset_map.end());
00265
00266 ap2->second.erase(*i);
00267
00268 _aset.erase(**i);
00269 }
00270
00271 _apset_map.erase(&*pos);
00272
00273 _nset.erase(pos);
00274 }
00275
00276
00277 void
00278 AdjGraph::remove_node(const AdjNode& n) {
00279 nset_t::iterator pos = _nset.find(n);
00280 if (pos != _nset.end())
00281 remove_node(pos);
00282 }
00283
00284 void
00285 AdjGraph::remove_node_if_alone(nset_t::iterator pos) {
00286 assert(pos != _nset.end());
00287 if (_apset_map[&*pos].empty())
00288 remove_node(pos);
00289 }
00290
00291
00292 void
00293 AdjGraph::remove_node_if_alone(const AdjNode& n) {
00294 nset_t::iterator pos = _nset.find(n);
00295 if (pos != _nset.end())
00296 remove_node_if_alone(pos);
00297 }
00298
00299
00300 void
00301 AdjGraph::build_asetmap() {
00302
00303 for (aset_t::const_iterator a = _aset.begin(); a != _aset.end(); ++a) {
00304
00305 nset_t::const_iterator n1 = _nset.find(AdjNode::make_key(a->endpoint1()));
00306 nset_t::const_iterator n2 = _nset.find(AdjNode::make_key(a->endpoint2()));
00307
00308 assert(n1 != _nset.end());
00309 assert(n2 != _nset.end());
00310
00311 _apset_map[&*n1].insert(&*a);
00312 _apset_map[&*n2].insert(&*a);
00313 }
00314 }
00315
00316 }
00317
00318 }
00319
00320 #endif // ! QOLYESTER_DAEMON_GRA_GRAPH_HXX