blob: e8bc8fdd02bdb6d2b56ebe35de3a653ca7e37953 [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);
Ashlesh Gawanded3ac7772016-11-06 00:53:05 -0600117
118 if (outRecord == pitEntry->out_end()) { // no out-record
119 NFD_LOG_TRACE(pitEntry->getInterest() << " dataFrom inFace=" << inFace.getId() << " no-out-record");
120 return;
121 }
122
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000123 time::steady_clock::Duration steadyRtt = time::steady_clock::now() - outRecord->getLastRenewed();
124 RttEstimator::Duration durationRtt = time::duration_cast<RttEstimator::Duration>(steadyRtt);
125
126 m_rttStats.addRttMeasurement(durationRtt);
127
128 NFD_LOG_TRACE("Recording RTT for FaceId: " << inFace.getId()
129 << " RTT: " << m_rttStats.getRtt()
130 << " SRTT: " << m_rttStats.getSrtt());
131}
132
133void
Junxiao Shifc021862016-08-25 21:51:18 +0000134FaceInfo::recordTimeout(const Name& interestName)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000135{
136 m_rttStats.recordTimeout();
137 cancelTimeoutEvent(interestName);
138}
139
140////////////////////////////////////////////////////////////////////////////////
141////////////////////////////////////////////////////////////////////////////////
142
143NamespaceInfo::NamespaceInfo()
144 : m_isProbingDue(false)
145 , m_hasFirstProbeBeenScheduled(false)
146{
147}
148
149FaceInfo*
150NamespaceInfo::getFaceInfo(const fib::Entry& fibEntry, const Face& face)
151{
152 FaceInfoTable::iterator it = m_fit.find(face.getId());
153
154 if (it != m_fit.end()) {
155 return &it->second;
156 }
157 else {
158 return nullptr;
159 }
160}
161
162FaceInfo&
163NamespaceInfo::getOrCreateFaceInfo(const fib::Entry& fibEntry, const Face& face)
164{
165 FaceInfoTable::iterator it = m_fit.find(face.getId());
166
167 FaceInfo* info = nullptr;
168
169 if (it == m_fit.end()) {
170 const auto& pair = m_fit.insert(std::make_pair(face.getId(), FaceInfo()));
171 info = &pair.first->second;
172
173 extendFaceInfoLifetime(*info, face);
174 }
175 else {
176 info = &it->second;
177 }
178
179 return *info;
180}
181
182void
183NamespaceInfo::expireFaceInfo(nfd::face::FaceId faceId)
184{
185 m_fit.erase(faceId);
186}
187
188void
189NamespaceInfo::extendFaceInfoLifetime(FaceInfo& info, const Face& face)
190{
191 // Cancel previous expiration
192 scheduler::cancel(info.getMeasurementExpirationEventId());
193
194 // Refresh measurement
195 scheduler::EventId id = scheduler::schedule(AsfMeasurements::MEASUREMENTS_LIFETIME,
196 bind(&NamespaceInfo::expireFaceInfo, this, face.getId()));
197
198 info.setMeasurementExpirationEventId(id);
199}
200
201////////////////////////////////////////////////////////////////////////////////
202////////////////////////////////////////////////////////////////////////////////
203
204constexpr time::microseconds AsfMeasurements::MEASUREMENTS_LIFETIME;
205
206AsfMeasurements::AsfMeasurements(MeasurementsAccessor& measurements)
207 : m_measurements(measurements)
208{
209}
210
211FaceInfo*
Junxiao Shifc021862016-08-25 21:51:18 +0000212AsfMeasurements::getFaceInfo(const fib::Entry& fibEntry, const Interest& interest, const Face& face)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000213{
214 NamespaceInfo& info = getOrCreateNamespaceInfo(fibEntry, interest);
215 return info.getFaceInfo(fibEntry, face);
216}
217
218FaceInfo&
Junxiao Shifc021862016-08-25 21:51:18 +0000219AsfMeasurements::getOrCreateFaceInfo(const fib::Entry& fibEntry, const Interest& interest, const Face& face)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000220{
221 NamespaceInfo& info = getOrCreateNamespaceInfo(fibEntry, interest);
222 return info.getOrCreateFaceInfo(fibEntry, face);
223}
224
Junxiao Shifc021862016-08-25 21:51:18 +0000225NamespaceInfo*
226AsfMeasurements::getNamespaceInfo(const Name& prefix)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000227{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000228 measurements::Entry* me = m_measurements.findLongestPrefixMatch(prefix);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000229 if (me == nullptr) {
230 return nullptr;
231 }
232
233 // Set or update entry lifetime
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000234 extendLifetime(*me);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000235
Junxiao Shifc021862016-08-25 21:51:18 +0000236 NamespaceInfo* info = me->insertStrategyInfo<NamespaceInfo>().first;
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000237 BOOST_ASSERT(info != nullptr);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000238 return info;
239}
240
241NamespaceInfo&
Junxiao Shifc021862016-08-25 21:51:18 +0000242AsfMeasurements::getOrCreateNamespaceInfo(const fib::Entry& fibEntry, const Interest& interest)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000243{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000244 measurements::Entry* me = m_measurements.get(fibEntry);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000245
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
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000257 extendLifetime(*me);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000258
Junxiao Shifc021862016-08-25 21:51:18 +0000259 NamespaceInfo* info = me->insertStrategyInfo<NamespaceInfo>().first;
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000260 BOOST_ASSERT(info != nullptr);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000261 return *info;
262}
263
264void
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000265AsfMeasurements::extendLifetime(measurements::Entry& me)
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000266{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000267 m_measurements.extendLifetime(me, MEASUREMENTS_LIFETIME);
Vince Lehman8a4c29e2016-07-11 08:49:35 +0000268}
269
270} // namespace asf
271} // namespace fw
272} // namespace nfd