NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.3: NDN, CCN, CCNx, content centric networks
API Documentation
asf-probing-module.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
26 #include "asf-probing-module.hpp"
27 #include "core/random.hpp"
28 #include "algorithm.hpp"
29 
30 namespace nfd {
31 namespace fw {
32 namespace asf {
33 
34 constexpr time::seconds ProbingModule::DEFAULT_PROBING_INTERVAL;
35 
36 static_assert(ProbingModule::DEFAULT_PROBING_INTERVAL < AsfMeasurements::MEASUREMENTS_LIFETIME,
37  "ProbingModule::DEFAULT_PROBING_INTERVAL must be less than AsfMeasurements::MEASUREMENTS_LIFETIME");
38 
40  : m_probingInterval(DEFAULT_PROBING_INTERVAL)
41  , m_measurements(measurements)
42 {
43 }
44 
45 void
47 {
48  Name prefix = fibEntry.getPrefix();
49 
50  // Set the probing flag for the namespace to true after passed interval of time
51  scheduler::schedule(interval, [this, prefix] {
52  NamespaceInfo* info = m_measurements.getNamespaceInfo(prefix);
53 
54  if (info == nullptr) {
55  // fib::Entry with the passed prefix has been removed or the fib::Entry has
56  // a name that is not controlled by the AsfStrategy
57  return;
58  }
59  else {
60  info->setIsProbingDue(true);
61  }
62  });
63 }
64 
65 Face*
67  const Interest& interest,
68  const fib::Entry& fibEntry,
69  const Face& faceUsed)
70 {
71  FaceInfoFacePairSet rankedFaces(
72  [] (FaceInfoFacePair pairLhs, FaceInfoFacePair pairRhs) -> bool {
73  // Sort by RTT
74  // If a face has timed-out, rank it behind non-timed-out faces
75  FaceInfo& lhs = *pairLhs.first;
76  FaceInfo& rhs = *pairRhs.first;
77 
78  return (!lhs.isTimeout() && rhs.isTimeout()) ||
79  (lhs.isTimeout() == rhs.isTimeout() && lhs.getSrtt() < rhs.getSrtt());
80  });
81 
82  // Put eligible faces into rankedFaces. If a face does not have an RTT measurement,
83  // immediately pick the face for probing
84  for (const fib::NextHop& hop : fibEntry.getNextHops()) {
85  Face& hopFace = hop.getFace();
86 
87  // Don't send probe Interest back to the incoming face or use the same face
88  // as the forwarded Interest or use a face that violates scope
89  if (hopFace.getId() == inFace.getId() || hopFace.getId() == faceUsed.getId() ||
90  wouldViolateScope(inFace, interest, hopFace)) {
91  continue;
92  }
93 
94  FaceInfo* info = m_measurements.getFaceInfo(fibEntry, interest, hopFace);
95 
96  // If no RTT has been recorded, probe this face
97  if (info == nullptr || !info->hasSrttMeasurement()) {
98  return &hopFace;
99  }
100 
101  // Add FaceInfo to container sorted by RTT
102  rankedFaces.insert(std::make_pair(info, &hopFace));
103  }
104 
105  if (rankedFaces.empty()) {
106  // No Face to probe
107  return nullptr;
108  }
109 
110  return getFaceBasedOnProbability(rankedFaces);
111 }
112 
113 bool
114 ProbingModule::isProbingNeeded(const fib::Entry& fibEntry, const Interest& interest)
115 {
116  // Return the probing status flag for a namespace
117  NamespaceInfo& info = m_measurements.getOrCreateNamespaceInfo(fibEntry, interest);
118 
119  // If a first probe has not been scheduled for a namespace
120  if (!info.isFirstProbeScheduled()) {
121  // Schedule first probe between 0 and 5 seconds
122  uint64_t interval = getRandomNumber(0, 5000);
123  scheduleProbe(fibEntry, time::milliseconds(interval));
124 
126  }
127 
128  return info.isProbingDue();
129 }
130 
131 void
132 ProbingModule::afterForwardingProbe(const fib::Entry& fibEntry, const Interest& interest)
133 {
134  // After probing is done, need to set probing flag to false and
135  // schedule another future probe
136  NamespaceInfo& info = m_measurements.getOrCreateNamespaceInfo(fibEntry, interest);
137  info.setIsProbingDue(false);
138 
139  scheduleProbe(fibEntry, m_probingInterval);
140 }
141 
142 Face*
143 ProbingModule::getFaceBasedOnProbability(const FaceInfoFacePairSet& rankedFaces)
144 {
145  double randomNumber = getRandomNumber(0, 1);
146  uint64_t rankSum = ((rankedFaces.size() + 1) * rankedFaces.size()) / 2;
147 
148  uint64_t rank = 1;
149  double offset = 0.0;
150 
151  for (const FaceInfoFacePair pair : rankedFaces) {
152  double probability = getProbingProbability(rank++, rankSum, rankedFaces.size());
153 
154  // Is the random number within the bounds of this face's probability + the previous faces'
155  // probability?
156  //
157  // e.g. (FaceId: 1, p=0.5), (FaceId: 2, p=0.33), (FaceId: 3, p=0.17)
158  // randomNumber = 0.92
159  //
160  // The face with FaceId: 3 should be picked
161  // (0.68 < 0.5 + 0.33 + 0.17) == true
162  //
163  if (randomNumber <= offset + probability) {
164  // Found face to probe
165  return pair.second;
166  }
167 
168  offset += probability;
169  }
170 
171  // Given a set of Faces, this method should always select a Face to probe
172  BOOST_ASSERT(false);
173  return nullptr;
174 }
175 
176 double
177 ProbingModule::getProbingProbability(uint64_t rank, uint64_t rankSum, uint64_t nFaces)
178 {
179  // p = n + 1 - j ; n: # faces
180  // ---------
181  // sum(ranks)
182  return static_cast<double>(nFaces + 1 - rank) / rankSum;
183 }
184 
185 double
186 ProbingModule::getRandomNumber(double start, double end)
187 {
188  std::uniform_real_distribution<double> dist(start, end);
189  return dist(getGlobalRng());
190 }
191 
192 } // namespace asf
193 } // namespace fw
194 } // namespace nfd
Declares the global pseudorandom number generator (PRNG) for NFD.
Helper class to retrieve and create strategy measurements.
represents a FIB entry
Definition: fib-entry.hpp:51
boost::posix_time::time_duration milliseconds(long duration)
Definition: asio.hpp:117
ProbingModule(AsfMeasurements &measurements)
RttStats::Rtt getSrtt() const
represents an Interest packet
Definition: interest.hpp:42
stores stategy information about each face in this namespace
bool isProbingNeeded(const fib::Entry &fibEntry, const Interest &interest)
ndn Face
Definition: face-impl.hpp:41
FaceInfo * getFaceInfo(const fib::Entry &fibEntry, const Interest &interest, const Face &face)
Copyright (c) 2011-2015 Regents of the University of California.
Definition: ndn-common.hpp:40
void setHasFirstProbeBeenScheduled(bool hasBeenScheduled)
void setIsProbingDue(bool isProbingDue)
NamespaceInfo & getOrCreateNamespaceInfo(const fib::Entry &fibEntry, const Interest &interest)
static constexpr time::microseconds MEASUREMENTS_LIFETIME
void scheduleProbe(const fib::Entry &fibEntry, const time::milliseconds &interval)
Represents an absolute name.
Definition: name.hpp:42
Face * getFaceToProbe(const Face &inFace, const Interest &interest, const fib::Entry &fibEntry, const Face &faceUsed)
const NextHopList & getNextHops() const
Definition: fib-entry.hpp:64
Strategy information for each face in a namespace.
std::mt19937 & getGlobalRng()
Definition: random.cpp:32
NamespaceInfo * getNamespaceInfo(const Name &prefix)
This file contains common algorithms used by forwarding strategies.
EventId schedule(time::nanoseconds after, const EventCallback &event)
schedule an event
Definition: scheduler.cpp:47
void afterForwardingProbe(const fib::Entry &fibEntry, const Interest &interest)
bool hasSrttMeasurement() const
static constexpr time::seconds DEFAULT_PROBING_INTERVAL
bool wouldViolateScope(const Face &inFace, const Interest &interest, const Face &outFace)
determine whether forwarding the Interest in pitEntry to outFace would violate scope ...
Definition: algorithm.cpp:37
const Name & getPrefix() const
Definition: fib-entry.hpp:58
represents a nexthop record in FIB entry
Definition: fib-nexthop.hpp:38