blob: da962134e8b774a9a4ba416d432ae67824deb818 [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
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -070026#include "ns3/ndnSIM/model/ndn-common.hpp"
27
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070028#include <boost/graph/graph_traits.hpp>
29#include <boost/graph/properties.hpp>
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -070030#include <boost/ref.hpp>
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070031
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -080032#include "ns3/ndnSIM/model/ndn-face.hpp"
33#include "ns3/ndnSIM/model/ndn-global-router.hpp"
34
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070035#include "ns3/node-list.h"
36#include "ns3/channel-list.h"
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -080037
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070038#include <list>
39#include <map>
40
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070041namespace boost {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070042
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080043class NdnGlobalRouterGraph {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070044public:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080045 typedef ns3::Ptr<ns3::ndn::GlobalRouter> Vertice;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070046 typedef uint16_t edge_property_type;
47 typedef uint32_t vertex_property_type;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070048
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080049 NdnGlobalRouterGraph()
50 {
51 for (ns3::NodeList::Iterator node = ns3::NodeList::Begin(); node != ns3::NodeList::End();
52 node++) {
53 ns3::Ptr<ns3::ndn::GlobalRouter> gr = (*node)->GetObject<ns3::ndn::GlobalRouter>();
54 if (gr != 0)
55 m_vertices.push_back(gr);
56 }
57
58 for (ns3::ChannelList::Iterator channel = ns3::ChannelList::Begin();
59 channel != ns3::ChannelList::End(); channel++) {
60 ns3::Ptr<ns3::ndn::GlobalRouter> gr = (*channel)->GetObject<ns3::ndn::GlobalRouter>();
61 if (gr != 0)
62 m_vertices.push_back(gr);
63 }
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070064 }
65
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080066 const std::list<Vertice>&
67 GetVertices() const
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070068 {
69 return m_vertices;
70 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080071
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070072public:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080073 std::list<Vertice> m_vertices;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070074};
75
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080076class ndn_global_router_graph_category : public virtual vertex_list_graph_tag,
77 public virtual incidence_graph_tag {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070078};
79
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070080template<>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080081struct graph_traits<NdnGlobalRouterGraph> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070082 // Graph concept
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070083 typedef NdnGlobalRouterGraph::Vertice vertex_descriptor;
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070084 typedef ns3::ndn::GlobalRouter::Incidency edge_descriptor;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070085 typedef directed_tag directed_category;
86 typedef disallow_parallel_edge_tag edge_parallel_category;
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070087 typedef ndn_global_router_graph_category traversal_category;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070088
89 // VertexList concept
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080090 typedef std::list<vertex_descriptor>::const_iterator vertex_iterator;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070091 typedef size_t vertices_size_type;
92
93 // AdjacencyGraph concept
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070094 typedef ns3::ndn::GlobalRouter::IncidencyList::iterator out_edge_iterator;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -070095 typedef size_t degree_size_type;
96
97 // typedef size_t edges_size_type;
98};
99
100} // namespace boost
101
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800102namespace boost {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700103
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800104inline graph_traits<NdnGlobalRouterGraph>::vertex_descriptor
105source(graph_traits<NdnGlobalRouterGraph>::edge_descriptor e, const NdnGlobalRouterGraph& g)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700106{
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800107 return std::get<0>(e);
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700108}
109
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800110inline graph_traits<NdnGlobalRouterGraph>::vertex_descriptor
111target(graph_traits<NdnGlobalRouterGraph>::edge_descriptor e, const NdnGlobalRouterGraph& g)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700112{
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800113 return std::get<2>(e);
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700114}
115
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800116inline std::pair<graph_traits<NdnGlobalRouterGraph>::vertex_iterator,
117 graph_traits<NdnGlobalRouterGraph>::vertex_iterator>
118vertices(const NdnGlobalRouterGraph& g)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700119{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800120 return make_pair(g.GetVertices().begin(), g.GetVertices().end());
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700121}
122
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800123inline graph_traits<NdnGlobalRouterGraph>::vertices_size_type
124num_vertices(const NdnGlobalRouterGraph& g)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700125{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800126 return g.GetVertices().size();
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700127}
128
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800129inline std::pair<graph_traits<NdnGlobalRouterGraph>::out_edge_iterator,
130 graph_traits<NdnGlobalRouterGraph>::out_edge_iterator>
131out_edges(graph_traits<NdnGlobalRouterGraph>::vertex_descriptor u, const NdnGlobalRouterGraph& g)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700132{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800133 return std::make_pair(u->GetIncidencies().begin(), u->GetIncidencies().end());
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700134}
135
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800136inline graph_traits<NdnGlobalRouterGraph>::degree_size_type
137out_degree(graph_traits<NdnGlobalRouterGraph>::vertex_descriptor u, const NdnGlobalRouterGraph& g)
138{
139 return u->GetIncidencies().size();
140}
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700141
142//////////////////////////////////////////////////////////////
143// Property maps
144
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800145struct EdgeWeights {
146 EdgeWeights(const NdnGlobalRouterGraph& graph)
147 : m_graph(graph)
148 {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700149 }
150
151private:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800152 const NdnGlobalRouterGraph& m_graph;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700153};
154
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800155struct VertexIds {
156 VertexIds(const NdnGlobalRouterGraph& graph)
157 : m_graph(graph)
158 {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700159 }
160
161private:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800162 const NdnGlobalRouterGraph& m_graph;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700163};
164
165template<>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800166struct property_map<NdnGlobalRouterGraph, edge_weight_t> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700167 typedef const EdgeWeights const_type;
168 typedef EdgeWeights type;
169};
170
171template<>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800172struct property_map<NdnGlobalRouterGraph, vertex_index_t> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700173 typedef const VertexIds const_type;
174 typedef VertexIds type;
175};
176
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700177template<>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800178struct property_traits<EdgeWeights> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700179 // Metric property map
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800180 typedef std::tuple<std::shared_ptr<nfd::Face>, uint16_t, double> value_type;
181 typedef std::tuple<std::shared_ptr<nfd::Face>, uint16_t, double> reference;
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700182 typedef ns3::ndn::GlobalRouter::Incidency key_type;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700183 typedef readable_property_map_tag category;
184};
185
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800186const property_traits<EdgeWeights>::value_type WeightZero(0, 0, 0.0);
187const property_traits<EdgeWeights>::value_type
188 WeightInf(0, std::numeric_limits<uint16_t>::max(), 0.0);
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700189
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800190struct WeightCompare : public std::binary_function<property_traits<EdgeWeights>::reference,
191 property_traits<EdgeWeights>::reference, bool> {
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700192 bool
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800193 operator()(std::tuple<std::shared_ptr<nfd::Face>, uint32_t, double> a,
194 std::tuple<std::shared_ptr<nfd::Face>, uint32_t, double> b) const
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700195 {
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800196 return std::get<1>(a) < std::get<1>(b);
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700197 }
198
199 bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800200 operator()(property_traits<EdgeWeights>::reference a, uint32_t b) const
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700201 {
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800202 return std::get<1>(a) < b;
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700203 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800204
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700205 bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800206 operator()(uint32_t a, uint32_t b) const
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700207 {
208 return a < b;
209 }
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700210};
211
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800212struct WeightCombine
213 : public std::binary_function<uint32_t, property_traits<EdgeWeights>::reference, uint32_t> {
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700214 uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800215 operator()(uint32_t a, property_traits<EdgeWeights>::reference b) const
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700216 {
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800217 return a + std::get<1>(b);
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700218 }
219
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800220 std::tuple<std::shared_ptr<nfd::Face>, uint32_t, double>
221 operator()(std::tuple<std::shared_ptr<nfd::Face>, uint32_t, double> a,
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800222 property_traits<EdgeWeights>::reference b) const
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700223 {
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800224 if (std::get<0>(a) == 0)
225 return std::make_tuple(std::get<0>(b), std::get<1>(a) + std::get<1>(b),
226 std::get<2>(a) + std::get<2>(b));
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700227 else
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800228 return std::make_tuple(std::get<0>(a), std::get<1>(a) + std::get<1>(b),
229 std::get<2>(a) + std::get<2>(b));
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700230 }
231};
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800232
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700233template<>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800234struct property_traits<VertexIds> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700235 // Metric property map
236 typedef uint32_t value_type;
237 typedef uint32_t reference;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800238 typedef ns3::Ptr<ns3::ndn::GlobalRouter> key_type;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700239 typedef readable_property_map_tag category;
240};
241
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700242inline EdgeWeights
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800243get(edge_weight_t, const NdnGlobalRouterGraph& g)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700244{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800245 return EdgeWeights(g);
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700246}
247
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700248inline VertexIds
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800249get(vertex_index_t, const NdnGlobalRouterGraph& g)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700250{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800251 return VertexIds(g);
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700252}
253
Alexander Afanasyeva5abcd92012-04-17 13:34:43 -0700254template<class M, class K, class V>
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700255inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800256put(reference_wrapper<M> mapp, K a, V p)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700257{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800258 mapp.get()[a] = p;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700259}
260
261// void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700262// put (cref< std::map< ns3::Ptr<ns3::ndn::GlobalRouter>, ns3::Ptr<ns3::ndn::GlobalRouter> > > map,
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700263
Alexander Afanasyevb2a11fe2012-12-12 11:38:39 -0800264inline uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800265get(const boost::VertexIds&, ns3::Ptr<ns3::ndn::GlobalRouter>& gr)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700266{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800267 return gr->GetId();
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700268}
269
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800270inline property_traits<EdgeWeights>::reference
271get(const boost::EdgeWeights&, ns3::ndn::GlobalRouter::Incidency& edge)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700272{
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800273 if (std::get<1>(edge) == 0)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800274 return property_traits<EdgeWeights>::reference(0, 0, 0.0);
275 else {
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800276 return property_traits<EdgeWeights>::reference(std::get<1>(edge),
277 static_cast<uint16_t>(
278 std::get<1>(edge)->getMetric()),
279 0.0);
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800280 }
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700281}
282
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800283struct PredecessorsMap
284 : public std::map<ns3::Ptr<ns3::ndn::GlobalRouter>, ns3::Ptr<ns3::ndn::GlobalRouter>> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700285};
286
287template<>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800288struct property_traits<reference_wrapper<PredecessorsMap>> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700289 // Metric property map
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800290 typedef ns3::Ptr<ns3::ndn::GlobalRouter> value_type;
291 typedef ns3::Ptr<ns3::ndn::GlobalRouter> reference;
292 typedef ns3::Ptr<ns3::ndn::GlobalRouter> key_type;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700293 typedef read_write_property_map_tag category;
294};
295
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800296struct DistancesMap : public std::map<ns3::Ptr<ns3::ndn::GlobalRouter>,
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800297 std::tuple<std::shared_ptr<nfd::Face>, uint32_t, double>> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700298};
299
300template<>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800301struct property_traits<reference_wrapper<DistancesMap>> {
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700302 // Metric property map
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800303 typedef std::tuple<std::shared_ptr<nfd::Face>, uint32_t, double> value_type;
304 typedef std::tuple<std::shared_ptr<nfd::Face>, uint32_t, double> reference;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800305 typedef ns3::Ptr<ns3::ndn::GlobalRouter> key_type;
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700306 typedef read_write_property_map_tag category;
307};
308
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800309inline std::tuple<std::shared_ptr<nfd::Face>, uint32_t, double>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800310get(DistancesMap& map, ns3::Ptr<ns3::ndn::GlobalRouter> key)
Alexander Afanasyevad3757f2012-04-17 10:27:59 -0700311{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800312 boost::DistancesMap::iterator i = map.find(key);
313 if (i == map.end())
Spyridon Mastorakis60f4b992014-11-07 15:51:38 -0800314 return std::tuple<std::shared_ptr<nfd::Face>, uint32_t,
315 double>(0, std::numeric_limits<uint32_t>::max(), 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