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

graph.hh

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 
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       AdjInfo(const address_t& ep1, const address_t& ep2, AdjTag tag = topo);
00079 
00085       const address_t&  endpoint1() const { return _ep1; }
00086 
00092       const address_t&  endpoint2() const { return _ep2; }
00093 
00094       AdjTag            tag() const { return _tag; }
00095 
00104       bool              operator==(const This& rhs) const;
00105 
00106       std::string       to_string() const
00107       {
00108         std::stringstream       s;
00109         s << "{ " << _ep1 << " -- " << _tag << " --> " << _ep2 << " }";
00110         return s.str();
00111       }
00112 
00122       static const This&        make_key(const address_t& ep1,
00123                                          const address_t& ep2,
00124                                          AdjTag tag = topo);
00125 
00132       static This               invert(const This& x);
00133     private:
00134       const address_t   _ep1;   
00135       const address_t   _ep2;   
00136       const AdjTag      _tag;
00137 
00138       static This       _dummy_for_find; 
00139     };
00140 
00145     struct hash_AdjInfo
00146     {
00147       ::size_t operator()(const AdjInfo& a) const
00148       {
00149         return std::hash<address_t>()(a.endpoint1()) +
00150           std::hash<address_t>()(a.endpoint2());
00151       }
00152       ::size_t operator()(const AdjInfo* a) const
00153       {
00154         return std::hash<address_t>()(a->endpoint1()) +
00155           std::hash<address_t>()(a->endpoint2());
00156       }
00157     };
00158 
00165     class AdjNode
00166     {
00167       typedef AdjNode                                   This;
00168 
00175       explicit AdjNode();
00176     public:
00182       AdjNode(const address_t& ep, unsigned w = 1);
00183 
00189       const address_t&  endpoint() const { return _endpoint; }
00195       unsigned          weight() const { return _weight; }
00196 
00202       void              set_weight(unsigned w) { _weight = w; }
00203 
00212       bool              operator==(const This& rhs) const;
00213 
00214       std::string       to_string() const
00215       {
00216         std::stringstream       s;
00217         s << "{ " << _endpoint << " " << _weight << " }";
00218         return s.str();
00219       }
00220 
00229       static const This&        make_key(const address_t& ep);
00230     private:
00231       const address_t   _endpoint; 
00232       unsigned          _weight; 
00233 
00234       static This       _dummy_for_find; 
00235     };
00236 
00241     struct hash_AdjNode
00242     {
00243       ::size_t operator()(const AdjNode& a) const
00244       {
00245         return std::hash<address_t>()(a.endpoint());
00246       }
00247       ::size_t operator()(const AdjNode* a) const
00248       {
00249         return std::hash<address_t>()(a->endpoint());
00250       }
00251     };
00252 
00253     namespace internal {
00254       typedef std::hash_set<AdjInfo, hash_AdjInfo>      iset_t;
00255       typedef iset_t::const_iterator                    iset_const_iterator;
00256       typedef utl::DeconstIterator<iset_const_iterator> iset_iterator;
00257 
00258       typedef std::hash_set<AdjNode, hash_AdjNode>      nset_t;
00259       typedef nset_t::const_iterator                    nset_const_iterator;
00260       typedef utl::DeconstIterator<nset_const_iterator> nset_iterator;
00261     } // namespace internal
00262 
00267     typedef utl::Set<AdjInfo, internal::iset_t, internal::iset_iterator>
00268     arcset_t;
00269 
00274     typedef utl::Set<AdjNode, internal::nset_t, internal::nset_iterator>
00275     nodeset_t;
00276 
00277     // This is graph /per se/.
00282     class AdjGraph
00283     {
00284       typedef AdjGraph          This;
00285 
00286       // We need a way to find all the arcs with a given node as either
00287       // endpoint quickly.  So we want a hash map (apsetmap_t)
00288       // associating a pointer to a node to a hash set of pointers to
00289       // arcs (apset_t).
00290 
00297       typedef std::hash_set<const AdjInfo*, hash_AdjInfo,
00298                             utl::pequal_to<AdjInfo> >      apset_t;
00299 
00307       typedef std::hash_map<const AdjNode*, apset_t, hash_AdjNode,
00308                             utl::pequal_to<AdjNode> >      apsetmap_t;
00309     public:
00310       // The sets of actual nodes and arcs
00315       typedef arcset_t          aset_t;
00316 
00321       typedef nodeset_t         nset_t;
00322 
00323       std::string       to_string() const
00324       {
00325         std::stringstream       s;
00326         s << "AdjGraph {\n";
00327         if (_nset.empty())
00328           s << "  nodes {}\n";
00329         else {
00330           s << "  nodes {\n";
00331           for (nset_t::const_iterator i = _nset.begin(); i != _nset.end(); ++i)
00332             s << "    " << i->to_string() << "\n";
00333           s << "  }\n";
00334         }
00335         if (_aset.empty())
00336           s << "  arcs {}\n";
00337         else {
00338           s << "  arcs {\n";
00339           for (aset_t::const_iterator i = _aset.begin(); i != _aset.end(); ++i)
00340             s << "    " << i->to_string() << "\n";
00341           s << "  }\n";
00342         }
00343         s << "}";
00344         return s.str();
00345       }
00346 
00350       AdjGraph();
00351 
00355       AdjGraph(const This& other);
00356 
00360       This&             operator=(const This& other);
00361 
00367       const aset_t&     arcs() const { return _aset; }
00368 
00374       const nset_t&     nodes() const { return _nset; }
00375 
00381       std::pair<nset_t::const_iterator, bool>   insert_node(const AdjNode& n);
00382 
00388       std::pair<aset_t::const_iterator, bool>   insert_arc(const AdjInfo& a);
00389 
00395       void              insert_edge(const AdjInfo& a);
00396 
00402       void              remove_arc(aset_t::iterator pos);
00403 
00409       void              remove_arc(const AdjInfo& a);
00410 
00416       void              remove_edge(aset_t::iterator pos);
00417 
00423       void              remove_edge(const AdjInfo& a);
00424 
00431       void              remove_arc_then_node(aset_t::iterator pos);
00432 
00439       void              remove_arc_then_node(const AdjInfo& a);
00440 
00448       void              remove_edge_then_node(aset_t::iterator pos);
00449 
00457       void              remove_edge_then_node(const AdjInfo& a);
00458 
00464       void              remove_node(nset_t::iterator pos);
00465 
00471       void              remove_node(const AdjNode& n);
00472 
00473       void              remove_node_if_alone(nset_t::iterator pos);
00474 
00480       void              remove_node_if_alone(const AdjNode& n);
00481 
00482     private:
00486       void              build_asetmap();
00487 
00488       aset_t            _aset;          
00489       nset_t            _nset;          
00490       apsetmap_t        _apset_map;     
00491     };
00492 
00493     inline
00494     std::ostream& operator<<(std::ostream& o, const AdjGraph& g)
00495     {
00496       return o << g.to_string();
00497     }
00498 
00499   } // namespace gra
00500 
00501   using gra::topo;
00502   using gra::twohop;
00503 
00504   typedef gra::AdjGraph pathnet_t;
00505 
00506 } // namespace olsr
00507 
00508 # ifndef QOLYESTER_DONTINCLUDE_HXX
00509 #  include "graph.hxx"
00510 # endif
00511 
00512 #endif // ! QOLYESTER_DAEMON_GRA_GRAPH_HH

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