23 #include <boost/graph/adjacency_list.hpp> 24 #include <boost/graph/dijkstra_shortest_paths.hpp> 25 #include <boost/graph/properties.hpp> 26 #include <boost/property_map/property_map.hpp> 29 #include "ns3/abort.h" 30 #include "ns3/ndnSIM/helper/lfid/abstract-fib.hpp" 49 for (
const auto& node : allNodeFIB) {
50 int nodeId = node.first;
51 if (dstId == nodeId) {
55 for (
const auto& fibNh : node.second.getNexthops(dstId)) {
57 boost::add_edge(static_cast<uint64_t>(nodeId), static_cast<uint64_t>(fibNh.getNexthopId()), 1, dg);
64 NodePrio(
int nodeId,
int remainingNh, set<FibNextHop> nhSet)
66 , m_remainingNh{remainingNh}
69 NS_ABORT_UNLESS(remainingNh > 0 && m_uwSet.size() > 0);
70 NS_ABORT_UNLESS(static_cast<int>(m_uwSet.size()) < remainingNh);
82 return static_cast<int>(m_uwSet.size());
91 return std::make_tuple(m_remainingNh, getHighestCostUw(), m_nodeId)
92 < std::make_tuple(other.m_remainingNh, other.getHighestCostUw(), other.m_nodeId);
109 NS_ABORT_UNLESS(m_remainingNh > 0 && m_remainingNh >
getRemainingUw());
116 NS_ABORT_UNLESS(m_uwSet.size() > 0);
117 auto success = m_uwSet.erase(nh);
118 NS_ABORT_UNLESS(success == 1);
122 getHighestCostUw()
const 124 NS_ABORT_UNLESS(m_uwSet.size() > 0);
125 NS_ABORT_UNLESS(std::prev(m_uwSet.end()) != m_uwSet.end());
126 return *(std::prev(m_uwSet.end()));
132 set<FibNextHop> m_uwSet;
141 return os <<
"Id: " << node.m_nodeId <<
", remaining NH: " << node.m_remainingNh
148 int removedLoopCounter = 0;
149 int upwardCounter = 0;
151 const int NUM_NODES{
static_cast<int>(allNodeFIB.size())};
157 for (
int dstId = 0; dstId < NUM_NODES; dstId++) {
162 std::priority_queue<NodePrio> q;
165 for (
const auto& node : allNodeFIB) {
166 int nodeId{node.first};
168 if (nodeId == dstId) {
173 if (!uwNhSet.empty()) {
174 upwardCounter += uwNhSet.size();
176 int fibSize{fib.numEnabledNhPerDst(dstId)};
178 q.emplace(nodeId, fibSize, uwNhSet);
187 int nodeId = node.
getId();
192 auto res = boost::edge(static_cast<uint64_t>(nhId), static_cast<uint64_t>(nodeId), dg);
194 auto arc = res.first;
195 bool arcExists = res.second;
198 boost::remove_edge(arc, dg);
205 std::vector<int> dists(num_vertices(dg));
207 auto weightmap =
get(boost::edge_weight, dg);
209 const auto& x = boost::edges(dg);
210 for (
auto e = x.first; e != x.second; e++) {
211 int weight =
get(weightmap, *e);
212 NS_ABORT_UNLESS(weight == 1);
216 dijkstra_shortest_paths(dg, static_cast<uint64_t>(nhId),
218 boost::make_iterator_property_map(dists.begin(),
get(boost::vertex_index, dg))));
220 bool willLoop = (dists.at(static_cast<size_t>(nodeId)) < (std::numeric_limits<int>::max() - 1));
225 removedLoopCounter++;
228 allNodeFIB.at(node.
getId()).erase(dstId, nhId);
230 auto res2 = boost::edge(static_cast<uint64_t>(node.
getId()), static_cast<uint64_t>(nhId), dg);
231 auto arc2 = res2.first;
232 NS_ABORT_UNLESS(res.second);
234 boost::remove_edge(arc2, dg);
239 boost::add_edge(static_cast<uint64_t>(nhId), static_cast<uint64_t>(nodeId), 1, dg);
250 std::cout <<
"Found " << upwardCounter <<
" UW nexthops, Removed " << removedLoopCounter
251 <<
" Looping UwNhs, Remaining: " << upwardCounter - removedLoopCounter <<
" NHs\n";
253 NS_ABORT_UNLESS((upwardCounter - removedLoopCounter) >= 0);
255 return removedLoopCounter;
261 int NUM_NODES{
static_cast<int>(allNodeFIB.size())};
262 int checkedUwCounter{0};
265 int removedDeadendCounter{0};
267 for (
int dstId = 0; dstId < NUM_NODES; dstId++) {
269 set<std::pair<int, FibNextHop>> nhSet;
272 for (
const auto& node : allNodeFIB) {
273 int nodeId{node.first};
274 if (nodeId == dstId) {
278 totalCounter += node.second.getNexthops(dstId).size();
280 const auto& uwNhSet = node.second.getUpwardNexthops(dstId);
281 uwCounter += uwNhSet.size();
283 nhSet.emplace(nodeId, fibNh);
289 while (!nhSet.empty()) {
293 const auto& nhPair = nhSet.begin();
294 NS_ABORT_UNLESS(nhPair != nhSet.end());
297 int nodeId = nhPair->first;
305 int reverseEntries{allNodeFIB.at(nh.
getNexthopId()).numEnabledNhPerDst(dstId)};
308 NS_ABORT_UNLESS(reverseEntries > 0);
312 if (reverseEntries <= 1) {
313 removedDeadendCounter++;
321 for (
const auto& ownNhs : nexthops) {
323 const auto& reverseNh = allNodeFIB.at(ownNhs.getNexthopId()).getNexthops(dstId);
325 for (
const auto& y : reverseNh) {
326 if (y.getNexthopId() == nodeId) {
328 nhSet.emplace(ownNhs.getNexthopId(), y);
339 std::cout <<
"Checked " << checkedUwCounter <<
" Upward NHs, Removed " << removedDeadendCounter
340 <<
" Deadend UwNhs, Remaining: " << uwCounter - removedDeadendCounter <<
" UW NHs, " 341 << totalCounter - removedDeadendCounter <<
" total nexthops\n";
344 return removedDeadendCounter;
Copyright (c) 2011-2015 Regents of the University of California.
const std::set< FibNextHop > & getUpwardNexthops(int dstId) const
size_t erase(int dstId, int nhId)
FibNextHop popHighestCostUw()
bool operator<(const NodePrio &other) const
Order by Remamining UW NHs, Highest DeltaCost, and then id.
int removeLoops(AllNodeFib &allNodeFIB, bool printOutput)
An abstract, lightweight representation of the FIB.
void getDigraphFromFib(DiGraph &dg, const AllNodeFib &allNodeFIB, const int dstId)
Fill directed graph only with edges existing in the FIB.
int removeDeadEnds(AllNodeFib &allNodeFIB, bool printOutput)
int getRemainingUw() const
std::unordered_map< int, AbstractFib > AllNodeFib
Copyright (c) 2011-2015 Regents of the University of California.
friend std::ostream & operator<<(std::ostream &, const NodePrio &node)
NodePrio(int nodeId, int remainingNh, set< FibNextHop > nhSet)
const std::set< FibNextHop > & getNexthops(int dstId) const
AbstractFib::AllNodeFib AllNodeFib
boost::adjacency_list< boost::listS, boost::vecS, boost::bidirectionalS, boost::no_property, boost::property< boost::edge_weight_t, int > > DiGraph