blob: 85bac7256ca590e02a0c3abc56b5944467dbf688 [file] [log] [blame]
Alexander Afanasyevad3757f2012-04-17 10:27:59 -07001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2012 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 */
20
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070021#ifndef BOOST_GRAPH_NDN_GLOBAL_ROUTING_HELPER_H
22#define BOOST_GRAPH_NDN_GLOBAL_ROUTING_HELPER_H
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070023
Alexander Afanasyev6315ef72012-06-01 20:56:31 -070024/// @cond include_hidden
25
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070026#include <boost/graph/graph_traits.hpp>
27#include <boost/graph/properties.hpp>
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -070028#include <boost/ref.hpp>
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070029
Alexander Afanasyev0c395372014-12-20 15:54:02 -080030#include "ns3/ndn-face.hpp"
31#include "ns3/ndn-limits.hpp"
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070032#include "ns3/node-list.h"
33#include "ns3/channel-list.h"
Alexander Afanasyev0c395372014-12-20 15:54:02 -080034#include "../model/ndn-global-router.hpp"
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070035#include <list>
36#include <map>
37
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070038namespace boost {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070039
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080040class NdnGlobalRouterGraph {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070041public:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080042 typedef ns3::Ptr<ns3::ndn::GlobalRouter> Vertice;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070043 typedef uint16_t edge_property_type;
44 typedef uint32_t vertex_property_type;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070045
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080046 NdnGlobalRouterGraph()
47 {
48 for (ns3::NodeList::Iterator node = ns3::NodeList::Begin(); node != ns3::NodeList::End();
49 node++) {
50 ns3::Ptr<ns3::ndn::GlobalRouter> gr = (*node)->GetObject<ns3::ndn::GlobalRouter>();
51 if (gr != 0)
52 m_vertices.push_back(gr);
53 }
54
55 for (ns3::ChannelList::Iterator channel = ns3::ChannelList::Begin();
56 channel != ns3::ChannelList::End(); channel++) {
57 ns3::Ptr<ns3::ndn::GlobalRouter> gr = (*channel)->GetObject<ns3::ndn::GlobalRouter>();
58 if (gr != 0)
59 m_vertices.push_back(gr);
60 }
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070061 }
62
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080063 const std::list<Vertice>&
64 GetVertices() const
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070065 {
66 return m_vertices;
67 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080068
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070069public:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080070 std::list<Vertice> m_vertices;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070071};
72
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080073class ndn_global_router_graph_category : public virtual vertex_list_graph_tag,
74 public virtual incidence_graph_tag {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070075};
76
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070077template<>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080078struct graph_traits<NdnGlobalRouterGraph> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070079 // Graph concept
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070080 typedef NdnGlobalRouterGraph::Vertice vertex_descriptor;
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070081 typedef ns3::ndn::GlobalRouter::Incidency edge_descriptor;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070082 typedef directed_tag directed_category;
83 typedef disallow_parallel_edge_tag edge_parallel_category;
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070084 typedef ndn_global_router_graph_category traversal_category;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070085
86 // VertexList concept
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080087 typedef std::list<vertex_descriptor>::const_iterator vertex_iterator;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070088 typedef size_t vertices_size_type;
89
90 // AdjacencyGraph concept
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070091 typedef ns3::ndn::GlobalRouter::IncidencyList::iterator out_edge_iterator;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070092 typedef size_t degree_size_type;
93
94 // typedef size_t edges_size_type;
95};
96
97} // namespace boost
98
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080099namespace boost {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700100
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800101inline graph_traits<NdnGlobalRouterGraph>::vertex_descriptor
102source(graph_traits<NdnGlobalRouterGraph>::edge_descriptor e, const NdnGlobalRouterGraph& g)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700103{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800104 return e.get<0>();
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700105}
106
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800107inline graph_traits<NdnGlobalRouterGraph>::vertex_descriptor
108target(graph_traits<NdnGlobalRouterGraph>::edge_descriptor e, const NdnGlobalRouterGraph& g)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700109{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800110 return e.get<2>();
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700111}
112
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800113inline std::pair<graph_traits<NdnGlobalRouterGraph>::vertex_iterator,
114 graph_traits<NdnGlobalRouterGraph>::vertex_iterator>
115vertices(const NdnGlobalRouterGraph& g)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700116{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800117 return make_pair(g.GetVertices().begin(), g.GetVertices().end());
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700118}
119
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800120inline graph_traits<NdnGlobalRouterGraph>::vertices_size_type
121num_vertices(const NdnGlobalRouterGraph& g)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700122{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800123 return g.GetVertices().size();
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700124}
125
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800126inline std::pair<graph_traits<NdnGlobalRouterGraph>::out_edge_iterator,
127 graph_traits<NdnGlobalRouterGraph>::out_edge_iterator>
128out_edges(graph_traits<NdnGlobalRouterGraph>::vertex_descriptor u, const NdnGlobalRouterGraph& g)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700129{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800130 return std::make_pair(u->GetIncidencies().begin(), u->GetIncidencies().end());
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700131}
132
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800133inline graph_traits<NdnGlobalRouterGraph>::degree_size_type
134out_degree(graph_traits<NdnGlobalRouterGraph>::vertex_descriptor u, const NdnGlobalRouterGraph& g)
135{
136 return u->GetIncidencies().size();
137}
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700138
139//////////////////////////////////////////////////////////////
140// Property maps
141
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800142struct EdgeWeights {
143 EdgeWeights(const NdnGlobalRouterGraph& graph)
144 : m_graph(graph)
145 {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700146 }
147
148private:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800149 const NdnGlobalRouterGraph& m_graph;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700150};
151
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800152struct VertexIds {
153 VertexIds(const NdnGlobalRouterGraph& graph)
154 : m_graph(graph)
155 {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700156 }
157
158private:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800159 const NdnGlobalRouterGraph& m_graph;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700160};
161
162template<>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800163struct property_map<NdnGlobalRouterGraph, edge_weight_t> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700164 typedef const EdgeWeights const_type;
165 typedef EdgeWeights type;
166};
167
168template<>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800169struct property_map<NdnGlobalRouterGraph, vertex_index_t> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700170 typedef const VertexIds const_type;
171 typedef VertexIds type;
172};
173
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700174template<>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800175struct property_traits<EdgeWeights> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700176 // Metric property map
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800177 typedef tuple<ns3::Ptr<ns3::ndn::Face>, uint16_t, double> value_type;
178 typedef tuple<ns3::Ptr<ns3::ndn::Face>, uint16_t, double> reference;
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700179 typedef ns3::ndn::GlobalRouter::Incidency key_type;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700180 typedef readable_property_map_tag category;
181};
182
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800183const property_traits<EdgeWeights>::value_type WeightZero(0, 0, 0.0);
184const property_traits<EdgeWeights>::value_type
185 WeightInf(0, std::numeric_limits<uint16_t>::max(), 0.0);
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700186
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800187struct WeightCompare : public std::binary_function<property_traits<EdgeWeights>::reference,
188 property_traits<EdgeWeights>::reference, bool> {
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700189 bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800190 operator()(tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double> a,
191 tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double> b) const
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700192 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800193 return a.get<1>() < b.get<1>();
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700194 }
195
196 bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800197 operator()(property_traits<EdgeWeights>::reference a, uint32_t b) const
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700198 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800199 return a.get<1>() < b;
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700200 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800201
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700202 bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800203 operator()(uint32_t a, uint32_t b) const
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700204 {
205 return a < b;
206 }
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700207};
208
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800209struct WeightCombine
210 : public std::binary_function<uint32_t, property_traits<EdgeWeights>::reference, uint32_t> {
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700211 uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800212 operator()(uint32_t a, property_traits<EdgeWeights>::reference b) const
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700213 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800214 return a + b.get<1>();
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700215 }
216
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800217 tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double>
218 operator()(tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double> a,
219 property_traits<EdgeWeights>::reference b) const
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700220 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800221 if (a.get<0>() == 0)
222 return make_tuple(b.get<0>(), a.get<1>() + b.get<1>(), a.get<2>() + b.get<2>());
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700223 else
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800224 return make_tuple(a.get<0>(), a.get<1>() + b.get<1>(), a.get<2>() + b.get<2>());
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700225 }
226};
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800227
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700228template<>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800229struct property_traits<VertexIds> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700230 // Metric property map
231 typedef uint32_t value_type;
232 typedef uint32_t reference;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800233 typedef ns3::Ptr<ns3::ndn::GlobalRouter> key_type;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700234 typedef readable_property_map_tag category;
235};
236
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700237inline EdgeWeights
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800238get(edge_weight_t, const NdnGlobalRouterGraph& g)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700239{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800240 return EdgeWeights(g);
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700241}
242
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700243inline VertexIds
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800244get(vertex_index_t, const NdnGlobalRouterGraph& g)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700245{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800246 return VertexIds(g);
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700247}
248
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700249template<class M, class K, class V>
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700250inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800251put(reference_wrapper<M> mapp, K a, V p)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700252{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800253 mapp.get()[a] = p;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700254}
255
256// void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700257// put (cref< std::map< ns3::Ptr<ns3::ndn::GlobalRouter>, ns3::Ptr<ns3::ndn::GlobalRouter> > > map,
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700258
Alexander Afanasyevb2a11fe2012-12-12 11:38:39 -0800259inline uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800260get(const boost::VertexIds&, ns3::Ptr<ns3::ndn::GlobalRouter>& gr)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700261{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800262 return gr->GetId();
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700263}
264
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800265inline property_traits<EdgeWeights>::reference
266get(const boost::EdgeWeights&, ns3::ndn::GlobalRouter::Incidency& edge)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700267{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800268 if (edge.get<1>() == 0)
269 return property_traits<EdgeWeights>::reference(0, 0, 0.0);
270 else {
271 ns3::Ptr<ns3::ndn::Limits> limits = edge.get<1>()->GetObject<ns3::ndn::Limits>();
272 double delay = 0.0;
273 if (limits != 0) // valid limits object
Alexander Afanasyeva8f5d882012-11-09 14:22:48 -0800274 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800275 delay = limits->GetLinkDelay();
Alexander Afanasyeva8f5d882012-11-09 14:22:48 -0800276 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800277 return property_traits<EdgeWeights>::reference(edge.get<1>(), edge.get<1>()->GetMetric(),
278 delay);
279 }
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700280}
281
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800282struct PredecessorsMap
283 : public std::map<ns3::Ptr<ns3::ndn::GlobalRouter>, ns3::Ptr<ns3::ndn::GlobalRouter>> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700284};
285
286template<>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800287struct property_traits<reference_wrapper<PredecessorsMap>> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700288 // Metric property map
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800289 typedef ns3::Ptr<ns3::ndn::GlobalRouter> value_type;
290 typedef ns3::Ptr<ns3::ndn::GlobalRouter> reference;
291 typedef ns3::Ptr<ns3::ndn::GlobalRouter> key_type;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700292 typedef read_write_property_map_tag category;
293};
294
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800295struct DistancesMap : public std::map<ns3::Ptr<ns3::ndn::GlobalRouter>,
296 tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double>> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700297};
298
299template<>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800300struct property_traits<reference_wrapper<DistancesMap>> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700301 // Metric property map
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800302 typedef tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double> value_type;
303 typedef tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double> reference;
304 typedef ns3::Ptr<ns3::ndn::GlobalRouter> key_type;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700305 typedef read_write_property_map_tag category;
306};
307
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800308inline tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double>
309get(DistancesMap& map, ns3::Ptr<ns3::ndn::GlobalRouter> key)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700310{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800311 boost::DistancesMap::iterator i = map.find(key);
312 if (i == map.end())
313 return tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double>(0,
314 std::numeric_limits<uint32_t>::max(),
315 0.0);
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700316 else
317 return i->second;
318}
319
320} // namespace boost
321
Alexander Afanasyev6315ef72012-06-01 20:56:31 -0700322/// @endcond
323
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700324#endif // BOOST_GRAPH_NDN_GLOBAL_ROUTING_HELPER_H