blob: c98ca86be8061bd85737f066ebfb209f9e85d709 [file] [log] [blame]
Vince Lehman8a4c29e2016-07-11 08:49:35 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2016, 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
28namespace nfd {
29namespace fw {
30namespace asf {
31
32NFD_LOG_INIT("AsfMeasurements");
33
34const RttStats::Rtt RttStats::RTT_TIMEOUT(-1.0);
35const RttStats::Rtt RttStats::RTT_NO_MEASUREMENT(0.0);
36const double RttStats::ALPHA = 0.125;
37
38RttStats::RttStats()
39 : m_srtt(RTT_NO_MEASUREMENT)
40 , m_rtt(RTT_NO_MEASUREMENT)
41{
42}
43
44void
45RttStats::addRttMeasurement(RttEstimator::Duration& durationRtt)
46{
47 m_rtt = static_cast<RttStats::Rtt>(durationRtt.count());
48
49 m_rttEstimator.addMeasurement(durationRtt);
50
51 m_srtt = computeSrtt(m_srtt, m_rtt);
52}
53
54RttStats::Rtt
55RttStats::computeSrtt(Rtt previousSrtt, Rtt currentRtt)
56{
57 if (previousSrtt == RTT_NO_MEASUREMENT) {
58 return currentRtt;
59 }
60
61 return Rtt(ALPHA * currentRtt + (1 - ALPHA) * previousSrtt);
62}
63
64////////////////////////////////////////////////////////////////////////////////
65////////////////////////////////////////////////////////////////////////////////
66
67FaceInfo::FaceInfo()
68 : m_isTimeoutScheduled(false)
69{
70}
71
72FaceInfo::~FaceInfo()
73{
74 cancelTimeoutEvent();
75 scheduler::cancel(m_measurementExpirationId);
76}
77
78void
Junxiao Shifc021862016-08-25 21:51:18 +000079FaceInfo::setTimeoutEvent(const scheduler::EventId& id, const Name& interestName)
Vince Lehman8a4c29e2016-07-11 08:49:35 +000080{
81 if (!m_isTimeoutScheduled) {
82 m_timeoutEventId = id;
83 m_isTimeoutScheduled = true;
84 m_lastInterestName = interestName;
85 }
86 else {
87 BOOST_THROW_EXCEPTION(FaceInfo::Error("Tried to schedule a timeout for a face that already has a timeout scheduled."));
88 }
89}
90
91void
92FaceInfo::cancelTimeoutEvent()
93{
94 scheduler::cancel(m_timeoutEventId);
95 m_isTimeoutScheduled = false;
96}
97
98void
Junxiao Shifc021862016-08-25 21:51:18 +000099FaceInfo::cancelTimeoutEvent(const Name& prefix)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000100{
101 if (isTimeoutScheduled() && doesNameMatchLastInterest(prefix)) {
102 cancelTimeoutEvent();
103 }
104}
105
106bool
Junxiao Shifc021862016-08-25 21:51:18 +0000107FaceInfo::doesNameMatchLastInterest(const Name& name)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000108{
109 return m_lastInterestName.isPrefixOf(name);
110}
111
112void
Junxiao Shi15e98b02016-08-12 11:21:44 +0000113FaceInfo::recordRtt(const shared_ptr<pit::Entry>& pitEntry, const Face& inFace)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000114{
115 // Calculate RTT
116 pit::OutRecordCollection::const_iterator outRecord = pitEntry->getOutRecord(inFace);
117 time::steady_clock::Duration steadyRtt = time::steady_clock::now() - outRecord->getLastRenewed();
118 RttEstimator::Duration durationRtt = time::duration_cast<RttEstimator::Duration>(steadyRtt);
119
120 m_rttStats.addRttMeasurement(durationRtt);
121
122 NFD_LOG_TRACE("Recording RTT for FaceId: " << inFace.getId()
123 << " RTT: " << m_rttStats.getRtt()
124 << " SRTT: " << m_rttStats.getSrtt());
125}
126
127void
Junxiao Shifc021862016-08-25 21:51:18 +0000128FaceInfo::recordTimeout(const Name& interestName)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000129{
130 m_rttStats.recordTimeout();
131 cancelTimeoutEvent(interestName);
132}
133
134////////////////////////////////////////////////////////////////////////////////
135////////////////////////////////////////////////////////////////////////////////
136
137NamespaceInfo::NamespaceInfo()
138 : m_isProbingDue(false)
139 , m_hasFirstProbeBeenScheduled(false)
140{
141}
142
143FaceInfo*
144NamespaceInfo::getFaceInfo(const fib::Entry& fibEntry, const Face& face)
145{
146 FaceInfoTable::iterator it = m_fit.find(face.getId());
147
148 if (it != m_fit.end()) {
149 return &it->second;
150 }
151 else {
152 return nullptr;
153 }
154}
155
156FaceInfo&
157NamespaceInfo::getOrCreateFaceInfo(const fib::Entry& fibEntry, const Face& face)
158{
159 FaceInfoTable::iterator it = m_fit.find(face.getId());
160
161 FaceInfo* info = nullptr;
162
163 if (it == m_fit.end()) {
164 const auto& pair = m_fit.insert(std::make_pair(face.getId(), FaceInfo()));
165 info = &pair.first->second;
166
167 extendFaceInfoLifetime(*info, face);
168 }
169 else {
170 info = &it->second;
171 }
172
173 return *info;
174}
175
176void
177NamespaceInfo::expireFaceInfo(nfd::face::FaceId faceId)
178{
179 m_fit.erase(faceId);
180}
181
182void
183NamespaceInfo::extendFaceInfoLifetime(FaceInfo& info, const Face& face)
184{
185 // Cancel previous expiration
186 scheduler::cancel(info.getMeasurementExpirationEventId());
187
188 // Refresh measurement
189 scheduler::EventId id = scheduler::schedule(AsfMeasurements::MEASUREMENTS_LIFETIME,
190 bind(&NamespaceInfo::expireFaceInfo, this, face.getId()));
191
192 info.setMeasurementExpirationEventId(id);
193}
194
195////////////////////////////////////////////////////////////////////////////////
196////////////////////////////////////////////////////////////////////////////////
197
198constexpr time::microseconds AsfMeasurements::MEASUREMENTS_LIFETIME;
199
200AsfMeasurements::AsfMeasurements(MeasurementsAccessor& measurements)
201 : m_measurements(measurements)
202{
203}
204
205FaceInfo*
Junxiao Shifc021862016-08-25 21:51:18 +0000206AsfMeasurements::getFaceInfo(const fib::Entry& fibEntry, const Interest& interest, const Face& face)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000207{
208 NamespaceInfo& info = getOrCreateNamespaceInfo(fibEntry, interest);
209 return info.getFaceInfo(fibEntry, face);
210}
211
212FaceInfo&
Junxiao Shifc021862016-08-25 21:51:18 +0000213AsfMeasurements::getOrCreateFaceInfo(const fib::Entry& fibEntry, const Interest& interest, const Face& face)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000214{
215 NamespaceInfo& info = getOrCreateNamespaceInfo(fibEntry, interest);
216 return info.getOrCreateFaceInfo(fibEntry, face);
217}
218
Junxiao Shifc021862016-08-25 21:51:18 +0000219NamespaceInfo*
220AsfMeasurements::getNamespaceInfo(const Name& prefix)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000221{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000222 measurements::Entry* me = m_measurements.findLongestPrefixMatch(prefix);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000223 if (me == nullptr) {
224 return nullptr;
225 }
226
227 // Set or update entry lifetime
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000228 extendLifetime(*me);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000229
Junxiao Shifc021862016-08-25 21:51:18 +0000230 NamespaceInfo* info = me->insertStrategyInfo<NamespaceInfo>().first;
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000231 BOOST_ASSERT(info != nullptr);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000232 return info;
233}
234
235NamespaceInfo&
Junxiao Shifc021862016-08-25 21:51:18 +0000236AsfMeasurements::getOrCreateNamespaceInfo(const fib::Entry& fibEntry, const Interest& interest)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000237{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000238 measurements::Entry* me = m_measurements.get(fibEntry);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000239
240 // If the FIB entry is not under the strategy's namespace, find a part of the prefix
241 // that falls under the strategy's namespace
242 for (size_t prefixLen = fibEntry.getPrefix().size() + 1;
243 me == nullptr && prefixLen <= interest.getName().size(); ++prefixLen) {
244 me = m_measurements.get(interest.getName().getPrefix(prefixLen));
245 }
246
247 // Either the FIB entry or the Interest's name must be under this strategy's namespace
248 BOOST_ASSERT(me != nullptr);
249
250 // Set or update entry lifetime
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000251 extendLifetime(*me);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000252
Junxiao Shifc021862016-08-25 21:51:18 +0000253 NamespaceInfo* info = me->insertStrategyInfo<NamespaceInfo>().first;
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000254 BOOST_ASSERT(info != nullptr);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000255 return *info;
256}
257
258void
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000259AsfMeasurements::extendLifetime(measurements::Entry& me)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000260{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000261 m_measurements.extendLifetime(me, MEASUREMENTS_LIFETIME);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000262}
263
264} // namespace asf
265} // namespace fw
266} // namespace nfd