29 #include <boost/random/uniform_int_distribution.hpp>
48 const shared_ptr<pit::Entry>& pitEntry)
52 if (nexthops.size() == 0) {
67 size_t nUpstreams = nexthops.size();
70 if (bestFace !=
nullptr && fibEntry.
hasNextHop(*bestFace) &&
74 deferRange = time::microseconds((deferFirst.count() + 1) / 2);
83 auto firstEligibleNexthop = std::find_if(nexthops.begin(), nexthops.end(),
87 if (firstEligibleNexthop != nexthops.end()) {
88 this->
sendInterest(pitEntry, firstEligibleNexthop->getFace());
92 shared_ptr<Face> previousFace = meInfo.
previousFace.lock();
93 if (previousFace !=
nullptr && fibEntry.
hasNextHop(*previousFace) &&
99 pitEntryInfo->
maxInterval = std::max(time::microseconds(1),
100 time::microseconds((2 * deferRange.count() + nUpstreams - 1) / nUpstreams));
115 shared_ptr<pit::Entry> pitEntry = pitEntryWeak.lock();
116 if (pitEntry ==
nullptr) {
124 BOOST_ASSERT(pitEntryInfo !=
nullptr);
128 shared_ptr<Face> previousFace = meInfo.
previousFace.lock();
129 if (previousFace !=
nullptr && fibEntry.
hasNextHop(*previousFace) &&
135 bool isForwarded =
false;
136 for (fib::NextHopList::const_iterator it = nexthops.begin(); it != nexthops.end(); ++it) {
137 Face& face = it->getFace();
146 boost::random::uniform_int_distribution<time::nanoseconds::rep> dist(0,
148 time::nanoseconds deferNext = time::nanoseconds(dist(
getGlobalRng()));
157 shared_ptr<pit::Entry> pitEntry = pitEntryWeak.lock();
158 if (pitEntry ==
nullptr) {
164 if (measurementsEntry ==
nullptr) {
173 measurementsEntry = this->
getMeasurements().getParent(*measurementsEntry);
179 const Face& inFace,
const Data& data)
181 if (!pitEntry->hasInRecords()) {
190 if (measurementsEntry ==
nullptr) {
199 measurementsEntry = this->
getMeasurements().getParent(*measurementsEntry);
203 if (pitEntryInfo !=
nullptr) {
210 if (bestFace.get() == &inFace)
225 BOOST_ASSERT(entry !=
nullptr);
234 if (parentEntry !=
nullptr) {
244 time::microseconds(8192);
246 time::microseconds(127);
248 time::microseconds(160000);
251 : prediction(INITIAL_PREDICTION)
258 this->operator=(other);
263 shared_ptr<Face> best = this->bestFace.lock();
264 if (best !=
nullptr) {
267 this->bestFace = best = this->previousFace.lock();
273 if (this->bestFace.expired()) {
274 this->bestFace =
const_cast<Face&
>(face).shared_from_this();
277 shared_ptr<Face> bestFace = this->bestFace.lock();
278 if (bestFace.get() == &face) {
279 this->adjustPredictDown();
282 this->previousFace = this->bestFace;
283 this->bestFace =
const_cast<Face&
>(face).shared_from_this();
288 NccStrategy::MeasurementsEntryInfo::adjustPredictDown() {
289 prediction = std::max(MIN_PREDICTION,
290 time::microseconds(prediction.count() - (prediction.count() >> ADJUST_PREDICT_DOWN_SHIFT)));
295 prediction = std::min(MAX_PREDICTION,
296 time::microseconds(prediction.count() + (prediction.count() >> ADJUST_PREDICT_UP_SHIFT)));
300 NccStrategy::MeasurementsEntryInfo::ageBestFace() {
301 this->previousFace = this->bestFace;
302 this->bestFace.reset();
bool canForwardToLegacy(const pit::Entry &pitEntry, const Face &face)
decide whether Interest can be forwarded to face
#define NFD_REGISTER_STRATEGY(StrategyType)
registers a built-in strategy
NccStrategy(Forwarder &forwarder, const Name &name=STRATEGY_NAME)
bool hasNextHop(const Face &face) const
void timeoutOnBestFace(weak_ptr< pit::Entry > pitEntryWeak)
best face did not reply within prediction
time::microseconds maxInterval
maximum interval between forwarding to two nexthops except best and previous
Copyright (c) 2014-2016, Regents of the University of California, Arizona Board of Regents...
weak_ptr< Face > previousFace
represents a Measurements entry
static const int UPDATE_MEASUREMENTS_N_LEVELS
void cancel(const EventId &eventId)
cancel a scheduled event
time::microseconds prediction
virtual void beforeSatisfyInterest(const shared_ptr< pit::Entry > &pitEntry, const Face &inFace, const Data &data) override
trigger before PIT entry is satisfied
scheduler::EventId bestFaceTimeout
timer that expires when best face does not respond within predicted time
static const time::nanoseconds MEASUREMENTS_LIFETIME
StrategyInfo on pit::Entry.
std::pair< T *, bool > insertStrategyInfo(A &&...args)
insert a StrategyInfo item
MeasurementsAccessor & getMeasurements()
shared_ptr< Face > getBestFace()
static const Name STRATEGY_NAME
MeasurementsEntryInfo & getMeasurementsEntryInfo(measurements::Entry *entry)
scheduler::EventId propagateTimer
timer for propagating to another face
void inheritFrom(const MeasurementsEntryInfo &other)
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
static const time::microseconds DEFER_RANGE_WITHOUT_BEST_FACE
void doPropagate(weak_ptr< pit::Entry > pitEntryWeak)
propagate to another upstream
void updateBestFace(const Face &face)
std::vector< fib::NextHop > NextHopList
static const time::microseconds MIN_PREDICTION
boost::random::mt19937 & getGlobalRng()
bool hasPendingOutRecords(const pit::Entry &pitEntry)
determine whether pitEntry has any pending out-records
represents a forwarding strategy
EventId schedule(const time::nanoseconds &after, const Scheduler::Event &event)
schedule an event
static const time::microseconds INITIAL_PREDICTION
StrategyInfo on measurements::Entry.
static const time::microseconds DEFER_FIRST_WITHOUT_BEST_FACE
virtual ~PitEntryInfo() override
void sendInterest(const shared_ptr< pit::Entry > &pitEntry, Face &outFace, bool wantNewNonce=false)
send Interest to outFace
represents a nexthop record in FIB entry
static const time::microseconds MAX_PREDICTION
const NextHopList & getNextHops() const
void rejectPendingInterest(const shared_ptr< pit::Entry > &pitEntry)
decide that a pending Interest cannot be forwarded
const fib::Entry & lookupFib(const pit::Entry &pitEntry) const
performs a FIB lookup, considering Link object if present
virtual void afterReceiveInterest(const Face &inFace, const Interest &interest, const shared_ptr< pit::Entry > &pitEntry) override
trigger after Interest is received