blob: 0f7f4e15df6d7e51c6cf0cd3168428e9a583b7b4 [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/*
Davide Pesaventoe4b22382018-06-10 14:37:24 -04003 * Copyright (c) 2014-2018, 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"
Junxiao Shiaf6569a2014-06-14 00:01:34 -070028#include "core/random.hpp"
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070029
30namespace nfd {
31namespace fw {
32
Junxiao Shifaf3eb02015-02-16 10:50:36 -070033NFD_REGISTER_STRATEGY(NccStrategy);
Junxiao Shif3c07812014-03-11 21:48:49 -070034
Davide Pesaventoe4b22382018-06-10 14:37:24 -040035const time::microseconds NccStrategy::DEFER_FIRST_WITHOUT_BEST_FACE = 4_ms;
36const time::microseconds NccStrategy::DEFER_RANGE_WITHOUT_BEST_FACE = 75_ms;
37const time::nanoseconds NccStrategy::MEASUREMENTS_LIFETIME = 16_s;
Junxiao Shi037f4ab2016-12-13 04:27:06 +000038
Junxiao Shif3c07812014-03-11 21:48:49 -070039NccStrategy::NccStrategy(Forwarder& forwarder, const Name& name)
Junxiao Shi18739c42016-12-22 08:03:00 +000040 : Strategy(forwarder)
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070041{
Junxiao Shi18739c42016-12-22 08:03:00 +000042 ParsedInstanceName parsed = parseInstanceName(name);
43 if (!parsed.parameters.empty()) {
44 BOOST_THROW_EXCEPTION(std::invalid_argument("NccStrategy does not accept parameters"));
45 }
Junxiao Shi91f6ee02016-12-29 21:44:44 +000046 if (parsed.version && *parsed.version != getStrategyName()[-1].toVersion()) {
47 BOOST_THROW_EXCEPTION(std::invalid_argument(
Alexander Afanasyev0c63c632017-12-05 11:17:09 -050048 "NccStrategy does not support version " + to_string(*parsed.version)));
Junxiao Shi91f6ee02016-12-29 21:44:44 +000049 }
Junxiao Shi18739c42016-12-22 08:03:00 +000050 this->setInstanceName(makeInstanceName(name, getStrategyName()));
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070051}
52
Junxiao Shi037f4ab2016-12-13 04:27:06 +000053const Name&
54NccStrategy::getStrategyName()
55{
56 static Name strategyName("/localhost/nfd/strategy/ncc/%FD%01");
57 return strategyName;
58}
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070059
60void
Junxiao Shi15e98b02016-08-12 11:21:44 +000061NccStrategy::afterReceiveInterest(const Face& inFace, const Interest& interest,
62 const shared_ptr<pit::Entry>& pitEntry)
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070063{
Junxiao Shi8d843142016-07-11 22:42:42 +000064 const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
65 const fib::NextHopList& nexthops = fibEntry.getNextHops();
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070066 if (nexthops.size() == 0) {
67 this->rejectPendingInterest(pitEntry);
68 return;
69 }
70
Junxiao Shifc021862016-08-25 21:51:18 +000071 PitEntryInfo* pitEntryInfo = pitEntry->insertStrategyInfo<PitEntryInfo>().first;
Junxiao Shifef73e42016-03-29 14:15:05 -070072 bool isNewPitEntry = !hasPendingOutRecords(*pitEntry);
Junxiao Shi8bfd56d2014-10-08 10:06:00 -070073 if (!isNewPitEntry) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070074 return;
75 }
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070076
Junxiao Shi80f9fcd2016-07-23 02:48:36 +000077 MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(pitEntry);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070078
Junxiao Shi1391d612014-03-27 22:27:20 -070079 time::microseconds deferFirst = DEFER_FIRST_WITHOUT_BEST_FACE;
80 time::microseconds deferRange = DEFER_RANGE_WITHOUT_BEST_FACE;
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070081 size_t nUpstreams = nexthops.size();
82
Junxiao Shi80f9fcd2016-07-23 02:48:36 +000083 shared_ptr<Face> bestFace = meInfo.getBestFace();
Junxiao Shia6de4292016-07-12 02:08:10 +000084 if (bestFace != nullptr && fibEntry.hasNextHop(*bestFace) &&
Junxiao Shie21b3f32016-11-24 14:13:46 +000085 !wouldViolateScope(inFace, interest, *bestFace) &&
Junxiao Shifef73e42016-03-29 14:15:05 -070086 canForwardToLegacy(*pitEntry, *bestFace)) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070087 // TODO Should we use `randlow = 100 + nrand48(h->seed) % 4096U;` ?
Junxiao Shi80f9fcd2016-07-23 02:48:36 +000088 deferFirst = meInfo.prediction;
Junxiao Shi1391d612014-03-27 22:27:20 -070089 deferRange = time::microseconds((deferFirst.count() + 1) / 2);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070090 --nUpstreams;
Junxiao Shie21b3f32016-11-24 14:13:46 +000091 this->sendInterest(pitEntry, *bestFace, interest);
Junxiao Shi1391d612014-03-27 22:27:20 -070092 pitEntryInfo->bestFaceTimeout = scheduler::schedule(
Junxiao Shi80f9fcd2016-07-23 02:48:36 +000093 meInfo.prediction,
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -070094 bind(&NccStrategy::timeoutOnBestFace, this, weak_ptr<pit::Entry>(pitEntry)));
95 }
96 else {
Junxiao Shi63162202015-01-14 22:27:33 -070097 // use first eligible nexthop
98 auto firstEligibleNexthop = std::find_if(nexthops.begin(), nexthops.end(),
Junxiao Shie21b3f32016-11-24 14:13:46 +000099 [&] (const fib::NextHop& nexthop) {
100 Face& outFace = nexthop.getFace();
101 return !wouldViolateScope(inFace, interest, outFace) &&
102 canForwardToLegacy(*pitEntry, outFace);
Junxiao Shi63162202015-01-14 22:27:33 -0700103 });
104 if (firstEligibleNexthop != nexthops.end()) {
Junxiao Shie21b3f32016-11-24 14:13:46 +0000105 this->sendInterest(pitEntry, firstEligibleNexthop->getFace(), interest);
106 }
107 else {
108 this->rejectPendingInterest(pitEntry);
109 return;
Junxiao Shi63162202015-01-14 22:27:33 -0700110 }
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700111 }
112
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000113 shared_ptr<Face> previousFace = meInfo.previousFace.lock();
Junxiao Shia6de4292016-07-12 02:08:10 +0000114 if (previousFace != nullptr && fibEntry.hasNextHop(*previousFace) &&
Junxiao Shie21b3f32016-11-24 14:13:46 +0000115 !wouldViolateScope(inFace, interest, *previousFace) &&
Junxiao Shifef73e42016-03-29 14:15:05 -0700116 canForwardToLegacy(*pitEntry, *previousFace)) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700117 --nUpstreams;
118 }
119
Junxiao Shi1391d612014-03-27 22:27:20 -0700120 if (nUpstreams > 0) {
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400121 pitEntryInfo->maxInterval = std::max(1_us,
Junxiao Shi1391d612014-03-27 22:27:20 -0700122 time::microseconds((2 * deferRange.count() + nUpstreams - 1) / nUpstreams));
123 }
Junxiao Shicbb490a2014-08-13 12:24:24 -0700124 else {
125 // Normally, maxInterval is unused if there aren't any face beyond best and previousBest.
126 // However, in case FIB entry gains a new nexthop before doPropagate executes (bug 1853),
127 // this maxInterval would be used to determine when the next doPropagate would happen.
128 pitEntryInfo->maxInterval = deferFirst;
129 }
Junxiao Shi1391d612014-03-27 22:27:20 -0700130 pitEntryInfo->propagateTimer = scheduler::schedule(deferFirst,
Junxiao Shie21b3f32016-11-24 14:13:46 +0000131 bind(&NccStrategy::doPropagate, this, inFace.getId(), weak_ptr<pit::Entry>(pitEntry)));
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700132}
133
134void
Junxiao Shie21b3f32016-11-24 14:13:46 +0000135NccStrategy::doPropagate(FaceId inFaceId, weak_ptr<pit::Entry> pitEntryWeak)
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700136{
Junxiao Shie21b3f32016-11-24 14:13:46 +0000137 Face* inFace = this->getFace(inFaceId);
138 if (inFace == nullptr) {
139 return;
140 }
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700141 shared_ptr<pit::Entry> pitEntry = pitEntryWeak.lock();
Junxiao Shi8d843142016-07-11 22:42:42 +0000142 if (pitEntry == nullptr) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700143 return;
144 }
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400145 auto inRecord = pitEntry->getInRecord(*inFace);
Junxiao Shie21b3f32016-11-24 14:13:46 +0000146 if (inRecord == pitEntry->in_end()) {
147 return;
148 }
149 const Interest& interest = inRecord->getInterest();
Junxiao Shi8d843142016-07-11 22:42:42 +0000150 const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700151
Junxiao Shifc021862016-08-25 21:51:18 +0000152 PitEntryInfo* pitEntryInfo = pitEntry->getStrategyInfo<PitEntryInfo>();
Junxiao Shi1391d612014-03-27 22:27:20 -0700153 // pitEntryInfo is guaranteed to exist here, because doPropagate is triggered
154 // from a timer set by NccStrategy.
Junxiao Shi8d843142016-07-11 22:42:42 +0000155 BOOST_ASSERT(pitEntryInfo != nullptr);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700156
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000157 MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(pitEntry);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700158
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000159 shared_ptr<Face> previousFace = meInfo.previousFace.lock();
Junxiao Shia6de4292016-07-12 02:08:10 +0000160 if (previousFace != nullptr && fibEntry.hasNextHop(*previousFace) &&
Junxiao Shie21b3f32016-11-24 14:13:46 +0000161 !wouldViolateScope(*inFace, interest, *previousFace) &&
Junxiao Shifef73e42016-03-29 14:15:05 -0700162 canForwardToLegacy(*pitEntry, *previousFace)) {
Junxiao Shie21b3f32016-11-24 14:13:46 +0000163 this->sendInterest(pitEntry, *previousFace, interest);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700164 }
165
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700166 bool isForwarded = false;
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400167 for (const auto& nexthop : fibEntry.getNextHops()) {
168 Face& face = nexthop.getFace();
Junxiao Shie21b3f32016-11-24 14:13:46 +0000169 if (!wouldViolateScope(*inFace, interest, face) &&
170 canForwardToLegacy(*pitEntry, face)) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700171 isForwarded = true;
Junxiao Shie21b3f32016-11-24 14:13:46 +0000172 this->sendInterest(pitEntry, face, interest);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700173 break;
174 }
175 }
176
177 if (isForwarded) {
Davide Pesavento5f47aa62016-10-07 22:09:09 +0200178 std::uniform_int_distribution<time::nanoseconds::rep> dist(0, pitEntryInfo->maxInterval.count() - 1);
Junxiao Shiaf6569a2014-06-14 00:01:34 -0700179 time::nanoseconds deferNext = time::nanoseconds(dist(getGlobalRng()));
Junxiao Shi1391d612014-03-27 22:27:20 -0700180 pitEntryInfo->propagateTimer = scheduler::schedule(deferNext,
Junxiao Shie21b3f32016-11-24 14:13:46 +0000181 bind(&NccStrategy::doPropagate, this, inFaceId, weak_ptr<pit::Entry>(pitEntry)));
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700182 }
183}
184
185void
186NccStrategy::timeoutOnBestFace(weak_ptr<pit::Entry> pitEntryWeak)
187{
188 shared_ptr<pit::Entry> pitEntry = pitEntryWeak.lock();
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000189 if (pitEntry == nullptr) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700190 return;
191 }
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000192 measurements::Entry* measurementsEntry = this->getMeasurements().get(*pitEntry);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700193
194 for (int i = 0; i < UPDATE_MEASUREMENTS_N_LEVELS; ++i) {
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000195 if (measurementsEntry == nullptr) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700196 // going out of this strategy's namespace
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000197 break;
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700198 }
Junxiao Shie368d992014-12-02 23:44:31 -0700199 this->getMeasurements().extendLifetime(*measurementsEntry, MEASUREMENTS_LIFETIME);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700200
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000201 MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(measurementsEntry);
202 meInfo.adjustPredictUp();
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700203
Junxiao Shie368d992014-12-02 23:44:31 -0700204 measurementsEntry = this->getMeasurements().getParent(*measurementsEntry);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700205 }
206}
207
208void
Junxiao Shi15e98b02016-08-12 11:21:44 +0000209NccStrategy::beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
Junxiao Shi82e7f582014-09-07 15:15:40 -0700210 const Face& inFace, const Data& data)
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700211{
Junxiao Shi4846f372016-04-05 13:39:30 -0700212 if (!pitEntry->hasInRecords()) {
Junxiao Shi82e7f582014-09-07 15:15:40 -0700213 // PIT entry has already been satisfied (and is now waiting for straggler timer to expire)
214 // NCC does not collect measurements for non-best face
215 return;
216 }
217
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000218 measurements::Entry* measurementsEntry = this->getMeasurements().get(*pitEntry);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700219
220 for (int i = 0; i < UPDATE_MEASUREMENTS_N_LEVELS; ++i) {
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000221 if (measurementsEntry == nullptr) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700222 // going out of this strategy's namespace
223 return;
224 }
Junxiao Shie368d992014-12-02 23:44:31 -0700225 this->getMeasurements().extendLifetime(*measurementsEntry, MEASUREMENTS_LIFETIME);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700226
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000227 MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(measurementsEntry);
228 meInfo.updateBestFace(inFace);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700229
Junxiao Shie368d992014-12-02 23:44:31 -0700230 measurementsEntry = this->getMeasurements().getParent(*measurementsEntry);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700231 }
232
Junxiao Shifc021862016-08-25 21:51:18 +0000233 PitEntryInfo* pitEntryInfo = pitEntry->getStrategyInfo<PitEntryInfo>();
Hila Ben Abraham39a79be2016-03-30 22:00:55 -0700234 if (pitEntryInfo != nullptr) {
Junxiao Shi1391d612014-03-27 22:27:20 -0700235 scheduler::cancel(pitEntryInfo->propagateTimer);
Hila Ben Abraham39a79be2016-03-30 22:00:55 -0700236
237 // Verify that the best face satisfied the interest before canceling the timeout call
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000238 MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(pitEntry);
239 shared_ptr<Face> bestFace = meInfo.getBestFace();
Hila Ben Abraham39a79be2016-03-30 22:00:55 -0700240
241 if (bestFace.get() == &inFace)
242 scheduler::cancel(pitEntryInfo->bestFaceTimeout);
Junxiao Shi1391d612014-03-27 22:27:20 -0700243 }
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700244}
245
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000246NccStrategy::MeasurementsEntryInfo&
Junxiao Shi15e98b02016-08-12 11:21:44 +0000247NccStrategy::getMeasurementsEntryInfo(const shared_ptr<pit::Entry>& entry)
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700248{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000249 measurements::Entry* measurementsEntry = this->getMeasurements().get(*entry);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700250 return this->getMeasurementsEntryInfo(measurementsEntry);
251}
252
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000253NccStrategy::MeasurementsEntryInfo&
254NccStrategy::getMeasurementsEntryInfo(measurements::Entry* entry)
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700255{
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000256 BOOST_ASSERT(entry != nullptr);
Junxiao Shifc021862016-08-25 21:51:18 +0000257 MeasurementsEntryInfo* info = nullptr;
258 bool isNew = false;
259 std::tie(info, isNew) = entry->insertStrategyInfo<MeasurementsEntryInfo>();
260 if (!isNew) {
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000261 return *info;
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700262 }
263
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000264 measurements::Entry* parentEntry = this->getMeasurements().getParent(*entry);
265 if (parentEntry != nullptr) {
266 MeasurementsEntryInfo& parentInfo = this->getMeasurementsEntryInfo(parentEntry);
267 info->inheritFrom(parentInfo);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700268 }
269
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000270 return *info;
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700271}
272
Davide Pesaventoe4b22382018-06-10 14:37:24 -0400273const time::microseconds NccStrategy::MeasurementsEntryInfo::INITIAL_PREDICTION = 8192_us;
274const time::microseconds NccStrategy::MeasurementsEntryInfo::MIN_PREDICTION = 127_us;
275const time::microseconds NccStrategy::MeasurementsEntryInfo::MAX_PREDICTION = 160_ms;
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700276
277NccStrategy::MeasurementsEntryInfo::MeasurementsEntryInfo()
Junxiao Shi1391d612014-03-27 22:27:20 -0700278 : prediction(INITIAL_PREDICTION)
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700279{
280}
281
282void
283NccStrategy::MeasurementsEntryInfo::inheritFrom(const MeasurementsEntryInfo& other)
284{
285 this->operator=(other);
286}
287
288shared_ptr<Face>
Davide Pesavento5f47aa62016-10-07 22:09:09 +0200289NccStrategy::MeasurementsEntryInfo::getBestFace()
290{
Junxiao Shi1391d612014-03-27 22:27:20 -0700291 shared_ptr<Face> best = this->bestFace.lock();
Junxiao Shi80f9fcd2016-07-23 02:48:36 +0000292 if (best != nullptr) {
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700293 return best;
294 }
Junxiao Shi1391d612014-03-27 22:27:20 -0700295 this->bestFace = best = this->previousFace.lock();
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700296 return best;
297}
298
299void
Davide Pesavento5f47aa62016-10-07 22:09:09 +0200300NccStrategy::MeasurementsEntryInfo::updateBestFace(const Face& face)
301{
Junxiao Shi1391d612014-03-27 22:27:20 -0700302 if (this->bestFace.expired()) {
303 this->bestFace = const_cast<Face&>(face).shared_from_this();
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700304 return;
305 }
Junxiao Shi1391d612014-03-27 22:27:20 -0700306 shared_ptr<Face> bestFace = this->bestFace.lock();
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700307 if (bestFace.get() == &face) {
308 this->adjustPredictDown();
309 }
310 else {
Junxiao Shi1391d612014-03-27 22:27:20 -0700311 this->previousFace = this->bestFace;
312 this->bestFace = const_cast<Face&>(face).shared_from_this();
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700313 }
314}
315
316void
Davide Pesavento5f47aa62016-10-07 22:09:09 +0200317NccStrategy::MeasurementsEntryInfo::adjustPredictDown()
318{
Junxiao Shi1391d612014-03-27 22:27:20 -0700319 prediction = std::max(MIN_PREDICTION,
320 time::microseconds(prediction.count() - (prediction.count() >> ADJUST_PREDICT_DOWN_SHIFT)));
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700321}
322
323void
Davide Pesavento5f47aa62016-10-07 22:09:09 +0200324NccStrategy::MeasurementsEntryInfo::adjustPredictUp()
325{
Junxiao Shi1391d612014-03-27 22:27:20 -0700326 prediction = std::min(MAX_PREDICTION,
327 time::microseconds(prediction.count() + (prediction.count() >> ADJUST_PREDICT_UP_SHIFT)));
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700328}
329
330void
Davide Pesavento5f47aa62016-10-07 22:09:09 +0200331NccStrategy::MeasurementsEntryInfo::ageBestFace()
332{
Junxiao Shi1391d612014-03-27 22:27:20 -0700333 this->previousFace = this->bestFace;
334 this->bestFace.reset();
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700335}
336
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700337NccStrategy::PitEntryInfo::~PitEntryInfo()
338{
Junxiao Shi1391d612014-03-27 22:27:20 -0700339 scheduler::cancel(this->bestFaceTimeout);
340 scheduler::cancel(this->propagateTimer);
Junxiao Shi0b5fbbb2014-02-20 15:54:03 -0700341}
342
343} // namespace fw
344} // namespace nfd