blob: ef04fac11da7d5e4068e9768ccc9d2b315f58ab9 [file] [log] [blame]
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2012 University of California, Los Angeles
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
*/
#ifndef BOOST_GRAPH_CCNX_GLOBAL_ROUTING_HELPER_H
#define BOOST_GRAPH_CCNX_GLOBAL_ROUTING_HELPER_H
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <boost/ref.hpp>
#include "ns3/ccnx-face.h"
#include "ns3/node-list.h"
#include "ns3/channel-list.h"
#include "../model/ccnx-global-router.h"
#include <list>
#include <map>
namespace boost
{
class CcnxGlobalRouterGraph
{
public:
typedef ns3::Ptr< ns3::CcnxGlobalRouter > Vertice;
typedef uint16_t edge_property_type;
typedef uint32_t vertex_property_type;
CcnxGlobalRouterGraph ()
{
for (ns3::NodeList::Iterator node = ns3::NodeList::Begin (); node != ns3::NodeList::End (); node++)
{
ns3::Ptr<ns3::CcnxGlobalRouter> gr = (*node)->GetObject<ns3::CcnxGlobalRouter> ();
if (gr != 0)
m_vertices.push_back (gr);
}
for (ns3::ChannelList::Iterator channel = ns3::ChannelList::Begin (); channel != ns3::ChannelList::End (); channel++)
{
ns3::Ptr<ns3::CcnxGlobalRouter> gr = (*channel)->GetObject<ns3::CcnxGlobalRouter> ();
if (gr != 0)
m_vertices.push_back (gr);
}
}
const std::list< Vertice > &
GetVertices () const
{
return m_vertices;
}
public:
std::list< Vertice > m_vertices;
};
class ccnx_global_router_graph_category :
public virtual vertex_list_graph_tag,
public virtual incidence_graph_tag
{
};
template<>
struct graph_traits< CcnxGlobalRouterGraph >
{
// Graph concept
typedef CcnxGlobalRouterGraph::Vertice vertex_descriptor;
typedef ns3::CcnxGlobalRouter::Incidency edge_descriptor;
typedef directed_tag directed_category;
typedef disallow_parallel_edge_tag edge_parallel_category;
typedef ccnx_global_router_graph_category traversal_category;
// VertexList concept
typedef std::list< vertex_descriptor >::const_iterator vertex_iterator;
typedef size_t vertices_size_type;
// AdjacencyGraph concept
typedef ns3::CcnxGlobalRouter::IncidencyList::iterator out_edge_iterator;
typedef size_t degree_size_type;
// typedef size_t edges_size_type;
};
} // namespace boost
namespace boost
{
inline
graph_traits< CcnxGlobalRouterGraph >::vertex_descriptor
source(
graph_traits< CcnxGlobalRouterGraph >::edge_descriptor e,
const CcnxGlobalRouterGraph& g)
{
return e.get<0> ();
}
inline
graph_traits< CcnxGlobalRouterGraph >::vertex_descriptor
target(
graph_traits< CcnxGlobalRouterGraph >::edge_descriptor e,
const CcnxGlobalRouterGraph& g)
{
return e.get<2> ();
}
inline
std::pair< graph_traits< CcnxGlobalRouterGraph >::vertex_iterator,
graph_traits< CcnxGlobalRouterGraph >::vertex_iterator >
vertices (const CcnxGlobalRouterGraph&g)
{
return make_pair (g.GetVertices ().begin (), g.GetVertices ().end ());
}
inline
graph_traits< CcnxGlobalRouterGraph >::vertices_size_type
num_vertices(const CcnxGlobalRouterGraph &g)
{
return g.GetVertices ().size ();
}
inline
std::pair< graph_traits< CcnxGlobalRouterGraph >::out_edge_iterator,
graph_traits< CcnxGlobalRouterGraph >::out_edge_iterator >
out_edges(
graph_traits< CcnxGlobalRouterGraph >::vertex_descriptor u,
const CcnxGlobalRouterGraph& g)
{
return std::make_pair(u->GetIncidencies ().begin (),
u->GetIncidencies ().end ());
}
inline
graph_traits< CcnxGlobalRouterGraph >::degree_size_type
out_degree(
graph_traits< CcnxGlobalRouterGraph >::vertex_descriptor u,
const CcnxGlobalRouterGraph& g)
{
return u->GetIncidencies ().size ();
}
//////////////////////////////////////////////////////////////
// Property maps
struct EdgeWeights
{
EdgeWeights (const CcnxGlobalRouterGraph &graph)
: m_graph (graph)
{
}
private:
const CcnxGlobalRouterGraph &m_graph;
};
struct VertexIds
{
VertexIds (const CcnxGlobalRouterGraph &graph)
: m_graph (graph)
{
}
private:
const CcnxGlobalRouterGraph &m_graph;
};
template<>
struct property_map< CcnxGlobalRouterGraph, edge_weight_t >
{
typedef const EdgeWeights const_type;
typedef EdgeWeights type;
};
template<>
struct property_map< CcnxGlobalRouterGraph, vertex_index_t >
{
typedef const VertexIds const_type;
typedef VertexIds type;
};
template<>
struct property_traits< EdgeWeights >
{
// Metric property map
typedef tuple< ns3::Ptr<ns3::CcnxFace>, uint16_t > value_type;
typedef tuple< ns3::Ptr<ns3::CcnxFace>, uint16_t > reference;
typedef ns3::CcnxGlobalRouter::Incidency key_type;
typedef readable_property_map_tag category;
};
const property_traits< EdgeWeights >::value_type WeightZero (0, 0);
const property_traits< EdgeWeights >::value_type WeightInf (0, std::numeric_limits<uint16_t>::max ());
struct WeightCompare :
public std::binary_function<property_traits< EdgeWeights >::reference,
property_traits< EdgeWeights >::reference,
bool>
{
bool
operator () (property_traits< EdgeWeights >::reference a,
property_traits< EdgeWeights >::reference b) const
{
return a.get<1> () < b.get<1> ();
}
bool
operator () (property_traits< EdgeWeights >::reference a,
uint32_t b) const
{
return a.get<1> () < b;
}
bool
operator () (uint32_t a,
uint32_t b) const
{
return a < b;
}
};
struct WeightCombine :
public std::binary_function<uint32_t,
property_traits< EdgeWeights >::reference,
uint32_t>
{
uint32_t
operator () (uint32_t a, property_traits< EdgeWeights >::reference b) const
{
return a + b.get<1> ();
}
tuple< ns3::Ptr<ns3::CcnxFace>, uint32_t >
operator () (tuple< ns3::Ptr<ns3::CcnxFace>, uint32_t > a,
property_traits< EdgeWeights >::reference b) const
{
if (a.get<0> () == 0)
return make_tuple (b.get<0> (), a.get<1> () + b.get<1> ());
else
return make_tuple (a.get<0> (), a.get<1> () + b.get<1> ());
}
};
template<>
struct property_traits< VertexIds >
{
// Metric property map
typedef uint32_t value_type;
typedef uint32_t reference;
typedef ns3::Ptr< ns3::CcnxGlobalRouter > key_type;
typedef readable_property_map_tag category;
};
inline EdgeWeights
get(edge_weight_t,
const CcnxGlobalRouterGraph &g)
{
return EdgeWeights (g);
}
inline VertexIds
get(vertex_index_t,
const CcnxGlobalRouterGraph &g)
{
return VertexIds (g);
}
template<class M, class K, class V>
inline void
put (reference_wrapper< M > mapp,
K a, V p)
{
mapp.get ()[a] = p;
}
// void
// put (cref< std::map< ns3::Ptr<ns3::CcnxGlobalRouter>, ns3::Ptr<ns3::CcnxGlobalRouter> > > map,
uint32_t
get (const boost::VertexIds&, ns3::Ptr<ns3::CcnxGlobalRouter> &gr)
{
return gr->GetId ();
}
inline property_traits< EdgeWeights >::reference
get(const boost::EdgeWeights&, ns3::CcnxGlobalRouter::Incidency &edge)
{
if (edge.get<1> () == 0)
return property_traits< EdgeWeights >::reference (0, 0);
else
return property_traits< EdgeWeights >::reference (edge.get<1> (), edge.get<1> ()->GetMetric ());
}
struct PredecessorsMap :
public std::map< ns3::Ptr< ns3::CcnxGlobalRouter >, ns3::Ptr< ns3::CcnxGlobalRouter > >
{
};
template<>
struct property_traits< reference_wrapper<PredecessorsMap> >
{
// Metric property map
typedef ns3::Ptr< ns3::CcnxGlobalRouter > value_type;
typedef ns3::Ptr< ns3::CcnxGlobalRouter > reference;
typedef ns3::Ptr< ns3::CcnxGlobalRouter > key_type;
typedef read_write_property_map_tag category;
};
struct DistancesMap :
public std::map< ns3::Ptr< ns3::CcnxGlobalRouter >, tuple< ns3::Ptr<ns3::CcnxFace>, uint32_t > >
{
};
template<>
struct property_traits< reference_wrapper<DistancesMap> >
{
// Metric property map
typedef tuple< ns3::Ptr<ns3::CcnxFace>, uint32_t > value_type;
typedef tuple< ns3::Ptr<ns3::CcnxFace>, uint32_t > reference;
typedef ns3::Ptr< ns3::CcnxGlobalRouter > key_type;
typedef read_write_property_map_tag category;
};
inline tuple< ns3::Ptr<ns3::CcnxFace>, uint32_t >
get (DistancesMap &map, ns3::Ptr<ns3::CcnxGlobalRouter> key)
{
boost::DistancesMap::iterator i = map.find (key);
if (i == map.end ())
return tuple< ns3::Ptr<ns3::CcnxFace>, uint32_t > (0, std::numeric_limits<uint32_t>::max ());
else
return i->second;
}
} // namespace boost
#endif // BOOST_GRAPH_CCNX_GLOBAL_ROUTING_HELPER_H