routing-table-calculator.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2014-2023, The University of Memphis,
4  * Regents of the University of California,
5  * Arizona Board of Regents.
6  *
7  * This file is part of NLSR (Named-data Link State Routing).
8  * See AUTHORS.md for complete list of NLSR authors and contributors.
9  *
10  * NLSR is free software: you can redistribute it and/or modify it under the terms
11  * of the GNU General Public License as published by the Free Software Foundation,
12  * either version 3 of the License, or (at your option) any later version.
13  *
14  * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16  * PURPOSE. See the GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along with
19  * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
23 #include "lsdb.hpp"
24 #include "map.hpp"
25 #include "nexthop.hpp"
26 #include "nlsr.hpp"
27 #include "logger.hpp"
28 #include "adjacent.hpp"
29 
30 #include <cmath>
31 #include <boost/lexical_cast.hpp>
32 #include <ndn-cxx/util/logger.hpp>
33 
34 namespace nlsr {
35 
36 INIT_LOGGER(route.RoutingTableCalculator);
37 
38 constexpr int EMPTY_PARENT = -12345;
39 constexpr double INF_DISTANCE = 2147483647;
40 constexpr int NO_MAPPING_NUM = -1;
41 constexpr int NO_NEXT_HOP = -12345;
42 constexpr double UNKNOWN_DISTANCE = -1.0;
43 constexpr double UNKNOWN_RADIUS = -1.0;
44 
45 void
47 {
48  adjMatrix = new double*[m_nRouters];
49 
50  for (size_t i = 0; i < m_nRouters; ++i) {
51  adjMatrix[i] = new double[m_nRouters];
52  }
53 }
54 
55 void
57 {
58  for (size_t i = 0; i < m_nRouters; i++) {
59  for (size_t j = 0; j < m_nRouters; j++) {
61  }
62  }
63 }
64 
65 void
67 {
68  // For each LSA represented in the map
69  auto lsaRange = lsdb.getLsdbIterator<AdjLsa>();
70  for (auto lsaIt = lsaRange.first; lsaIt != lsaRange.second; ++lsaIt) {
71  auto adjLsa = std::static_pointer_cast<AdjLsa>(*lsaIt);
72  auto row = pMap.getMappingNoByRouterName(adjLsa->getOriginRouter());
73 
74  std::list<Adjacent> adl = adjLsa->getAdl().getAdjList();
75  // For each adjacency represented in the LSA
76  for (const auto& adjacent : adl) {
77  auto col = pMap.getMappingNoByRouterName(adjacent.getName());
78  double cost = adjacent.getLinkCost();
79 
80  if (row && col && *row < static_cast<int32_t>(m_nRouters)
81  && *col < static_cast<int32_t>(m_nRouters)) {
82  adjMatrix[*row][*col] = cost;
83  }
84  }
85  }
86 
87  // Links that do not have the same cost for both directions should
88  // have their costs corrected:
89  //
90  // If the cost of one side of the link is NON_ADJACENT_COST (i.e. broken) or negative,
91  // both direction of the link should have their cost corrected to NON_ADJACENT_COST.
92  //
93  // Otherwise, both sides of the link should use the larger of the two costs.
94  //
95  // Additionally, this means that we can halve the amount of space
96  // that the matrix uses by only maintaining a triangle.
97  // - But that is not yet implemented.
98  for (size_t row = 0; row < m_nRouters; ++row) {
99  for (size_t col = 0; col < m_nRouters; ++col) {
100  double toCost = adjMatrix[row][col];
101  double fromCost = adjMatrix[col][row];
102 
103  if (fromCost != toCost) {
104  double correctedCost = Adjacent::NON_ADJACENT_COST;
105 
106  if (toCost >= 0 && fromCost >= 0) {
107  // If both sides of the link are up, use the larger cost else break the link
108  correctedCost = std::max(toCost, fromCost);
109  }
110 
111  NLSR_LOG_WARN("Cost between [" << row << "][" << col << "] and [" << col << "][" << row <<
112  "] are not the same (" << toCost << " != " << fromCost << "). " <<
113  "Correcting to cost: " << correctedCost);
114 
115  adjMatrix[row][col] = correctedCost;
116  adjMatrix[col][row] = correctedCost;
117  }
118  }
119  }
120 }
121 
122 void
124 {
125  if (!ndn_cxx_getLogger().isLevelEnabled(ndn::util::LogLevel::DEBUG)) {
126  return;
127  }
128 
129  NLSR_LOG_DEBUG("-----------Legend (routerName -> index)------");
130  std::string routerIndex;
131  std::string indexToNameMapping;
132  std::string lengthOfDash = "--";
133 
134  for (size_t i = 0; i < m_nRouters; i++) {
135  routerIndex += boost::lexical_cast<std::string>(i);
136  routerIndex += " ";
137  lengthOfDash += "--";
138  NLSR_LOG_DEBUG("Router:" + map.getRouterNameByMappingNo(i)->toUri() +
139  " Index:" + boost::lexical_cast<std::string>(i));
140  }
141  NLSR_LOG_DEBUG(" |" + routerIndex);
142  NLSR_LOG_DEBUG(lengthOfDash);
143 
144  for (size_t i = 0; i < m_nRouters; i++) {
145  std::string line;
146  for (size_t j = 0; j < m_nRouters; j++) {
147  if (adjMatrix[i][j] == NO_NEXT_HOP) {
148  line += "0 ";
149  }
150  else {
151  line += boost::lexical_cast<std::string>(adjMatrix[i][j]);
152  line += " ";
153  }
154  }
155  line = boost::lexical_cast<std::string>(i) + "|" + line;
156  NLSR_LOG_DEBUG(line);
157  }
158 }
159 
160 void
161 RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
162 {
163  for (int i = 0; i < static_cast<int>(m_nRouters); i++) {
164  if (i == link) {
165  adjMatrix[source][i] = linkCost;
166  }
167  else {
168  // if "i" is not a link to the source, set it's cost to a non adjacent value.
170  }
171  }
172 }
173 
174 int
176 {
177  int noLink = 0;
178 
179  for (size_t i = 0; i < m_nRouters; i++) {
180  if (adjMatrix[sRouter][i] >= 0 && i != static_cast<size_t>(sRouter)) { // make sure "i" is not self
181  noLink++;
182  }
183  }
184  return noLink;
185 }
186 
187 void
189  double* linkCosts, int source)
190 {
191  int j = 0;
192 
193  for (size_t i = 0; i < m_nRouters; i++) {
194  if (adjMatrix[source][i] >= 0 && i != static_cast<size_t>(source)) {// make sure "i" is not self
195  links[j] = i;
196  linkCosts[j] = adjMatrix[source][i];
197  j++;
198  }
199  }
200 }
201 
202 void
204 {
205  for (size_t i = 0; i < m_nRouters; ++i) {
206  delete [] adjMatrix[i];
207  }
208  delete [] adjMatrix;
209 }
210 
211 void
213 {
214  links = new int[vNoLink];
215 }
216 
217 void
219 {
220  linkCosts = new double[vNoLink];
221 }
222 
223 void
225 {
226  delete [] links;
227 }
228 void
230 {
231  delete [] linkCosts;
232 }
233 
234 void
236  ConfParameter& confParam,
237  const Lsdb& lsdb)
238 {
239  NLSR_LOG_DEBUG("LinkStateRoutingTableCalculator::calculatePath Called");
241  initMatrix();
242  makeAdjMatrix(lsdb, pMap);
243  writeAdjMatrixLog(pMap);
244  auto sourceRouter = pMap.getMappingNoByRouterName(confParam.getRouterPrefix());
245  allocateParent(); // These two matrices are used in Dijkstra's algorithm.
246  allocateDistance(); //
247  // We only bother to do the calculation if we have a router by that name.
248  if (sourceRouter && confParam.getMaxFacesPerPrefix() == 1) {
249  // In the single path case we can simply run Dijkstra's algorithm.
250  doDijkstraPathCalculation(*sourceRouter);
251  // Inform the routing table of the new next hops.
252  addAllLsNextHopsToRoutingTable(confParam.getAdjacencyList(), rt, pMap, *sourceRouter);
253  }
254  else {
255  // Multi Path
256  setNoLink(getNumOfLinkfromAdjMatrix(*sourceRouter));
257  allocateLinks();
259  // Gets a sparse listing of adjacencies for path calculation
260  getLinksFromAdjMatrix(links, linkCosts, *sourceRouter);
261  for (int i = 0 ; i < vNoLink; i++) {
262  // Simulate that only the current neighbor is accessible
263  adjustAdMatrix(*sourceRouter, links[i], linkCosts[i]);
264  writeAdjMatrixLog(pMap);
265  // Do Dijkstra's algorithm using the current neighbor as your start.
266  doDijkstraPathCalculation(*sourceRouter);
267  // Update the routing table with the calculations.
268  addAllLsNextHopsToRoutingTable(confParam.getAdjacencyList(), rt, pMap, *sourceRouter);
269  }
270  freeLinks();
271  freeLinksCosts();
272  }
273  freeParent();
274  freeDistance();
275  freeAdjMatrix();
276 }
277 
278 void
279 LinkStateRoutingTableCalculator::doDijkstraPathCalculation(int sourceRouter)
280 {
281  int i;
282  int v, u;
283  int* Q = new int[m_nRouters]; // Each cell represents the router with that mapping no.
284  int head = 0;
285  // Initiate the parent
286  for (i = 0 ; i < static_cast<int>(m_nRouters); i++) {
287  m_parent[i] = EMPTY_PARENT;
288  // Array where the ith element is the distance to the router with mapping no i.
289  m_distance[i] = INF_DISTANCE;
290  Q[i] = i;
291  }
292  if (sourceRouter != NO_MAPPING_NUM) {
293  // Distance to source from source is always 0.
294  m_distance[sourceRouter] = 0;
295  sortQueueByDistance(Q, m_distance, head, m_nRouters);
296  // While we haven't visited every node.
297  while (head < static_cast<int>(m_nRouters)) {
298  u = Q[head]; // Set u to be the current node pointed to by head.
299  if (m_distance[u] == INF_DISTANCE) {
300  break; // This can only happen when there are no accessible nodes.
301  }
302  // Iterate over the adjacent nodes to u.
303  for (v = 0 ; v < static_cast<int>(m_nRouters); v++) {
304  // If the current node is accessible.
305  if (adjMatrix[u][v] >= 0) {
306  // And we haven't visited it yet.
307  if (isNotExplored(Q, v, head + 1, m_nRouters)) {
308  // And if the distance to this node + from this node to v
309  // is less than the distance from our source node to v
310  // that we got when we built the adj LSAs
311  if (m_distance[u] + adjMatrix[u][v] < m_distance[v]) {
312  // Set the new distance
313  m_distance[v] = m_distance[u] + adjMatrix[u][v] ;
314  // Set how we get there.
315  m_parent[v] = u;
316  }
317  }
318  }
319  }
320  // Increment the head position, resort the list by distance from where we are.
321  head++;
322  sortQueueByDistance(Q, m_distance, head, m_nRouters);
323  }
324  }
325  delete [] Q;
326 }
327 
328 void
329 LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(AdjacencyList& adjacencies,
330  RoutingTable& rt, Map& pMap,
331  uint32_t sourceRouter)
332 {
333  NLSR_LOG_DEBUG("LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called");
334 
335  int nextHopRouter = 0;
336 
337  // For each router we have
338  for (size_t i = 0; i < m_nRouters ; i++) {
339  if (i != sourceRouter) {
340 
341  // Obtain the next hop that was determined by the algorithm
342  nextHopRouter = getLsNextHop(i, sourceRouter);
343  // If this router is accessible at all
344  if (nextHopRouter != NO_NEXT_HOP) {
345 
346  // Fetch its distance
347  double routeCost = m_distance[i];
348  // Fetch its actual name
349  auto nextHopRouterName = pMap.getRouterNameByMappingNo(nextHopRouter);
350  if (nextHopRouterName) {
351  std::string nextHopFace =
352  adjacencies.getAdjacent(*nextHopRouterName).getFaceUri().toString();
353  // Add next hop to routing table
354  NextHop nh(nextHopFace, routeCost);
355  rt.addNextHop(*(pMap.getRouterNameByMappingNo(i)), nh);
356  }
357  }
358  }
359  }
360 }
361 
362 int
363 LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
364 {
365  int nextHop = NO_NEXT_HOP;
366  while (m_parent[dest] != EMPTY_PARENT) {
367  nextHop = dest;
368  dest = m_parent[dest];
369  }
370  if (dest != source) {
371  nextHop = NO_NEXT_HOP;
372  }
373  return nextHop;
374 }
375 
376 void
377 LinkStateRoutingTableCalculator::sortQueueByDistance(int* Q,
378  double* dist,
379  int start, int element)
380 {
381  for (int i = start ; i < element ; i++) {
382  for (int j = i + 1; j < element; j++) {
383  if (dist[Q[j]] < dist[Q[i]]) {
384  int tempU = Q[j];
385  Q[j] = Q[i];
386  Q[i] = tempU;
387  }
388  }
389  }
390 }
391 
392 int
393 LinkStateRoutingTableCalculator::isNotExplored(int* Q,
394  int u, int start, int element)
395 {
396  int ret = 0;
397  for (int i = start; i < element; i++) {
398  if (Q[i] == u) {
399  ret = 1;
400  break;
401  }
402  }
403  return ret;
404 }
405 
406 void
407 LinkStateRoutingTableCalculator::allocateParent()
408 {
409  m_parent = new int[m_nRouters];
410 }
411 
412 void
413 LinkStateRoutingTableCalculator::allocateDistance()
414 {
415  m_distance = new double[m_nRouters];
416 }
417 
418 void
419 LinkStateRoutingTableCalculator::freeParent()
420 {
421  delete [] m_parent;
422 }
423 
424 void LinkStateRoutingTableCalculator::freeDistance()
425 {
426  delete [] m_distance;
427 }
428 
429 void
431  Lsdb& lsdb, AdjacencyList& adjacencies)
432 {
433  NLSR_LOG_TRACE("Calculating hyperbolic paths");
434 
435  auto thisRouter = map.getMappingNoByRouterName(m_thisRouterName);
436 
437  // Iterate over directly connected neighbors
438  std::list<Adjacent> neighbors = adjacencies.getAdjList();
439  for (std::list<Adjacent>::iterator adj = neighbors.begin(); adj != neighbors.end(); ++adj) {
440 
441  // Don't calculate nexthops using an inactive router
442  if (adj->getStatus() == Adjacent::STATUS_INACTIVE) {
443  NLSR_LOG_TRACE(adj->getName() << " is inactive; not using it as a nexthop");
444  continue;
445  }
446 
447  ndn::Name srcRouterName = adj->getName();
448 
449  // Don't calculate nexthops for this router to other routers
450  if (srcRouterName == m_thisRouterName) {
451  continue;
452  }
453 
454  std::string srcFaceUri = adj->getFaceUri().toString();
455 
456  // Install nexthops for this router to the neighbor; direct neighbors have a 0 cost link
457  addNextHop(srcRouterName, srcFaceUri, 0, rt);
458 
459  auto src = map.getMappingNoByRouterName(srcRouterName);
460  if (!src) {
461  NLSR_LOG_WARN(adj->getName() << " does not exist in the router map!");
462  continue;
463  }
464 
465  // Get hyperbolic distance from direct neighbor to every other router
466  for (int dest = 0; dest < static_cast<int>(m_nRouters); ++dest) {
467  // Don't calculate nexthops to this router or from a router to itself
468  if (thisRouter && dest != *thisRouter && dest != *src) {
469 
470  auto destRouterName = map.getRouterNameByMappingNo(dest);
471  if (destRouterName) {
472  double distance = getHyperbolicDistance(lsdb, srcRouterName, *destRouterName);
473 
474  // Could not compute distance
475  if (distance == UNKNOWN_DISTANCE) {
476  NLSR_LOG_WARN("Could not calculate hyperbolic distance from " << srcRouterName
477  << " to " << *destRouterName);
478  continue;
479  }
480  addNextHop(*destRouterName, srcFaceUri, distance, rt);
481  }
482  }
483  }
484  }
485 }
486 
487 double
488 HyperbolicRoutingCalculator::getHyperbolicDistance(Lsdb& lsdb, ndn::Name src, ndn::Name dest)
489 {
490  NLSR_LOG_TRACE("Calculating hyperbolic distance from " << src << " to " << dest);
491 
492  double distance = UNKNOWN_DISTANCE;
493 
494  auto srcLsa = lsdb.findLsa<CoordinateLsa>(src);
495  auto destLsa = lsdb.findLsa<CoordinateLsa>(dest);
496 
497  // Coordinate LSAs do not exist for these routers
498  if (srcLsa == nullptr || destLsa == nullptr) {
499  return UNKNOWN_DISTANCE;
500  }
501 
502  std::vector<double> srcTheta = srcLsa->getCorTheta();
503  std::vector<double> destTheta = destLsa->getCorTheta();
504 
505  double srcRadius = srcLsa->getCorRadius();
506  double destRadius = destLsa->getCorRadius();
507 
508  double diffTheta = calculateAngularDistance(srcTheta, destTheta);
509 
510  if (srcRadius == UNKNOWN_RADIUS || destRadius == UNKNOWN_RADIUS ||
511  diffTheta == UNKNOWN_DISTANCE) {
512  return UNKNOWN_DISTANCE;
513  }
514 
515  // double r_i, double r_j, double delta_theta, double zeta = 1 (default)
516  distance = calculateHyperbolicDistance(srcRadius, destRadius, diffTheta);
517 
518  NLSR_LOG_TRACE("Distance from " << src << " to " << dest << " is " << distance);
519 
520  return distance;
521 }
522 
523 double
524 HyperbolicRoutingCalculator::calculateAngularDistance(std::vector<double> angleVectorI,
525  std::vector<double> angleVectorJ)
526 {
527  // It is not possible for angle vector size to be zero as ensured by conf-file-processor
528 
529  // https://en.wikipedia.org/wiki/N-sphere#Spherical_coordinates
530 
531  // Check if two vector lengths are the same
532  if (angleVectorI.size() != angleVectorJ.size()) {
533  NLSR_LOG_ERROR("Angle vector sizes do not match");
534  return UNKNOWN_DISTANCE;
535  }
536 
537  // Check if all angles are within the [0, PI] and [0, 2PI] ranges
538  if (angleVectorI.size() > 1) {
539  for (unsigned int k = 0; k < angleVectorI.size() - 1; k++) {
540  if ((angleVectorI[k] > M_PI && angleVectorI[k] < 0.0) ||
541  (angleVectorJ[k] > M_PI && angleVectorJ[k] < 0.0)) {
542  NLSR_LOG_ERROR("Angle outside [0, PI]");
543  return UNKNOWN_DISTANCE;
544  }
545  }
546  }
547 
548  if (angleVectorI[angleVectorI.size()-1] > 2.*M_PI ||
549  angleVectorI[angleVectorI.size()-1] < 0.0) {
550  NLSR_LOG_ERROR("Angle not within [0, 2PI]");
551  return UNKNOWN_DISTANCE;
552  }
553 
554  if (angleVectorI[angleVectorI.size()-1] > 2.*M_PI ||
555  angleVectorI[angleVectorI.size()-1] < 0.0) {
556  NLSR_LOG_ERROR("Angle not within [0, 2PI]");
557  return UNKNOWN_DISTANCE;
558  }
559 
560  // deltaTheta = arccos(vectorI . vectorJ) -> do the inner product
561  double innerProduct = 0.0;
562 
563  // Calculate x0 of the vectors
564  double x0i = std::cos(angleVectorI[0]);
565  double x0j = std::cos(angleVectorJ[0]);
566 
567  // Calculate xn of the vectors
568  double xni = std::sin(angleVectorI[angleVectorI.size() - 1]);
569  double xnj = std::sin(angleVectorJ[angleVectorJ.size() - 1]);
570 
571  // Do the aggregation of the (n-1) coordinates (if there is more than one angle)
572  // i.e contraction of all (n-1)-dimensional angular coordinates to one variable
573  for (unsigned int k = 0; k < angleVectorI.size() - 1; k++) {
574  xni *= std::sin(angleVectorI[k]);
575  xnj *= std::sin(angleVectorJ[k]);
576  }
577  innerProduct += (x0i * x0j) + (xni * xnj);
578 
579  // If d > 1
580  if (angleVectorI.size() > 1) {
581  for (unsigned int m = 1; m < angleVectorI.size(); m++) {
582  // calculate euclidean coordinates given the angles and assuming R_sphere = 1
583  double xmi = std::cos(angleVectorI[m]);
584  double xmj = std::cos(angleVectorJ[m]);
585  for (unsigned int l = 0; l < m; l++) {
586  xmi *= std::sin(angleVectorI[l]);
587  xmj *= std::sin(angleVectorJ[l]);
588  }
589  innerProduct += xmi * xmj;
590  }
591  }
592 
593  // ArcCos of the inner product gives the angular distance
594  // between two points on a d-dimensional sphere
595  return std::acos(innerProduct);
596 }
597 
598 double
599 HyperbolicRoutingCalculator::calculateHyperbolicDistance(double rI, double rJ,
600  double deltaTheta)
601 {
602  if (deltaTheta == UNKNOWN_DISTANCE) {
603  return UNKNOWN_DISTANCE;
604  }
605 
606  // Usually, we set zeta = 1 in all experiments
607  double zeta = 1;
608 
609  if (deltaTheta <= 0.0 || rI <= 0.0 || rJ <= 0.0) {
610  NLSR_LOG_ERROR("Delta theta or rI or rJ is <= 0");
611  NLSR_LOG_ERROR("Please make sure that no two nodes have the exact same HR coordinates");
612  return UNKNOWN_DISTANCE;
613  }
614 
615  double xij = (1. / zeta) * std::acosh(std::cosh(zeta*rI) * std::cosh(zeta*rJ) -
616  std::sinh(zeta*rI)*std::sinh(zeta*rJ)*std::cos(deltaTheta));
617  return xij;
618 }
619 
620 void
621 HyperbolicRoutingCalculator::addNextHop(ndn::Name dest, std::string faceUri,
622  double cost, RoutingTable& rt)
623 {
624  NextHop hop(faceUri, cost);
625  hop.setHyperbolic(true);
626 
627  NLSR_LOG_TRACE("Calculated " << hop << " for destination: " << dest);
628 
629  if (m_isDryRun) {
630  rt.addNextHopToDryTable(dest, hop);
631  }
632  else {
633  rt.addNextHop(dest, hop);
634  }
635 }
636 
637 } // namespace nlsr
Data abstraction for AdjLsa AdjacencyLsa := ADJACENCY-LSA-TYPE TLV-LENGTH Lsa Adjacency*.
Definition: adj-lsa.hpp:38
std::list< Adjacent > & getAdjList()
static constexpr double NON_ADJACENT_COST
Definition: adjacent.hpp:187
A class to house all the configuration parameters for NLSR.
const ndn::Name & getRouterPrefix() const
AdjacencyList & getAdjacencyList()
uint32_t getMaxFacesPerPrefix() const
Data abstraction for CoordinateLsa CoordinateLsa := COORDINATE-LSA-TYPE TLV-LENGTH Lsa HyperbolicRadi...
double getCorRadius() const
const std::vector< double > getCorTheta() const
void calculatePath(Map &map, RoutingTable &rt, Lsdb &lsdb, AdjacencyList &adjacencies)
std::shared_ptr< T > findLsa(const ndn::Name &router) const
Definition: lsdb.hpp:116
std::pair< LsaContainer::index< Lsdb::byType >::type::iterator, LsaContainer::index< Lsdb::byType >::type::iterator > getLsdbIterator() const
Definition: lsdb.hpp:162
std::optional< int32_t > getMappingNoByRouterName(const ndn::Name &rName)
Definition: map.cpp:56
std::optional< ndn::Name > getRouterNameByMappingNo(int32_t mn) const
Definition: map.cpp:48
void initMatrix()
set NON_ADJACENT_COST i.e. -12345 to every cell of the matrix to ensure that the memory is safe....
int getNumOfLinkfromAdjMatrix(int sRouter)
Returns how many links a router in the matrix has.
void adjustAdMatrix(int source, int link, double linkCost)
Adjust a link cost in the adj. matrix.
void allocateAdjMatrix()
Allocate the space needed for the adj. matrix.
void makeAdjMatrix(const Lsdb &lsdb, Map &pMap)
Constructs an adj. matrix to calculate with.
void writeAdjMatrixLog(const Map &map) const
Writes a formated adjacent matrix to DEBUG log.
void getLinksFromAdjMatrix(int *links, double *linkCosts, int source)
Populates temp. variables with the link costs for some router.
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California.
#define NLSR_LOG_DEBUG(x)
Definition: logger.hpp:38
#define INIT_LOGGER(name)
Definition: logger.hpp:35
#define NLSR_LOG_WARN(x)
Definition: logger.hpp:40
#define NLSR_LOG_ERROR(x)
Definition: logger.hpp:41
#define NLSR_LOG_TRACE(x)
Definition: logger.hpp:37
@ RoutingTable
Definition: tlv-nlsr.hpp:47
Copyright (c) 2014-2020, The University of Memphis, Regents of the University of California.
constexpr int NO_NEXT_HOP
constexpr double INF_DISTANCE
constexpr int NO_MAPPING_NUM
constexpr int EMPTY_PARENT
constexpr double UNKNOWN_RADIUS
constexpr double UNKNOWN_DISTANCE