graph.hh

Go to the documentation of this file.
00001 // Copyright (C) 2003-2006 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 
00031 
00032 #ifndef QOLYESTER_DAEMON_GRA_GRAPH_HH
00033 # define QOLYESTER_DAEMON_GRA_GRAPH_HH 1
00034 
00035 # include <string>
00036 # include <ext/hash_map>
00037 # include <sstream>
00038 # include <ostream>
00039 # include "net/ipaddress.hh"
00040 # include "utl/iterator.hh"
00041 # include "utl/set.hh"
00042 
00043 // These are the graph-specific declarations.  The directed graph is
00044 // implemented as an adjacency hash table, to allow quick access.
00045 
00046 namespace olsr {
00047 
00048   namespace gra {
00049 
00050     enum AdjTag { topo = 0, twohop = 1 };
00051 
00059     class AdjInfo
00060     {
00061       typedef AdjInfo   This;
00062 
00069       explicit AdjInfo();
00070     public:
00078       inline AdjInfo(const address_t& ep1, const address_t& ep2,
00079                      AdjTag tag = topo);
00080 
00086       const address_t&  endpoint1() const { return _ep1; }
00087 
00093       const address_t&  endpoint2() const { return _ep2; }
00094 
00095       AdjTag            tag() const { return _tag; }
00096 
00105       inline bool       operator==(const This& rhs) const;
00106 
00107       std::string       to_string() const
00108       {
00109         std::stringstream       s;
00110         s << "{ " << _ep1 << " -- " << _tag << " --> " << _ep2 << " }";
00111         return s.str();
00112       }
00113 
00123       static inline const This& make_key(const address_t& ep1,
00124                                          const address_t& ep2,
00125                                          AdjTag tag = topo);
00126 
00133       static inline This        invert(const This& x);
00134     private:
00135       const address_t   _ep1;   
00136       const address_t   _ep2;   
00137       const AdjTag      _tag;
00138 
00139       static This       _dummy_for_find; 
00140     };
00141 
00146     struct hash_AdjInfo
00147     {
00148       ::size_t operator()(const AdjInfo& a) const
00149       {
00150         return std::hash<address_t>()(a.endpoint1()) ^
00151           std::hash<address_t>()(a.endpoint2());
00152       }
00153       ::size_t operator()(const AdjInfo* a) const
00154       {
00155         return std::hash<address_t>()(a->endpoint1()) ^
00156           std::hash<address_t>()(a->endpoint2());
00157       }
00158     };
00159 
00166     class AdjNode
00167     {
00168       typedef AdjNode                                   This;
00169 
00176       explicit inline AdjNode();
00177     public:
00183       inline AdjNode(const address_t& ep, unsigned w = 1);
00184 
00190       const address_t&  endpoint() const { return _endpoint; }
00196       unsigned          weight() const { return _weight; }
00197 
00203       void              set_weight(unsigned w) { _weight = w; }
00204 
00213       inline bool       operator==(const This& rhs) const;
00214 
00215       std::string       to_string() const
00216       {
00217         std::stringstream       s;
00218         s << "{ " << _endpoint << ' ' << _weight << " }";
00219         return s.str();
00220       }
00221 
00230       static inline const This& make_key(const address_t& ep);
00231     private:
00232       const address_t   _endpoint; 
00233       unsigned          _weight; 
00234 
00235       static This       _dummy_for_find; 
00236     };
00237 
00242     struct hash_AdjNode
00243     {
00244       ::size_t operator()(const AdjNode& a) const
00245       {
00246         return std::hash<address_t>()(a.endpoint());
00247       }
00248       ::size_t operator()(const AdjNode* a) const
00249       {
00250         return std::hash<address_t>()(a->endpoint());
00251       }
00252     };
00253 
00254     namespace internal {
00255       typedef std::hash_set<AdjInfo, hash_AdjInfo>      iset_t;
00256       typedef iset_t::const_iterator                    iset_const_iterator;
00257       typedef utl::DeconstIterator<iset_const_iterator> iset_iterator;
00258 
00259       typedef std::hash_set<AdjNode, hash_AdjNode>      nset_t;
00260       typedef nset_t::const_iterator                    nset_const_iterator;
00261       typedef utl::DeconstIterator<nset_const_iterator> nset_iterator;
00262     } // namespace internal
00263 
00268     typedef utl::Set<AdjInfo, internal::iset_t, internal::iset_iterator>
00269     arcset_t;
00270 
00275     typedef utl::Set<AdjNode, internal::nset_t, internal::nset_iterator>
00276     nodeset_t;
00277 
00278     // This is graph /per se/.
00283     class AdjGraph
00284     {
00285       typedef AdjGraph          This;
00286 
00287       // We need a way to find all the arcs with a given node as either
00288       // endpoint quickly.  So we want a hash map (apsetmap_t)
00289       // associating a pointer to a node to a hash set of pointers to
00290       // arcs (apset_t).
00291 
00298       typedef std::hash_set<const AdjInfo*, hash_AdjInfo,
00299                             utl::pequal_to<AdjInfo> >      apset_t;
00300 
00308       typedef std::hash_map<const AdjNode*, apset_t, hash_AdjNode,
00309                             utl::pequal_to<AdjNode> >      apsetmap_t;
00310     public:
00311       // The sets of actual nodes and arcs
00316       typedef arcset_t          aset_t;
00317 
00322       typedef nodeset_t         nset_t;
00323 
00324       std::string       to_string() const
00325       {
00326         std::stringstream       s;
00327         s << "AdjGraph {\n";
00328         if (_nset.empty())
00329           s << "  nodes {}\n";
00330         else {
00331           s << "  nodes {\n";
00332           for (nset_t::const_iterator i = _nset.begin(); i != _nset.end(); ++i)
00333             s << "    " << i->to_string() << '\n';
00334           s << "  }\n";
00335         }
00336         if (_aset.empty())
00337           s << "  arcs {}\n";
00338         else {
00339           s << "  arcs {\n";
00340           for (aset_t::const_iterator i = _aset.begin(); i != _aset.end(); ++i)
00341             s << "    " << i->to_string() << '\n';
00342           s << "  }\n";
00343         }
00344         s << '}';
00345         return s.str();
00346       }
00347 
00351       inline AdjGraph();
00352 
00356       inline AdjGraph(const This& other);
00357 
00361       inline This&      operator=(const This& other);
00362 
00368       const aset_t&     arcs() const { return _aset; }
00369 
00375       const nset_t&     nodes() const { return _nset; }
00376 
00382       inline
00383       std::pair<nset_t::const_iterator, bool>   insert_node(const AdjNode& n);
00384 
00390       inline
00391       std::pair<aset_t::const_iterator, bool>   insert_arc(const AdjInfo& a);
00392 
00398       inline void       insert_edge(const AdjInfo& a);
00399 
00405       inline void       remove_arc(aset_t::iterator pos);
00406 
00412       inline void       remove_arc(const AdjInfo& a);
00413 
00419       inline void       remove_edge(aset_t::iterator pos);
00420 
00426       inline void       remove_edge(const AdjInfo& a);
00427 
00434       inline void       remove_arc_then_node(aset_t::iterator pos);
00435 
00442       inline void       remove_arc_then_node(const AdjInfo& a);
00443 
00451       inline void       remove_edge_then_node(aset_t::iterator pos);
00452 
00460       inline void       remove_edge_then_node(const AdjInfo& a);
00461 
00467       inline void       remove_node(nset_t::iterator pos);
00468 
00474       inline void       remove_node(const AdjNode& n);
00475 
00476       inline void       remove_node_if_alone(nset_t::iterator pos);
00477 
00483       inline void       remove_node_if_alone(const AdjNode& n);
00484 
00485     private:
00489       inline void       build_asetmap();
00490 
00491       aset_t            _aset;          
00492       nset_t            _nset;          
00493       apsetmap_t        _apset_map;     
00494     };
00495 
00496     inline
00497     std::ostream& operator<<(std::ostream& o, const AdjGraph& g)
00498     {
00499       return o << g.to_string();
00500     }
00501 
00502   } // namespace gra
00503 
00504   using gra::topo;
00505   using gra::twohop;
00506 
00507   typedef gra::AdjGraph pathnet_t;
00508 
00509 } // namespace olsr
00510 
00511 # include "graph.hxx"
00512 
00513 #endif // ! QOLYESTER_DAEMON_GRA_GRAPH_HH

Generated on Mon Sep 10 17:02:11 2007 for Qolyester daemon by  doxygen 1.5.1