asf-measurements.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2014-2019, Regents of the University of California,
4  * Arizona Board of Regents,
5  * Colorado State University,
6  * University Pierre & Marie Curie, Sorbonne University,
7  * Washington University in St. Louis,
8  * Beijing Institute of Technology,
9  * The University of Memphis.
10  *
11  * This file is part of NFD (Named Data Networking Forwarding Daemon).
12  * See AUTHORS.md for complete list of NFD authors and contributors.
13  *
14  * NFD is free software: you can redistribute it and/or modify it under the terms
15  * of the GNU General Public License as published by the Free Software Foundation,
16  * either version 3 of the License, or (at your option) any later version.
17  *
18  * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20  * PURPOSE. See the GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License along with
23  * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24  */
25 
26 #include "asf-measurements.hpp"
27 #include "common/global.hpp"
28 
29 namespace nfd {
30 namespace fw {
31 namespace asf {
32 
34 
37 const double RttStats::ALPHA = 0.125;
38 
40  : m_srtt(RTT_NO_MEASUREMENT)
41  , m_rtt(RTT_NO_MEASUREMENT)
42 {
43 }
44 
45 void
47 {
48  m_rtt = static_cast<RttStats::Rtt>(durationRtt.count());
49 
50  m_rttEstimator.addMeasurement(durationRtt);
51 
52  m_srtt = computeSrtt(m_srtt, m_rtt);
53 }
54 
56 RttStats::computeSrtt(Rtt previousSrtt, Rtt currentRtt)
57 {
58  if (previousSrtt == RTT_NO_MEASUREMENT) {
59  return currentRtt;
60  }
61 
62  return Rtt(ALPHA * currentRtt + (1 - ALPHA) * previousSrtt);
63 }
64 
67 
69  : m_isTimeoutScheduled(false)
70  , m_nSilentTimeouts(0)
71 {
72 }
73 
75 {
77  m_measurementExpirationId.cancel();
78 }
79 
80 void
81 FaceInfo::setTimeoutEvent(const scheduler::EventId& id, const Name& interestName)
82 {
83  if (!m_isTimeoutScheduled) {
84  m_timeoutEventId = id;
85  m_isTimeoutScheduled = true;
86  m_lastInterestName = interestName;
87  }
88  else {
89  NDN_THROW(FaceInfo::Error("Tried to schedule a timeout for a face that already has a timeout scheduled"));
90  }
91 }
92 
93 void
94 FaceInfo::cancelTimeoutEvent()
95 {
96  m_timeoutEventId.cancel();
97  m_isTimeoutScheduled = false;
98 }
99 
100 void
101 FaceInfo::cancelTimeoutEvent(const Name& prefix)
102 {
103  if (isTimeoutScheduled() && doesNameMatchLastInterest(prefix)) {
105  }
106 }
107 
108 bool
109 FaceInfo::doesNameMatchLastInterest(const Name& name)
110 {
111  return m_lastInterestName.isPrefixOf(name);
112 }
113 
114 void
115 FaceInfo::recordRtt(const shared_ptr<pit::Entry>& pitEntry, const Face& inFace)
116 {
117  // Calculate RTT
118  auto outRecord = pitEntry->getOutRecord(inFace, 0);
119 
120  if (outRecord == pitEntry->out_end()) { // no out-record
121  NFD_LOG_TRACE(pitEntry->getInterest() << " dataFrom inFace=" << inFace.getId() << " no-out-record");
122  return;
123  }
124 
125  time::steady_clock::Duration steadyRtt = time::steady_clock::now() - outRecord->getLastRenewed();
126  auto durationRtt = time::duration_cast<RttEstimator::Duration>(steadyRtt);
127 
128  m_rttStats.addRttMeasurement(durationRtt);
129 
130  NFD_LOG_TRACE("Recording RTT for FaceId: " << inFace.getId()
131  << " RTT: " << m_rttStats.getRtt()
132  << " SRTT: " << m_rttStats.getSrtt());
133 }
134 
135 void
136 FaceInfo::recordTimeout(const Name& interestName)
137 {
138  m_rttStats.recordTimeout();
139  cancelTimeoutEvent(interestName);
140 }
141 
144 
146  : m_isProbingDue(false)
147  , m_hasFirstProbeBeenScheduled(false)
148 {
149 }
150 
151 FaceInfo*
153 {
154  auto it = m_fit.find(faceId);
155  if (it != m_fit.end()) {
156  return &it->second;
157  }
158  else {
159  return nullptr;
160  }
161 }
162 
163 FaceInfo&
165 {
166  auto it = m_fit.find(faceId);
167  FaceInfo* info = nullptr;
168 
169  if (it == m_fit.end()) {
170  const auto& pair = m_fit.emplace(faceId, FaceInfo());
171  info = &pair.first->second;
172 
173  extendFaceInfoLifetime(*info, faceId);
174  }
175  else {
176  info = &it->second;
177  }
178 
179  return *info;
180 }
181 
182 void
184 {
185  m_fit.erase(faceId);
186 }
187 
188 void
190 {
191  // Cancel previous expiration
192  info.getMeasurementExpirationEventId().cancel();
193 
194  // Refresh measurement
196  [=] { expireFaceInfo(faceId); });
198 }
199 
202 
203 constexpr time::microseconds AsfMeasurements::MEASUREMENTS_LIFETIME;
204 
205 AsfMeasurements::AsfMeasurements(MeasurementsAccessor& measurements)
206  : m_measurements(measurements)
207 {
208 }
209 
210 FaceInfo*
211 AsfMeasurements::getFaceInfo(const fib::Entry& fibEntry, const Interest& interest, FaceId faceId)
212 {
213  NamespaceInfo& info = getOrCreateNamespaceInfo(fibEntry, interest);
214  return info.getFaceInfo(fibEntry, faceId);
215 }
216 
217 FaceInfo&
218 AsfMeasurements::getOrCreateFaceInfo(const fib::Entry& fibEntry, const Interest& interest,
219  FaceId faceId)
220 {
221  NamespaceInfo& info = getOrCreateNamespaceInfo(fibEntry, interest);
222  return info.getOrCreateFaceInfo(fibEntry, faceId);
223 }
224 
227 {
228  measurements::Entry* me = m_measurements.findLongestPrefixMatch(prefix);
229  if (me == nullptr) {
230  return nullptr;
231  }
232 
233  // Set or update entry lifetime
234  extendLifetime(*me);
235 
236  NamespaceInfo* info = me->insertStrategyInfo<NamespaceInfo>().first;
237  BOOST_ASSERT(info != nullptr);
238  return info;
239 }
240 
242 AsfMeasurements::getOrCreateNamespaceInfo(const fib::Entry& fibEntry, const Interest& interest)
243 {
244  measurements::Entry* me = m_measurements.get(fibEntry);
245 
246  // If the FIB entry is not under the strategy's namespace, find a part of the prefix
247  // that falls under the strategy's namespace
248  for (size_t prefixLen = fibEntry.getPrefix().size() + 1;
249  me == nullptr && prefixLen <= interest.getName().size(); ++prefixLen) {
250  me = m_measurements.get(interest.getName().getPrefix(prefixLen));
251  }
252 
253  // Either the FIB entry or the Interest's name must be under this strategy's namespace
254  BOOST_ASSERT(me != nullptr);
255 
256  // Set or update entry lifetime
257  extendLifetime(*me);
258 
259  NamespaceInfo* info = me->insertStrategyInfo<NamespaceInfo>().first;
260  BOOST_ASSERT(info != nullptr);
261  return *info;
262 }
263 
264 void
265 AsfMeasurements::extendLifetime(measurements::Entry& me)
266 {
267  m_measurements.extendLifetime(me, MEASUREMENTS_LIFETIME);
268 }
269 
270 } // namespace asf
271 } // namespace fw
272 } // namespace nfd
FaceInfo * getFaceInfo(const fib::Entry &fibEntry, const Interest &interest, FaceId faceId)
const Name & getName() const
void extendFaceInfoLifetime(FaceInfo &info, FaceId faceId)
Represents a Measurements entry.
NamespaceInfo * getNamespaceInfo(const Name &prefix)
represents a FIB entry
Definition: fib-entry.hpp:51
#define NFD_LOG_TRACE
Definition: logger.hpp:37
void addRttMeasurement(RttEstimator::Duration &durationRtt)
FaceInfo & getOrCreateFaceInfo(const fib::Entry &fibEntry, const Interest &interest, FaceId faceId)
time::duration< double, boost::micro > Rtt
std::pair< T *, bool > insertStrategyInfo(A &&...args)
Insert a StrategyInfo item.
time::microseconds Duration
Scheduler & getScheduler()
Returns the global Scheduler instance for the calling thread.
Definition: global.cpp:45
void cancelTimeoutEvent(const Name &prefix)
FaceInfo & getOrCreateFaceInfo(const fib::Entry &fibEntry, FaceId faceId)
void expireFaceInfo(FaceId faceId)
const Name & getPrefix() const
Definition: fib-entry.hpp:58
static constexpr time::microseconds MEASUREMENTS_LIFETIME
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
Definition: algorithm.hpp:32
NamespaceInfo & getOrCreateNamespaceInfo(const fib::Entry &fibEntry, const Interest &interest)
const scheduler::EventId & getMeasurementExpirationEventId()
bool isTimeoutScheduled() const
void recordRtt(const shared_ptr< pit::Entry > &pitEntry, const Face &inFace)
stores stategy information about each face in this namespace
void recordTimeout(const Name &interestName)
FaceInfo * getFaceInfo(const fib::Entry &fibEntry, FaceId faceId)
void setTimeoutEvent(const scheduler::EventId &id, const Name &interestName)
#define NFD_LOG_INIT(name)
Definition: logger.hpp:31
static const Rtt RTT_TIMEOUT
uint64_t FaceId
identifies a face
Definition: face.hpp:39
AsfMeasurements(MeasurementsAccessor &measurements)
void setMeasurementExpirationEventId(const scheduler::EventId &id)
void addMeasurement(Duration measure)
Strategy information for each face in a namespace.
Helper class to retrieve and create strategy measurements.
static const Rtt RTT_NO_MEASUREMENT