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