table: simplify pit::Entry API
refs #3546
Change-Id: I6a9cb83b9e56ce1d1bb6047049378c51781605af
diff --git a/daemon/fw/access-strategy.cpp b/daemon/fw/access-strategy.cpp
index 8d53168..862e165 100644
--- a/daemon/fw/access-strategy.cpp
+++ b/daemon/fw/access-strategy.cpp
@@ -195,14 +195,14 @@
pi->rtoTimer.cancel();
}
- if (pitEntry->getInRecords().empty()) { // already satisfied by another upstream
+ if (!pitEntry->hasInRecords()) { // already satisfied by another upstream
NFD_LOG_DEBUG(pitEntry->getInterest() << " dataFrom " << inFace.getId() <<
" not-fastest");
return;
}
- pit::OutRecordCollection::const_iterator outRecord = pitEntry->getOutRecord(inFace);
- if (outRecord == pitEntry->getOutRecords().end()) { // no OutRecord
+ pit::OutRecordCollection::iterator outRecord = pitEntry->getOutRecord(inFace);
+ if (outRecord == pitEntry->out_end()) { // no out-record
NFD_LOG_DEBUG(pitEntry->getInterest() << " dataFrom " << inFace.getId() <<
" no-out-record");
return;
diff --git a/daemon/fw/best-route-strategy2.cpp b/daemon/fw/best-route-strategy2.cpp
index 96791be..0644ba9 100644
--- a/daemon/fw/best-route-strategy2.cpp
+++ b/daemon/fw/best-route-strategy2.cpp
@@ -50,7 +50,7 @@
* \param pitEntry PIT entry
* \param nexthop next hop
* \param currentDownstream incoming FaceId of current Interest
- * \param wantUnused if true, NextHop must not have unexpired OutRecord
+ * \param wantUnused if true, NextHop must not have unexpired out-record
* \param now time::steady_clock::now(), ignored if !wantUnused
*/
static inline bool
@@ -70,10 +70,9 @@
return false;
if (wantUnused) {
- // NextHop must not have unexpired OutRecord
- pit::OutRecordCollection::const_iterator outRecord = pitEntry->getOutRecord(*upstream);
- if (outRecord != pitEntry->getOutRecords().end() &&
- outRecord->getExpiry() > now) {
+ // NextHop must not have unexpired out-record
+ pit::OutRecordCollection::iterator outRecord = pitEntry->getOutRecord(*upstream);
+ if (outRecord != pitEntry->out_end() && outRecord->getExpiry() > now) {
return false;
}
}
@@ -81,8 +80,8 @@
return true;
}
-/** \brief pick an eligible NextHop with earliest OutRecord
- * \note It is assumed that every nexthop has an OutRecord
+/** \brief pick an eligible NextHop with earliest out-record
+ * \note It is assumed that every nexthop has an out-record.
*/
static inline fib::NextHopList::const_iterator
findEligibleNextHopWithEarliestOutRecord(const shared_ptr<pit::Entry>& pitEntry,
@@ -94,8 +93,8 @@
for (fib::NextHopList::const_iterator it = nexthops.begin(); it != nexthops.end(); ++it) {
if (!predicate_NextHop_eligible(pitEntry, *it, currentDownstream))
continue;
- pit::OutRecordCollection::const_iterator outRecord = pitEntry->getOutRecord(*it->getFace());
- BOOST_ASSERT(outRecord != pitEntry->getOutRecords().end());
+ pit::OutRecordCollection::iterator outRecord = pitEntry->getOutRecord(*it->getFace());
+ BOOST_ASSERT(outRecord != pitEntry->out_end());
if (outRecord->getLastRenewed() < earliestRenewed) {
found = it;
earliestRenewed = outRecord->getLastRenewed();
@@ -209,8 +208,8 @@
if (nOutRecordsNotNacked == 1) {
BOOST_ASSERT(lastFaceNotNacked != nullptr);
- pit::InRecordCollection::const_iterator inR = pitEntry->getInRecord(*lastFaceNotNacked);
- if (inR != pitEntry->getInRecords().end()) {
+ pit::InRecordCollection::iterator inR = pitEntry->getInRecord(*lastFaceNotNacked);
+ if (inR != pitEntry->in_end()) {
// one out-record not Nacked, which is also a downstream
NFD_LOG_DEBUG(nack.getInterest() << " nack-from=" << inFace.getId() <<
" nack=" << nack.getReason() <<
diff --git a/daemon/fw/forwarder.cpp b/daemon/fw/forwarder.cpp
index ef792ae..b575e3b 100644
--- a/daemon/fw/forwarder.cpp
+++ b/daemon/fw/forwarder.cpp
@@ -142,9 +142,7 @@
this->cancelUnsatisfyAndStragglerTimer(pitEntry);
// is pending?
- const pit::InRecordCollection& inRecords = pitEntry->getInRecords();
- bool isPending = inRecords.begin() != inRecords.end();
- if (!isPending) {
+ if (!pitEntry->hasInRecords()) {
m_cs.find(interest,
bind(&Forwarder::onContentStoreHit, this, ref(inFace), pitEntry, _1, _2),
bind(&Forwarder::onContentStoreMiss, this, ref(inFace), pitEntry, _1));
@@ -184,7 +182,7 @@
NFD_LOG_DEBUG("onContentStoreMiss interest=" << interest.getName());
shared_ptr<Face> face = const_pointer_cast<Face>(inFace.shared_from_this());
- // insert InRecord
+ // insert in-record
pitEntry->insertOrUpdateInRecord(face, interest);
// set PIT unsatisfy timer
@@ -261,14 +259,14 @@
this->onOutgoingData(data, *const_pointer_cast<Face>(inFace.shared_from_this()));
}
-/** \brief compare two InRecords for picking outgoing Interest
+/** \brief compare two in-records for picking outgoing Interest
* \return true if b is preferred over a
*
* This function should be passed to std::max_element over InRecordCollection.
* The outgoing Interest picked is the last incoming Interest
* that does not come from outFace.
- * If all InRecords come from outFace, it's fine to pick that. This happens when
- * there's only one InRecord that comes from outFace. The legit use is for
+ * If all in-records come from outFace, it's fine to pick that. This happens when
+ * there's only one in-record that comes from outFace. The legit use is for
* vehicular network; otherwise, strategy shouldn't send to the sole inFace.
*/
static inline bool
@@ -306,12 +304,10 @@
}
// pick Interest
- const pit::InRecordCollection& inRecords = pitEntry->getInRecords();
- pit::InRecordCollection::const_iterator pickedInRecord = std::max_element(
- inRecords.begin(), inRecords.end(), bind(&compare_pickInterest, _1, _2, &outFace));
- BOOST_ASSERT(pickedInRecord != inRecords.end());
- shared_ptr<Interest> interest = const_pointer_cast<Interest>(
- pickedInRecord->getInterest().shared_from_this());
+ pit::InRecordCollection::iterator pickedInRecord = std::max_element(
+ pitEntry->in_begin(), pitEntry->in_end(), bind(&compare_pickInterest, _1, _2, &outFace));
+ BOOST_ASSERT(pickedInRecord != pitEntry->in_end());
+ auto interest = const_pointer_cast<Interest>(pickedInRecord->getInterest().shared_from_this());
if (wantNewNonce) {
interest = make_shared<Interest>(*interest);
@@ -319,7 +315,7 @@
interest->setNonce(dist(getGlobalRng()));
}
- // insert OutRecord
+ // insert out-record
pitEntry->insertOrUpdateOutRecord(outFace.shared_from_this(), *interest);
// send Interest
@@ -403,6 +399,7 @@
std::set<Face*> pendingDownstreams;
// foreach PitEntry
+ auto now = time::steady_clock::now();
for (const shared_ptr<pit::Entry>& pitEntry : pitMatches) {
NFD_LOG_DEBUG("onIncomingData matching=" << pitEntry->getName());
@@ -410,9 +407,8 @@
this->cancelUnsatisfyAndStragglerTimer(pitEntry);
// remember pending downstreams
- const pit::InRecordCollection& inRecords = pitEntry->getInRecords();
- for (const pit::InRecord& inRecord : inRecords) {
- if (inRecord.getExpiry() > time::steady_clock::now()) {
+ for (const pit::InRecord& inRecord : pitEntry->getInRecords()) {
+ if (inRecord.getExpiry() > now) {
pendingDownstreams.insert(inRecord.getFace().get());
}
}
@@ -421,11 +417,11 @@
this->dispatchToStrategy(pitEntry, bind(&Strategy::beforeSatisfyInterest, _1,
pitEntry, cref(inFace), cref(data)));
- // Dead Nonce List insert if necessary (for OutRecord of inFace)
+ // Dead Nonce List insert if necessary (for out-record of inFace)
this->insertDeadNonceList(*pitEntry, true, data.getFreshnessPeriod(), &inFace);
// mark PIT satisfied
- pitEntry->deleteInRecords();
+ pitEntry->clearInRecords();
pitEntry->deleteOutRecord(inFace);
// set PIT straggler timer
@@ -511,7 +507,7 @@
// has out-record?
pit::OutRecordCollection::iterator outRecord = pitEntry->getOutRecord(inFace);
// if no out-record found, drop
- if (outRecord == pitEntry->getOutRecords().end()) {
+ if (outRecord == pitEntry->out_end()) {
NFD_LOG_DEBUG("onIncomingNack face=" << inFace.getId() <<
" nack=" << nack.getInterest().getName() <<
"~" << nack.getReason() << " no-out-record");
@@ -552,10 +548,10 @@
}
// has in-record?
- pit::InRecordCollection::const_iterator inRecord = pitEntry->getInRecord(outFace);
+ pit::InRecordCollection::iterator inRecord = pitEntry->getInRecord(outFace);
// if no in-record found, drop
- if (inRecord == pitEntry->getInRecords().end()) {
+ if (inRecord == pitEntry->in_end()) {
NFD_LOG_DEBUG("onOutgoingNack face=" << outFace.getId() <<
" nack=" << pitEntry->getInterest().getName() <<
"~" << nack.getReason() << " no-in-record");
@@ -595,15 +591,13 @@
void
Forwarder::setUnsatisfyTimer(shared_ptr<pit::Entry> pitEntry)
{
- const pit::InRecordCollection& inRecords = pitEntry->getInRecords();
- pit::InRecordCollection::const_iterator lastExpiring =
- std::max_element(inRecords.begin(), inRecords.end(),
- &compare_InRecord_expiry);
+ pit::InRecordCollection::iterator lastExpiring =
+ std::max_element(pitEntry->in_begin(), pitEntry->in_end(), &compare_InRecord_expiry);
time::steady_clock::TimePoint lastExpiry = lastExpiring->getExpiry();
- time::nanoseconds lastExpiryFromNow = lastExpiry - time::steady_clock::now();
- if (lastExpiryFromNow <= time::seconds(0)) {
- // TODO all InRecords are already expired; will this happen?
+ time::nanoseconds lastExpiryFromNow = lastExpiry - time::steady_clock::now();
+ if (lastExpiryFromNow <= time::seconds::zero()) {
+ // TODO all in-records are already expired; will this happen?
}
scheduler::cancel(pitEntry->m_unsatisfyTimer);
@@ -666,7 +660,7 @@
}
else {
// insert outgoing Nonce of a specific face
- pit::OutRecordCollection::const_iterator outRecord = pitEntry.getOutRecord(*upstream);
+ pit::OutRecordCollection::iterator outRecord = pitEntry.getOutRecord(*upstream);
if (outRecord != pitEntry.getOutRecords().end()) {
m_deadNonceList.add(pitEntry.getName(), outRecord->getLastNonce());
}
diff --git a/daemon/fw/forwarder.hpp b/daemon/fw/forwarder.hpp
index 2bac6b0..bb3935c 100644
--- a/daemon/fw/forwarder.hpp
+++ b/daemon/fw/forwarder.hpp
@@ -206,8 +206,8 @@
cancelUnsatisfyAndStragglerTimer(shared_ptr<pit::Entry> pitEntry);
/** \brief insert Nonce to Dead Nonce List if necessary
- * \param upstream if null, insert Nonces from all OutRecords;
- * if not null, insert Nonce only on the OutRecord of this face
+ * \param upstream if null, insert Nonces from all out-records;
+ * if not null, insert Nonce only on the out-records of this face
*/
VIRTUAL_WITH_TESTS void
insertDeadNonceList(pit::Entry& pitEntry, bool isSatisfied,
diff --git a/daemon/fw/ncc-strategy.cpp b/daemon/fw/ncc-strategy.cpp
index ef91c6b..c096fe1 100644
--- a/daemon/fw/ncc-strategy.cpp
+++ b/daemon/fw/ncc-strategy.cpp
@@ -192,7 +192,7 @@
NccStrategy::beforeSatisfyInterest(shared_ptr<pit::Entry> pitEntry,
const Face& inFace, const Data& data)
{
- if (pitEntry->getInRecords().empty()) {
+ if (!pitEntry->hasInRecords()) {
// PIT entry has already been satisfied (and is now waiting for straggler timer to expire)
// NCC does not collect measurements for non-best face
return;
diff --git a/daemon/fw/pit-algorithm.cpp b/daemon/fw/pit-algorithm.cpp
index ac04e2a..ca54dfe 100644
--- a/daemon/fw/pit-algorithm.cpp
+++ b/daemon/fw/pit-algorithm.cpp
@@ -48,7 +48,7 @@
if (scope_prefix::LOCALHOP.isPrefixOf(pitEntry.getName())) {
// face is non-local, violates localhop scope unless PIT entry has local in-record
- return std::none_of(pitEntry.getInRecords().begin(), pitEntry.getInRecords().end(),
+ return std::none_of(pitEntry.in_begin(), pitEntry.in_end(),
[] (const pit::InRecord& inRecord) { return inRecord.getFace()->getScope() == ndn::nfd::FACE_SCOPE_LOCAL; });
}
@@ -61,7 +61,7 @@
{
time::steady_clock::TimePoint now = time::steady_clock::now();
- bool hasUnexpiredOutRecord = std::any_of(pitEntry.getOutRecords().begin(), pitEntry.getOutRecords().end(),
+ bool hasUnexpiredOutRecord = std::any_of(pitEntry.out_begin(), pitEntry.out_end(),
[&face, &now] (const pit::OutRecord& outRecord) {
return outRecord.getFace().get() == &face && outRecord.getExpiry() >= now;
});
@@ -69,7 +69,7 @@
return false;
}
- bool hasUnexpiredOtherInRecord = std::any_of(pitEntry.getInRecords().begin(), pitEntry.getInRecords().end(),
+ bool hasUnexpiredOtherInRecord = std::any_of(pitEntry.in_begin(), pitEntry.in_end(),
[&face, &now] (const pit::InRecord& inRecord) {
return inRecord.getFace().get() != &face && inRecord.getExpiry() >= now;
});
@@ -114,7 +114,7 @@
hasPendingOutRecords(const pit::Entry& pitEntry)
{
time::steady_clock::TimePoint now = time::steady_clock::now();
- return std::any_of(pitEntry.getOutRecords().begin(), pitEntry.getOutRecords().end(),
+ return std::any_of(pitEntry.out_begin(), pitEntry.out_end(),
[&now] (const pit::OutRecord& outRecord) { return outRecord.getExpiry() >= now; });
}
diff --git a/daemon/fw/retx-suppression.cpp b/daemon/fw/retx-suppression.cpp
index a420581..9ae122a 100644
--- a/daemon/fw/retx-suppression.cpp
+++ b/daemon/fw/retx-suppression.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -31,13 +31,12 @@
time::steady_clock::TimePoint
RetxSuppression::getLastOutgoing(const pit::Entry& pitEntry) const
{
- const pit::OutRecordCollection& outRecords = pitEntry.getOutRecords();
pit::OutRecordCollection::const_iterator lastOutgoing = std::max_element(
- outRecords.begin(), outRecords.end(),
- [] (const pit::OutRecord& a, const pit::OutRecord& b) {
- return a.getLastRenewed() < b.getLastRenewed();
- });
- BOOST_ASSERT(lastOutgoing != outRecords.end()); // otherwise it's new PIT entry
+ pitEntry.out_begin(), pitEntry.out_end(),
+ [] (const pit::OutRecord& a, const pit::OutRecord& b) {
+ return a.getLastRenewed() < b.getLastRenewed();
+ });
+ BOOST_ASSERT(lastOutgoing != pitEntry.out_end()); // otherwise it's new PIT entry
return lastOutgoing->getLastRenewed();
}
diff --git a/daemon/fw/strategy.cpp b/daemon/fw/strategy.cpp
index 00fe82f..e0dca89 100644
--- a/daemon/fw/strategy.cpp
+++ b/daemon/fw/strategy.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -74,8 +74,7 @@
{
// populate downstreams with all downstreams faces
std::unordered_set<const Face*> downstreams;
- const pit::InRecordCollection& inRecords = pitEntry->getInRecords();
- std::transform(inRecords.begin(), inRecords.end(), std::inserter(downstreams, downstreams.end()),
+ std::transform(pitEntry->in_begin(), pitEntry->in_end(), std::inserter(downstreams, downstreams.end()),
[] (const pit::InRecord& inR) { return inR.getFace().get(); });
// delete excluded faces
@@ -88,7 +87,7 @@
for (const Face* downstream : downstreams) {
this->sendNack(pitEntry, *downstream, header);
}
- // warning: don't loop on pitEntry->getInRecords(), because InRecord is erased when sending Nack
+ // warning: don't loop on pitEntry->getInRecords(), because in-record is deleted when sending Nack
}
} // namespace fw
diff --git a/daemon/table/pit-entry.cpp b/daemon/table/pit-entry.cpp
index 21e4c53..d19369a 100644
--- a/daemon/table/pit-entry.cpp
+++ b/daemon/table/pit-entry.cpp
@@ -34,10 +34,11 @@
{
}
-const Name&
-Entry::getName() const
+InRecordCollection::iterator
+Entry::getInRecord(const Face& face)
{
- return m_interest->getName();
+ return std::find_if(m_inRecords.begin(), m_inRecords.end(),
+ [&face] (const InRecord& inRecord) { return inRecord.getFace().get() == &face; });
}
InRecordCollection::iterator
@@ -54,13 +55,6 @@
return it;
}
-InRecordCollection::const_iterator
-Entry::getInRecord(const Face& face) const
-{
- return std::find_if(m_inRecords.begin(), m_inRecords.end(),
- [&face] (const InRecord& inRecord) { return inRecord.getFace().get() == &face; });
-}
-
void
Entry::deleteInRecord(const Face& face)
{
@@ -72,12 +66,19 @@
}
void
-Entry::deleteInRecords()
+Entry::clearInRecords()
{
m_inRecords.clear();
}
OutRecordCollection::iterator
+Entry::getOutRecord(const Face& face)
+{
+ return std::find_if(m_outRecords.begin(), m_outRecords.end(),
+ [&face] (const OutRecord& outRecord) { return outRecord.getFace().get() == &face; });
+}
+
+OutRecordCollection::iterator
Entry::insertOrUpdateOutRecord(shared_ptr<Face> face, const Interest& interest)
{
auto it = std::find_if(m_outRecords.begin(), m_outRecords.end(),
@@ -91,13 +92,6 @@
return it;
}
-OutRecordCollection::iterator
-Entry::getOutRecord(const Face& face)
-{
- return std::find_if(m_outRecords.begin(), m_outRecords.end(),
- [&face] (const OutRecord& outRecord) { return outRecord.getFace().get() == &face; });
-}
-
void
Entry::deleteOutRecord(const Face& face)
{
diff --git a/daemon/table/pit-entry.hpp b/daemon/table/pit-entry.hpp
index 012b5aa..ece0b40 100644
--- a/daemon/table/pit-entry.hpp
+++ b/daemon/table/pit-entry.hpp
@@ -40,15 +40,21 @@
namespace pit {
-/** \brief represents an unordered collection of InRecords
+/** \brief an unordered collection of in-records
*/
-typedef std::list< InRecord> InRecordCollection;
+typedef std::list<InRecord> InRecordCollection;
-/** \brief represents an unordered collection of OutRecords
+/** \brief an unordered collection of out-records
*/
typedef std::list<OutRecord> OutRecordCollection;
-/** \brief represents a PIT entry
+/** \brief an Interest table entry
+ *
+ * An Interest table entry represents either a pending Interest or a recently satisfied Interest.
+ * Each entry contains a collection of in-records, a collection of out-records,
+ * and two timers used in forwarding pipelines.
+ * In addition, the entry, in-records, and out-records are subclasses of StrategyInfoHost,
+ * which allows forwarding strategy to store arbitrary information on them.
*/
class Entry : public StrategyInfoHost, noncopyable
{
@@ -56,6 +62,11 @@
explicit
Entry(const Interest& interest);
+ /** \return the representative Interest of the PIT entry
+ * \note Every Interest in in-records and out-records should have same Name and Selectors
+ * as the representative Interest.
+ * \todo #3162 require Link field to match the representative Interest
+ */
const Interest&
getInterest() const;
@@ -64,57 +75,118 @@
const Name&
getName() const;
-public: // InRecord
+public: // in-record
+ /** \return collection of in-records
+ */
const InRecordCollection&
getInRecords() const;
- /** \brief inserts a InRecord for face, and updates it with interest
- *
- * If InRecord for face exists, the existing one is updated.
- * This method does not add the Nonce as a seen Nonce.
- * \return an iterator to the InRecord
+ /** \retval true There is at least one in-record.
+ * This implies some downstream is waiting for Data or Nack.
+ * \retval false There is no in-record.
+ * This implies the entry is new or has been satisfied or Nacked.
+ */
+ bool
+ hasInRecords() const;
+
+ InRecordCollection::iterator
+ in_begin();
+
+ InRecordCollection::const_iterator
+ in_begin() const;
+
+ InRecordCollection::iterator
+ in_end();
+
+ InRecordCollection::const_iterator
+ in_end() const;
+
+ /** \brief get the in-record for \p face
+ * \return an iterator to the in-record, or .in_end() if it does not exist
+ */
+ InRecordCollection::iterator
+ getInRecord(const Face& face);
+
+ /** \brief insert or update an in-record
+ * \return an iterator to the new or updated in-record
*/
InRecordCollection::iterator
insertOrUpdateInRecord(shared_ptr<Face> face, const Interest& interest);
- /** \brief get the InRecord for face
- * \return an iterator to the InRecord, or .end if it does not exist
+ /** \brief delete the in-record for \p face if it exists
*/
- InRecordCollection::const_iterator
- getInRecord(const Face& face) const;
-
- /// deletes one InRecord for face if exists
void
deleteInRecord(const Face& face);
- /// deletes all InRecords
+ /** \brief delete all in-records
+ */
void
- deleteInRecords();
+ clearInRecords();
-public: // OutRecord
+public: // out-record
+ /** \return collection of in-records
+ */
const OutRecordCollection&
getOutRecords() const;
- /** \brief inserts a OutRecord for face, and updates it with interest
- *
- * If OutRecord for face exists, the existing one is updated.
- * \return an iterator to the OutRecord
+ /** \retval true There is at least one out-record.
+ * This implies the Interest has been forwarded to some upstream,
+ * and they haven't returned Data, but may have returned Nacks.
+ * \retval false There is no out-record.
+ * This implies the Interest has not been forwarded.
*/
- OutRecordCollection::iterator
- insertOrUpdateOutRecord(shared_ptr<Face> face, const Interest& interest);
+ bool
+ hasOutRecords() const;
- /** \brief get the OutRecord for face
- * \return an iterator to the OutRecord, or .end if it does not exist
+ OutRecordCollection::iterator
+ out_begin();
+
+ OutRecordCollection::const_iterator
+ out_begin() const;
+
+ OutRecordCollection::iterator
+ out_end();
+
+ OutRecordCollection::const_iterator
+ out_end() const;
+
+ /** \brief get the out-record for \p face
+ * \return an iterator to the out-record, or .out_end() if it does not exist
*/
OutRecordCollection::iterator
getOutRecord(const Face& face);
- /// deletes one OutRecord for face if exists
+ /** \brief insert or update an out-record
+ * \return an iterator to the new or updated out-record
+ */
+ OutRecordCollection::iterator
+ insertOrUpdateOutRecord(shared_ptr<Face> face, const Interest& interest);
+
+ /** \brief delete the out-record for \p face if it exists
+ */
void
deleteOutRecord(const Face& face);
public:
+ /** \brief unsatisfy timer
+ *
+ * This timer is used in forwarding pipelines to delete the entry
+ * when it expires without being satisfied.
+ * It fires when the last InterestLifetime among in-records expires.
+ *
+ * Either this or the straggler timer should be set at all times,
+ * except when this entry is being processed in a pipeline.
+ */
scheduler::EventId m_unsatisfyTimer;
+
+ /** \brief straggler timer
+ *
+ * This timer is used in forwarding pipelines to delete the entry when it has been satisfied
+ * and is no longer needed for measurement collection purpose.
+ *
+ * Either this or the unsatisfy timer should be set at all times,
+ * except when this entry is being processed in a pipeline.
+ */
scheduler::EventId m_stragglerTimer;
private:
@@ -122,9 +194,6 @@
InRecordCollection m_inRecords;
OutRecordCollection m_outRecords;
- static const Name LOCALHOST_NAME;
- static const Name LOCALHOP_NAME;
-
shared_ptr<name_tree::Entry> m_nameTreeEntry;
friend class nfd::NameTree;
@@ -137,18 +206,84 @@
return *m_interest;
}
+inline const Name&
+Entry::getName() const
+{
+ return m_interest->getName();
+}
+
inline const InRecordCollection&
Entry::getInRecords() const
{
return m_inRecords;
}
+inline bool
+Entry::hasInRecords() const
+{
+ return !m_inRecords.empty();
+}
+
+inline InRecordCollection::iterator
+Entry::in_begin()
+{
+ return m_inRecords.begin();
+}
+
+inline InRecordCollection::const_iterator
+Entry::in_begin() const
+{
+ return m_inRecords.begin();
+}
+
+inline InRecordCollection::iterator
+Entry::in_end()
+{
+ return m_inRecords.end();
+}
+
+inline InRecordCollection::const_iterator
+Entry::in_end() const
+{
+ return m_inRecords.end();
+}
+
inline const OutRecordCollection&
Entry::getOutRecords() const
{
return m_outRecords;
}
+inline bool
+Entry::hasOutRecords() const
+{
+ return !m_outRecords.empty();
+}
+
+inline OutRecordCollection::iterator
+Entry::out_begin()
+{
+ return m_outRecords.begin();
+}
+
+inline OutRecordCollection::const_iterator
+Entry::out_begin() const
+{
+ return m_outRecords.begin();
+}
+
+inline OutRecordCollection::iterator
+Entry::out_end()
+{
+ return m_outRecords.end();
+}
+
+inline OutRecordCollection::const_iterator
+Entry::out_end() const
+{
+ return m_outRecords.end();
+}
+
} // namespace pit
} // namespace nfd
diff --git a/daemon/table/pit-in-record.hpp b/daemon/table/pit-in-record.hpp
index da56d1f..dd6ad06 100644
--- a/daemon/table/pit-in-record.hpp
+++ b/daemon/table/pit-in-record.hpp
@@ -1,12 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014, Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology,
- * The University of Memphis
+ * Copyright (c) 2014-2016, Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -31,8 +31,7 @@
namespace nfd {
namespace pit {
-/** \class InRecord
- * \brief contains information about an Interest from an incoming face
+/** \brief contains information about an Interest from an incoming face
*/
class InRecord : public FaceRecord
{
diff --git a/tests/daemon/fw/best-route-strategy2.t.cpp b/tests/daemon/fw/best-route-strategy2.t.cpp
index 9cecd15..00c059f 100644
--- a/tests/daemon/fw/best-route-strategy2.t.cpp
+++ b/tests/daemon/fw/best-route-strategy2.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -119,7 +119,7 @@
scheduler::cancel(retxFrom4Evt);
// nexthops for accepted retransmissions: follow FIB cost,
- // later forward to an eligible upstream with earliest OutRecord
+ // later forward to an eligible upstream with earliest out-record
BOOST_REQUIRE_GE(strategy.sendInterestHistory.size(), 6);
BOOST_CHECK_EQUAL(strategy.sendInterestHistory[1].outFaceId, face1->getId());
BOOST_CHECK_EQUAL(strategy.sendInterestHistory[2].outFaceId, face3->getId());
diff --git a/tests/daemon/fw/forwarder.t.cpp b/tests/daemon/fw/forwarder.t.cpp
index 906e2ca..45014ff 100644
--- a/tests/daemon/fw/forwarder.t.cpp
+++ b/tests/daemon/fw/forwarder.t.cpp
@@ -476,8 +476,8 @@
BOOST_CHECK_EQUAL(strategyQ->afterReceiveNack_count, 1);
// record Nack on PIT out-record
- pit::OutRecordCollection::const_iterator outRecord1 = pit1->getOutRecord(*face1);
- BOOST_REQUIRE(outRecord1 != pit1->getOutRecords().end());
+ pit::OutRecordCollection::iterator outRecord1 = pit1->getOutRecord(*face1);
+ BOOST_REQUIRE(outRecord1 != pit1->out_end());
BOOST_REQUIRE(outRecord1->getIncomingNack() != nullptr);
BOOST_CHECK_EQUAL(outRecord1->getIncomingNack()->getReason(), lp::NackReason::CONGESTION);
@@ -559,8 +559,8 @@
BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest().getNonce(), 152);
// erase in-record
- pit::InRecordCollection::const_iterator inRecord2a = pit2->getInRecord(*face1);
- BOOST_CHECK(inRecord2a == pit2->getInRecords().end());
+ pit::InRecordCollection::iterator inRecord2a = pit2->getInRecord(*face1);
+ BOOST_CHECK(inRecord2a == pit2->in_end());
// send Nack with correct Nonce
face2->sentNacks.clear();
@@ -570,8 +570,8 @@
BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().getNonce(), 808);
// erase in-record
- pit::InRecordCollection::const_iterator inRecord2b = pit2->getInRecord(*face1);
- BOOST_CHECK(inRecord2b == pit2->getInRecords().end());
+ pit::InRecordCollection::iterator inRecord2b = pit2->getInRecord(*face1);
+ BOOST_CHECK(inRecord2b == pit2->in_end());
// don't send Nack to multi-access face
shared_ptr<Interest> interest2c = makeInterest("/Vi8tRm9MG3", 228);
diff --git a/tests/daemon/fw/ncc-strategy.t.cpp b/tests/daemon/fw/ncc-strategy.t.cpp
index 94fe162..fa42622 100644
--- a/tests/daemon/fw/ncc-strategy.t.cpp
+++ b/tests/daemon/fw/ncc-strategy.t.cpp
@@ -208,7 +208,7 @@
// face1 responds
shared_ptr<Data> data1 = makeData("ndn:/seRMz5a6/%00");
strategy->beforeSatisfyInterest(pitEntry1, *face1, *data1);
- pitEntry1->deleteInRecords();
+ pitEntry1->clearInRecords();
this->advanceClocks(time::milliseconds(10));
// face2 also responds
strategy->beforeSatisfyInterest(pitEntry1, *face2, *data1);
@@ -268,7 +268,7 @@
data1->setFreshnessPeriod(time::milliseconds(5));
strategy->beforeSatisfyInterest(pitEntry1, *face2, *data1);
pitEntry1->deleteOutRecord(*face2);
- pitEntry1->deleteInRecords();
+ pitEntry1->clearInRecords();
this->advanceClocks(time::milliseconds(10));
// similar Interest: strategy should still forward it
diff --git a/tests/daemon/table/pit.t.cpp b/tests/daemon/table/pit.t.cpp
index 9ca3ec7..01f063d 100644
--- a/tests/daemon/table/pit.t.cpp
+++ b/tests/daemon/table/pit.t.cpp
@@ -58,22 +58,21 @@
interest4->setInterestLifetime(time::milliseconds(8795));
interest4->setNonce(17365);
- pit::Entry entry(*interest);
+ Entry entry(*interest);
BOOST_CHECK_EQUAL(entry.getInterest().getName(), name);
BOOST_CHECK_EQUAL(entry.getName(), name);
- const pit::InRecordCollection& inRecords1 = entry.getInRecords();
+ const InRecordCollection& inRecords1 = entry.getInRecords();
BOOST_CHECK_EQUAL(inRecords1.size(), 0);
- const pit::OutRecordCollection& outRecords1 = entry.getOutRecords();
+ const OutRecordCollection& outRecords1 = entry.getOutRecords();
BOOST_CHECK_EQUAL(outRecords1.size(), 0);
- // insert InRecord
+ // insert in-record
time::steady_clock::TimePoint before1 = time::steady_clock::now();
- pit::InRecordCollection::iterator in1 =
- entry.insertOrUpdateInRecord(face1, *interest1);
+ InRecordCollection::iterator in1 = entry.insertOrUpdateInRecord(face1, *interest1);
time::steady_clock::TimePoint after1 = time::steady_clock::now();
- const pit::InRecordCollection& inRecords2 = entry.getInRecords();
+ const InRecordCollection& inRecords2 = entry.getInRecords();
BOOST_CHECK_EQUAL(inRecords2.size(), 1);
BOOST_CHECK(in1 == inRecords2.begin());
BOOST_CHECK_EQUAL(in1->getFace(), face1);
@@ -85,12 +84,11 @@
(after1 - before1));
BOOST_CHECK(in1 == entry.getInRecord(*face1));
- // insert OutRecord
+ // insert out-record
time::steady_clock::TimePoint before2 = time::steady_clock::now();
- pit::OutRecordCollection::iterator out1 =
- entry.insertOrUpdateOutRecord(face1, *interest1);
+ OutRecordCollection::iterator out1 = entry.insertOrUpdateOutRecord(face1, *interest1);
time::steady_clock::TimePoint after2 = time::steady_clock::now();
- const pit::OutRecordCollection& outRecords2 = entry.getOutRecords();
+ const OutRecordCollection& outRecords2 = entry.getOutRecords();
BOOST_CHECK_EQUAL(outRecords2.size(), 1);
BOOST_CHECK(out1 == outRecords2.begin());
BOOST_CHECK_EQUAL(out1->getFace(), face1);
@@ -102,12 +100,11 @@
(after2 - before2));
BOOST_CHECK(out1 == entry.getOutRecord(*face1));
- // update InRecord
+ // update in-record
time::steady_clock::TimePoint before3 = time::steady_clock::now();
- pit::InRecordCollection::iterator in2 =
- entry.insertOrUpdateInRecord(face1, *interest2);
+ InRecordCollection::iterator in2 = entry.insertOrUpdateInRecord(face1, *interest2);
time::steady_clock::TimePoint after3 = time::steady_clock::now();
- const pit::InRecordCollection& inRecords3 = entry.getInRecords();
+ const InRecordCollection& inRecords3 = entry.getInRecords();
BOOST_CHECK_EQUAL(inRecords3.size(), 1);
BOOST_CHECK(in2 == inRecords3.begin());
BOOST_CHECK_EQUAL(in2->getFace(), face1);
@@ -116,42 +113,41 @@
- interest2->getInterestLifetime(),
(after3 - before3));
- // insert another InRecord
- pit::InRecordCollection::iterator in3 =
- entry.insertOrUpdateInRecord(face2, *interest3);
- const pit::InRecordCollection& inRecords4 = entry.getInRecords();
+ // insert another in-record
+ InRecordCollection::iterator in3 = entry.insertOrUpdateInRecord(face2, *interest3);
+ const InRecordCollection& inRecords4 = entry.getInRecords();
BOOST_CHECK_EQUAL(inRecords4.size(), 2);
BOOST_CHECK_EQUAL(in3->getFace(), face2);
- // get InRecord
- pit::InRecordCollection::const_iterator in4 = entry.getInRecord(*face1);
- BOOST_REQUIRE(in4 != entry.getInRecords().end());
+ // get in-record
+ InRecordCollection::iterator in4 = entry.getInRecord(*face1);
+ BOOST_REQUIRE(in4 != entry.in_end());
BOOST_CHECK_EQUAL(in4->getFace(), face1);
- // delete all InRecords
- entry.deleteInRecords();
- const pit::InRecordCollection& inRecords5 = entry.getInRecords();
+ // clear in-records
+ entry.clearInRecords();
+ const InRecordCollection& inRecords5 = entry.getInRecords();
BOOST_CHECK_EQUAL(inRecords5.size(), 0);
- BOOST_CHECK(entry.getInRecord(*face1) == entry.getInRecords().end());
+ BOOST_CHECK(entry.getInRecord(*face1) == entry.in_end());
- // insert another OutRecord
- pit::OutRecordCollection::iterator out2 =
+ // insert another out-record
+ OutRecordCollection::iterator out2 =
entry.insertOrUpdateOutRecord(face2, *interest4);
- const pit::OutRecordCollection& outRecords3 = entry.getOutRecords();
+ const OutRecordCollection& outRecords3 = entry.getOutRecords();
BOOST_CHECK_EQUAL(outRecords3.size(), 2);
BOOST_CHECK_EQUAL(out2->getFace(), face2);
- // get OutRecord
- pit::OutRecordCollection::const_iterator out3 = entry.getOutRecord(*face1);
- BOOST_REQUIRE(out3 != entry.getOutRecords().end());
+ // get out-record
+ OutRecordCollection::iterator out3 = entry.getOutRecord(*face1);
+ BOOST_REQUIRE(out3 != entry.out_end());
BOOST_CHECK_EQUAL(out3->getFace(), face1);
- // delete OutRecord
+ // delete out-record
entry.deleteOutRecord(*face2);
- const pit::OutRecordCollection& outRecords4 = entry.getOutRecords();
+ const OutRecordCollection& outRecords4 = entry.getOutRecords();
BOOST_REQUIRE_EQUAL(outRecords4.size(), 1);
BOOST_CHECK_EQUAL(outRecords4.begin()->getFace(), face1);
- BOOST_CHECK(entry.getOutRecord(*face2) == entry.getOutRecords().end());
+ BOOST_CHECK(entry.getOutRecord(*face2) == entry.out_end());
}
BOOST_AUTO_TEST_CASE(Lifetime)
@@ -161,19 +157,19 @@
BOOST_ASSERT(interest->getInterestLifetime() < time::milliseconds::zero());
shared_ptr<Face> face = make_shared<DummyFace>();
- pit::Entry entry(*interest);
+ Entry entry(*interest);
- pit::InRecordCollection::iterator inIt = entry.insertOrUpdateInRecord(face, *interest);
+ InRecordCollection::iterator inIt = entry.insertOrUpdateInRecord(face, *interest);
BOOST_CHECK_GT(inIt->getExpiry(), time::steady_clock::now());
- pit::OutRecordCollection::iterator outIt = entry.insertOrUpdateOutRecord(face, *interest);
+ OutRecordCollection::iterator outIt = entry.insertOrUpdateOutRecord(face, *interest);
BOOST_CHECK_GT(outIt->getExpiry(), time::steady_clock::now());
}
BOOST_AUTO_TEST_CASE(OutRecordNack)
{
shared_ptr<Face> face1 = make_shared<DummyFace>();
- pit::OutRecord outR(face1);
+ OutRecord outR(face1);
BOOST_CHECK(outR.getIncomingNack() == nullptr);
shared_ptr<Interest> interest1 = makeInterest("ndn:/uWiapGjYL");
@@ -215,7 +211,7 @@
NameTree nameTree(16);
Pit pit(nameTree);
BOOST_CHECK_EQUAL(pit.size(), 0);
- std::pair<shared_ptr<pit::Entry>, bool> insertResult;
+ std::pair<shared_ptr<Entry>, bool> insertResult;
// base
shared_ptr<Interest> interestA = make_shared<Interest>(name1);
@@ -315,7 +311,7 @@
NameTree nameTree(16);
Pit pit(nameTree);
- std::pair<shared_ptr<pit::Entry>, bool> insertResult;
+ std::pair<shared_ptr<Entry>, bool> insertResult;
BOOST_CHECK_EQUAL(pit.size(), 0);
@@ -346,7 +342,7 @@
size_t nNameTreeEntriesBefore = nameTree.size();
shared_ptr<Interest> interest = makeInterest("/37xWVvQ2K");
- shared_ptr<pit::Entry> entry = pit.insert(*interest).first;
+ shared_ptr<Entry> entry = pit.insert(*interest).first;
pit.erase(entry);
BOOST_CHECK_EQUAL(nameTree.size(), nNameTreeEntriesBefore);
}
@@ -379,14 +375,14 @@
shared_ptr<Data> data = makeData(nameABCD);
- pit::DataMatchResult matches = pit.findAllDataMatches(*data);
+ DataMatchResult matches = pit.findAllDataMatches(*data);
bool hasA = false;
bool hasAB = false;
bool hasABC = false;
bool hasD = false;
- for (const shared_ptr<pit::Entry>& entry : matches) {
+ for (const shared_ptr<Entry>& entry : matches) {
++count;
if (entry->getName().equals(nameA ))
@@ -419,10 +415,10 @@
shared_ptr<Interest> interest = makeInterest(fullName);
pit.insert(*interest);
- pit::DataMatchResult matches = pit.findAllDataMatches(*data);
+ DataMatchResult matches = pit.findAllDataMatches(*data);
BOOST_REQUIRE_EQUAL(std::distance(matches.begin(), matches.end()), 1);
- shared_ptr<pit::Entry> found = *matches.begin();
+ shared_ptr<Entry> found = *matches.begin();
BOOST_CHECK_EQUAL(found->getName(), fullName);
}