blob: 50632007b8379fb7146f1c5d737cf4740f57d228 [file] [log] [blame]
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyev0c63c632017-12-05 11:17:09 -05002/*
ashiqopu3ad49db2018-10-20 22:38:47 +00003 * Copyright (c) 2014-2019, Regents of the University of California,
Junxiao Shi63162202015-01-14 22:27:33 -07004 * 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.
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
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/>.
Junxiao Shiaf6569a2014-06-14 00:01:34 -070024 */
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070025
26#include "ncc-strategy.hpp"
Junxiao Shi00dc9142016-11-21 14:23:12 +000027#include "algorithm.hpp"
Davide Pesavento3dade002019-03-19 11:29:56 -060028#include "daemon/global.hpp"
Davide Pesaventob8bd5ee2019-02-03 22:53:40 -050029
30#include <ndn-cxx/util/random.hpp>
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070031
32namespace nfd {
33namespace fw {
34
Junxiao Shifaf3eb02015-02-16 10:50:36 -070035NFD_REGISTER_STRATEGY(NccStrategy);
Junxiao Shif3c07812014-03-11 21:48:49 -070036
Davide Pesaventoe4b22382018-06-10 14:37:24 -040037const time::microseconds NccStrategy::DEFER_FIRST_WITHOUT_BEST_FACE = 4_ms;
38const time::microseconds NccStrategy::DEFER_RANGE_WITHOUT_BEST_FACE = 75_ms;
39const time::nanoseconds NccStrategy::MEASUREMENTS_LIFETIME = 16_s;
Junxiao Shi037f4ab2016-12-13 04:27:06 +000040
Junxiao Shif3c07812014-03-11 21:48:49 -070041NccStrategy::NccStrategy(Forwarder& forwarder, const Name& name)
Junxiao Shi18739c42016-12-22 08:03:00 +000042 : Strategy(forwarder)
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070043{
Junxiao Shi18739c42016-12-22 08:03:00 +000044 ParsedInstanceName parsed = parseInstanceName(name);
45 if (!parsed.parameters.empty()) {
Davide Pesavento19779d82019-02-14 13:40:04 -050046 NDN_THROW(std::invalid_argument("NccStrategy does not accept parameters"));
Junxiao Shi18739c42016-12-22 08:03:00 +000047 }
Junxiao Shi91f6ee02016-12-29 21:44:44 +000048 if (parsed.version && *parsed.version != getStrategyName()[-1].toVersion()) {
Davide Pesavento19779d82019-02-14 13:40:04 -050049 NDN_THROW(std::invalid_argument(
Alexander Afanasyev0c63c632017-12-05 11:17:09 -050050 "NccStrategy does not support version " + to_string(*parsed.version)));
Junxiao Shi91f6ee02016-12-29 21:44:44 +000051 }
Junxiao Shi18739c42016-12-22 08:03:00 +000052 this->setInstanceName(makeInstanceName(name, getStrategyName()));
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070053}
54
Junxiao Shi037f4ab2016-12-13 04:27:06 +000055const Name&
56NccStrategy::getStrategyName()
57{
58 static Name strategyName("/localhost/nfd/strategy/ncc/%FD%01");
59 return strategyName;
60}
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070061
62void
ashiqopuc7079482019-02-20 05:34:37 +000063NccStrategy::afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
Junxiao Shi15e98b02016-08-12 11:21:44 +000064 const shared_ptr<pit::Entry>& pitEntry)
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070065{
Junxiao Shi8d843142016-07-11 22:42:42 +000066 const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
67 const fib::NextHopList& nexthops = fibEntry.getNextHops();
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070068 if (nexthops.size() == 0) {
69 this->rejectPendingInterest(pitEntry);
70 return;
71 }
72
Junxiao Shifc021862016-08-25 21:51:18 +000073 PitEntryInfo* pitEntryInfo = pitEntry->insertStrategyInfo<PitEntryInfo>().first;
Junxiao Shifef73e42016-03-29 14:15:05 -070074 bool isNewPitEntry = !hasPendingOutRecords(*pitEntry);
Junxiao Shi8bfd56d2014-10-08 10:06:00 -070075 if (!isNewPitEntry) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070076 return;
77 }
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070078
Junxiao Shi80f9fcd2016-07-23 02:48:36 +000079 MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(pitEntry);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070080
Junxiao Shi1391d612014-03-27 22:27:20 -070081 time::microseconds deferFirst = DEFER_FIRST_WITHOUT_BEST_FACE;
82 time::microseconds deferRange = DEFER_RANGE_WITHOUT_BEST_FACE;
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070083 size_t nUpstreams = nexthops.size();
84
Junxiao Shi80f9fcd2016-07-23 02:48:36 +000085 shared_ptr<Face> bestFace = meInfo.getBestFace();
ashiqopu3ad49db2018-10-20 22:38:47 +000086 if (bestFace != nullptr && fibEntry.hasNextHop(*bestFace, 0) &&
ashiqopuc7079482019-02-20 05:34:37 +000087 !wouldViolateScope(ingress.face, interest, *bestFace) &&
Junxiao Shifef73e42016-03-29 14:15:05 -070088 canForwardToLegacy(*pitEntry, *bestFace)) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070089 // TODO Should we use `randlow = 100 + nrand48(h->seed) % 4096U;` ?
Junxiao Shi80f9fcd2016-07-23 02:48:36 +000090 deferFirst = meInfo.prediction;
Junxiao Shi1391d612014-03-27 22:27:20 -070091 deferRange = time::microseconds((deferFirst.count() + 1) / 2);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070092 --nUpstreams;
ashiqopuc7079482019-02-20 05:34:37 +000093 this->sendInterest(pitEntry, FaceEndpoint(*bestFace, 0), interest);
Davide Pesavento3dade002019-03-19 11:29:56 -060094 pitEntryInfo->bestFaceTimeout = getScheduler().schedule(meInfo.prediction,
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070095 bind(&NccStrategy::timeoutOnBestFace, this, weak_ptr<pit::Entry>(pitEntry)));
96 }
97 else {
Junxiao Shi63162202015-01-14 22:27:33 -070098 // use first eligible nexthop
99 auto firstEligibleNexthop = std::find_if(nexthops.begin(), nexthops.end(),
Junxiao Shie21b3f32016-11-24 14:13:46 +0000100 [&] (const fib::NextHop& nexthop) {
101 Face& outFace = nexthop.getFace();
ashiqopuc7079482019-02-20 05:34:37 +0000102 return !wouldViolateScope(ingress.face, interest, outFace) &&
Junxiao Shie21b3f32016-11-24 14:13:46 +0000103 canForwardToLegacy(*pitEntry, outFace);
Junxiao Shi63162202015-01-14 22:27:33 -0700104 });
105 if (firstEligibleNexthop != nexthops.end()) {
ashiqopuc7079482019-02-20 05:34:37 +0000106 this->sendInterest(pitEntry, FaceEndpoint(firstEligibleNexthop->getFace(), 0), interest);
Junxiao Shie21b3f32016-11-24 14:13:46 +0000107 }
108 else {
109 this->rejectPendingInterest(pitEntry);
110 return;
Junxiao Shi63162202015-01-14 22:27:33 -0700111 }
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700112 }
113
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000114 shared_ptr<Face> previousFace = meInfo.previousFace.lock();
ashiqopu3ad49db2018-10-20 22:38:47 +0000115 if (previousFace != nullptr && fibEntry.hasNextHop(*previousFace, 0) &&
ashiqopuc7079482019-02-20 05:34:37 +0000116 !wouldViolateScope(ingress.face, interest, *previousFace) &&
Junxiao Shifef73e42016-03-29 14:15:05 -0700117 canForwardToLegacy(*pitEntry, *previousFace)) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700118 --nUpstreams;
119 }
120
Junxiao Shi1391d612014-03-27 22:27:20 -0700121 if (nUpstreams > 0) {
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400122 pitEntryInfo->maxInterval = std::max(1_us,
Junxiao Shi1391d612014-03-27 22:27:20 -0700123 time::microseconds((2 * deferRange.count() + nUpstreams - 1) / nUpstreams));
124 }
Junxiao Shicbb490a2014-08-13 12:24:24 -0700125 else {
126 // Normally, maxInterval is unused if there aren't any face beyond best and previousBest.
127 // However, in case FIB entry gains a new nexthop before doPropagate executes (bug 1853),
128 // this maxInterval would be used to determine when the next doPropagate would happen.
129 pitEntryInfo->maxInterval = deferFirst;
130 }
Davide Pesavento3dade002019-03-19 11:29:56 -0600131 pitEntryInfo->propagateTimer = getScheduler().schedule(deferFirst,
ashiqopuc7079482019-02-20 05:34:37 +0000132 bind(&NccStrategy::doPropagate, this, ingress.face.getId(), weak_ptr<pit::Entry>(pitEntry)));
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700133}
134
135void
Junxiao Shie21b3f32016-11-24 14:13:46 +0000136NccStrategy::doPropagate(FaceId inFaceId, weak_ptr<pit::Entry> pitEntryWeak)
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700137{
Junxiao Shie21b3f32016-11-24 14:13:46 +0000138 Face* inFace = this->getFace(inFaceId);
139 if (inFace == nullptr) {
140 return;
141 }
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700142 shared_ptr<pit::Entry> pitEntry = pitEntryWeak.lock();
Junxiao Shi8d843142016-07-11 22:42:42 +0000143 if (pitEntry == nullptr) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700144 return;
145 }
ashiqopud3ae85d2019-02-17 02:29:55 +0000146 auto inRecord = pitEntry->getInRecord(*inFace, 0);
Junxiao Shie21b3f32016-11-24 14:13:46 +0000147 if (inRecord == pitEntry->in_end()) {
148 return;
149 }
150 const Interest& interest = inRecord->getInterest();
Junxiao Shi8d843142016-07-11 22:42:42 +0000151 const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700152
Junxiao Shifc021862016-08-25 21:51:18 +0000153 PitEntryInfo* pitEntryInfo = pitEntry->getStrategyInfo<PitEntryInfo>();
Junxiao Shi1391d612014-03-27 22:27:20 -0700154 // pitEntryInfo is guaranteed to exist here, because doPropagate is triggered
155 // from a timer set by NccStrategy.
Junxiao Shi8d843142016-07-11 22:42:42 +0000156 BOOST_ASSERT(pitEntryInfo != nullptr);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700157
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000158 MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(pitEntry);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700159
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000160 shared_ptr<Face> previousFace = meInfo.previousFace.lock();
ashiqopu3ad49db2018-10-20 22:38:47 +0000161 if (previousFace != nullptr && fibEntry.hasNextHop(*previousFace, 0) &&
Junxiao Shie21b3f32016-11-24 14:13:46 +0000162 !wouldViolateScope(*inFace, interest, *previousFace) &&
Junxiao Shifef73e42016-03-29 14:15:05 -0700163 canForwardToLegacy(*pitEntry, *previousFace)) {
ashiqopuc7079482019-02-20 05:34:37 +0000164 this->sendInterest(pitEntry, FaceEndpoint(*previousFace, 0), interest);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700165 }
166
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700167 bool isForwarded = false;
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400168 for (const auto& nexthop : fibEntry.getNextHops()) {
169 Face& face = nexthop.getFace();
Junxiao Shie21b3f32016-11-24 14:13:46 +0000170 if (!wouldViolateScope(*inFace, interest, face) &&
171 canForwardToLegacy(*pitEntry, face)) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700172 isForwarded = true;
ashiqopuc7079482019-02-20 05:34:37 +0000173 this->sendInterest(pitEntry, FaceEndpoint(face, 0), interest);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700174 break;
175 }
176 }
177
178 if (isForwarded) {
Davide Pesavento5f47aa62016-10-07 22:09:09 +0200179 std::uniform_int_distribution<time::nanoseconds::rep> dist(0, pitEntryInfo->maxInterval.count() - 1);
Davide Pesaventob8bd5ee2019-02-03 22:53:40 -0500180 time::nanoseconds deferNext(dist(ndn::random::getRandomNumberEngine()));
Davide Pesavento3dade002019-03-19 11:29:56 -0600181 pitEntryInfo->propagateTimer = getScheduler().schedule(deferNext,
Junxiao Shie21b3f32016-11-24 14:13:46 +0000182 bind(&NccStrategy::doPropagate, this, inFaceId, weak_ptr<pit::Entry>(pitEntry)));
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700183 }
184}
185
186void
187NccStrategy::timeoutOnBestFace(weak_ptr<pit::Entry> pitEntryWeak)
188{
189 shared_ptr<pit::Entry> pitEntry = pitEntryWeak.lock();
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000190 if (pitEntry == nullptr) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700191 return;
192 }
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000193 measurements::Entry* measurementsEntry = this->getMeasurements().get(*pitEntry);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700194
195 for (int i = 0; i < UPDATE_MEASUREMENTS_N_LEVELS; ++i) {
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000196 if (measurementsEntry == nullptr) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700197 // going out of this strategy's namespace
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000198 break;
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700199 }
Junxiao Shie368d992014-12-02 23:44:31 -0700200 this->getMeasurements().extendLifetime(*measurementsEntry, MEASUREMENTS_LIFETIME);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700201
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000202 MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(measurementsEntry);
203 meInfo.adjustPredictUp();
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700204
Junxiao Shie368d992014-12-02 23:44:31 -0700205 measurementsEntry = this->getMeasurements().getParent(*measurementsEntry);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700206 }
207}
208
209void
Junxiao Shi15e98b02016-08-12 11:21:44 +0000210NccStrategy::beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
ashiqopuc7079482019-02-20 05:34:37 +0000211 const FaceEndpoint& ingress, const Data& data)
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700212{
Junxiao Shi4846f372016-04-05 13:39:30 -0700213 if (!pitEntry->hasInRecords()) {
Junxiao Shi82e7f582014-09-07 15:15:40 -0700214 // PIT entry has already been satisfied (and is now waiting for straggler timer to expire)
215 // NCC does not collect measurements for non-best face
216 return;
217 }
218
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000219 measurements::Entry* measurementsEntry = this->getMeasurements().get(*pitEntry);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700220
221 for (int i = 0; i < UPDATE_MEASUREMENTS_N_LEVELS; ++i) {
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000222 if (measurementsEntry == nullptr) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700223 // going out of this strategy's namespace
224 return;
225 }
Junxiao Shie368d992014-12-02 23:44:31 -0700226 this->getMeasurements().extendLifetime(*measurementsEntry, MEASUREMENTS_LIFETIME);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700227
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000228 MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(measurementsEntry);
ashiqopuc7079482019-02-20 05:34:37 +0000229 meInfo.updateBestFace(ingress.face);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700230
Junxiao Shie368d992014-12-02 23:44:31 -0700231 measurementsEntry = this->getMeasurements().getParent(*measurementsEntry);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700232 }
233
Junxiao Shifc021862016-08-25 21:51:18 +0000234 PitEntryInfo* pitEntryInfo = pitEntry->getStrategyInfo<PitEntryInfo>();
Hila Ben Abraham39a79be2016-03-30 22:00:55 -0700235 if (pitEntryInfo != nullptr) {
Davide Pesavento3dade002019-03-19 11:29:56 -0600236 pitEntryInfo->propagateTimer.cancel();
Hila Ben Abraham39a79be2016-03-30 22:00:55 -0700237
238 // Verify that the best face satisfied the interest before canceling the timeout call
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000239 MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(pitEntry);
240 shared_ptr<Face> bestFace = meInfo.getBestFace();
Hila Ben Abraham39a79be2016-03-30 22:00:55 -0700241
ashiqopuc7079482019-02-20 05:34:37 +0000242 if (bestFace.get() == &ingress.face)
Davide Pesavento3dade002019-03-19 11:29:56 -0600243 pitEntryInfo->bestFaceTimeout.cancel();
Junxiao Shi1391d612014-03-27 22:27:20 -0700244 }
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700245}
246
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000247NccStrategy::MeasurementsEntryInfo&
Junxiao Shi15e98b02016-08-12 11:21:44 +0000248NccStrategy::getMeasurementsEntryInfo(const shared_ptr<pit::Entry>& entry)
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700249{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000250 measurements::Entry* measurementsEntry = this->getMeasurements().get(*entry);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700251 return this->getMeasurementsEntryInfo(measurementsEntry);
252}
253
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000254NccStrategy::MeasurementsEntryInfo&
255NccStrategy::getMeasurementsEntryInfo(measurements::Entry* entry)
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700256{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000257 BOOST_ASSERT(entry != nullptr);
Junxiao Shifc021862016-08-25 21:51:18 +0000258 MeasurementsEntryInfo* info = nullptr;
259 bool isNew = false;
260 std::tie(info, isNew) = entry->insertStrategyInfo<MeasurementsEntryInfo>();
261 if (!isNew) {
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000262 return *info;
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700263 }
264
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000265 measurements::Entry* parentEntry = this->getMeasurements().getParent(*entry);
266 if (parentEntry != nullptr) {
267 MeasurementsEntryInfo& parentInfo = this->getMeasurementsEntryInfo(parentEntry);
268 info->inheritFrom(parentInfo);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700269 }
270
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000271 return *info;
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700272}
273
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400274const time::microseconds NccStrategy::MeasurementsEntryInfo::INITIAL_PREDICTION = 8192_us;
275const time::microseconds NccStrategy::MeasurementsEntryInfo::MIN_PREDICTION = 127_us;
276const time::microseconds NccStrategy::MeasurementsEntryInfo::MAX_PREDICTION = 160_ms;
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700277
278NccStrategy::MeasurementsEntryInfo::MeasurementsEntryInfo()
Junxiao Shi1391d612014-03-27 22:27:20 -0700279 : prediction(INITIAL_PREDICTION)
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700280{
281}
282
283void
284NccStrategy::MeasurementsEntryInfo::inheritFrom(const MeasurementsEntryInfo& other)
285{
286 this->operator=(other);
287}
288
289shared_ptr<Face>
Davide Pesavento5f47aa62016-10-07 22:09:09 +0200290NccStrategy::MeasurementsEntryInfo::getBestFace()
291{
Junxiao Shi1391d612014-03-27 22:27:20 -0700292 shared_ptr<Face> best = this->bestFace.lock();
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000293 if (best != nullptr) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700294 return best;
295 }
Junxiao Shi1391d612014-03-27 22:27:20 -0700296 this->bestFace = best = this->previousFace.lock();
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700297 return best;
298}
299
300void
Davide Pesavento5f47aa62016-10-07 22:09:09 +0200301NccStrategy::MeasurementsEntryInfo::updateBestFace(const Face& face)
302{
Junxiao Shi1391d612014-03-27 22:27:20 -0700303 if (this->bestFace.expired()) {
304 this->bestFace = const_cast<Face&>(face).shared_from_this();
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700305 return;
306 }
Junxiao Shi1391d612014-03-27 22:27:20 -0700307 shared_ptr<Face> bestFace = this->bestFace.lock();
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700308 if (bestFace.get() == &face) {
309 this->adjustPredictDown();
310 }
311 else {
Junxiao Shi1391d612014-03-27 22:27:20 -0700312 this->previousFace = this->bestFace;
313 this->bestFace = const_cast<Face&>(face).shared_from_this();
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700314 }
315}
316
317void
Davide Pesavento5f47aa62016-10-07 22:09:09 +0200318NccStrategy::MeasurementsEntryInfo::adjustPredictDown()
319{
Junxiao Shi1391d612014-03-27 22:27:20 -0700320 prediction = std::max(MIN_PREDICTION,
321 time::microseconds(prediction.count() - (prediction.count() >> ADJUST_PREDICT_DOWN_SHIFT)));
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700322}
323
324void
Davide Pesavento5f47aa62016-10-07 22:09:09 +0200325NccStrategy::MeasurementsEntryInfo::adjustPredictUp()
326{
Junxiao Shi1391d612014-03-27 22:27:20 -0700327 prediction = std::min(MAX_PREDICTION,
328 time::microseconds(prediction.count() + (prediction.count() >> ADJUST_PREDICT_UP_SHIFT)));
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700329}
330
331void
Davide Pesavento5f47aa62016-10-07 22:09:09 +0200332NccStrategy::MeasurementsEntryInfo::ageBestFace()
333{
Junxiao Shi1391d612014-03-27 22:27:20 -0700334 this->previousFace = this->bestFace;
335 this->bestFace.reset();
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700336}
337
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700338NccStrategy::PitEntryInfo::~PitEntryInfo()
339{
Davide Pesavento3dade002019-03-19 11:29:56 -0600340 bestFaceTimeout.cancel();
341 propagateTimer.cancel();
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700342}
343
344} // namespace fw
345} // namespace nfd