table: change ContentStore lookup API to allow async implementations
refs: #2411
Change-Id: Ifbb4179c34cf10a7913f8113a2f9238476d8eafa
diff --git a/daemon/fw/forwarder.cpp b/daemon/fw/forwarder.cpp
index 524fef5..3afdc00 100644
--- a/daemon/fw/forwarder.cpp
+++ b/daemon/fw/forwarder.cpp
@@ -91,23 +91,25 @@
const pit::InRecordCollection& inRecords = pitEntry->getInRecords();
bool isPending = inRecords.begin() != inRecords.end();
if (!isPending) {
- // CS lookup
- const Data* csMatch = m_cs.find(interest);
- if (csMatch != 0) {
- const_cast<Data*>(csMatch)->setIncomingFaceId(FACEID_CONTENT_STORE);
- // XXX should we lookup PIT for other Interests that also match csMatch?
-
- // set PIT straggler timer
- this->setStragglerTimer(pitEntry, true, csMatch->getFreshnessPeriod());
-
- // goto outgoing Data pipeline
- this->onOutgoingData(*csMatch, inFace);
- return;
- }
+ m_cs.find(interest,
+ bind(&Forwarder::onContentStoreHit, this, ref(inFace), pitEntry, _1, _2),
+ bind(&Forwarder::onContentStoreMiss, this, ref(inFace), pitEntry, _1));
}
+ else {
+ this->onContentStoreMiss(inFace, pitEntry, interest);
+ }
+}
+void
+Forwarder::onContentStoreMiss(const Face& inFace,
+ shared_ptr<pit::Entry> pitEntry,
+ const Interest& interest)
+{
+ NFD_LOG_DEBUG("onContentStoreMiss interest=" << interest.getName());
+
+ shared_ptr<Face> face = const_pointer_cast<Face>(inFace.shared_from_this());
// insert InRecord
- pitEntry->insertOrUpdateInRecord(inFace.shared_from_this(), interest);
+ pitEntry->insertOrUpdateInRecord(face, interest);
// set PIT unsatisfy timer
this->setUnsatisfyTimer(pitEntry);
@@ -121,6 +123,24 @@
}
void
+Forwarder::onContentStoreHit(const Face& inFace,
+ shared_ptr<pit::Entry> pitEntry,
+ const Interest& interest,
+ const Data& data)
+{
+ NFD_LOG_DEBUG("onContentStoreMiss interest=" << interest.getName());
+
+ const_pointer_cast<Data>(data.shared_from_this())->setIncomingFaceId(FACEID_CONTENT_STORE);
+ // XXX should we lookup PIT for other Interests that also match csMatch?
+
+ // set PIT straggler timer
+ this->setStragglerTimer(pitEntry, true, data.getFreshnessPeriod());
+
+ // goto outgoing Data pipeline
+ this->onOutgoingData(data, *const_pointer_cast<Face>(inFace.shared_from_this()));
+}
+
+void
Forwarder::onInterestLoop(Face& inFace, const Interest& interest,
shared_ptr<pit::Entry> pitEntry)
{
diff --git a/daemon/fw/forwarder.hpp b/daemon/fw/forwarder.hpp
index a753f15..aa5d19d 100644
--- a/daemon/fw/forwarder.hpp
+++ b/daemon/fw/forwarder.hpp
@@ -110,6 +110,17 @@
VIRTUAL_WITH_TESTS void
onIncomingInterest(Face& inFace, const Interest& interest);
+ /** \brief Content Store miss pipeline
+ */
+ void
+ onContentStoreMiss(const Face& inFace, shared_ptr<pit::Entry> pitEntry, const Interest& interest);
+
+ /** \brief Content Store hit pipeline
+ */
+ void
+ onContentStoreHit(const Face& inFace, shared_ptr<pit::Entry> pitEntry,
+ const Interest& interest, const Data& data);
+
/** \brief Interest loop pipeline
*/
VIRTUAL_WITH_TESTS void
diff --git a/daemon/table/cs.cpp b/daemon/table/cs.cpp
index 2226335..a63d33e 100644
--- a/daemon/table/cs.cpp
+++ b/daemon/table/cs.cpp
@@ -97,9 +97,14 @@
return true;
}
-const Data*
-Cs::find(const Interest& interest) const
+void
+Cs::find(const Interest& interest,
+ const HitCallback& hitCallback,
+ const MissCallback& missCallback) const
{
+ BOOST_ASSERT(static_cast<bool>(hitCallback));
+ BOOST_ASSERT(static_cast<bool>(missCallback));
+
const Name& prefix = interest.getName();
bool isRightmost = interest.getChildSelector() == 1;
NFD_LOG_DEBUG("find " << prefix << (isRightmost ? " R" : " L"));
@@ -120,10 +125,11 @@
if (match == last) {
NFD_LOG_DEBUG(" no-match");
- return nullptr;
+ missCallback(interest);
+ return;
}
NFD_LOG_DEBUG(" matching " << match->getName());
- return &match->getData();
+ hitCallback(interest, match->getData());
}
TableIt
diff --git a/daemon/table/cs.hpp b/daemon/table/cs.hpp
index 77a4474..5e3bfbe 100644
--- a/daemon/table/cs.hpp
+++ b/daemon/table/cs.hpp
@@ -68,10 +68,20 @@
bool
insert(const Data& data, bool isUnsolicited = false);
+ typedef std::function<void(const Interest&, const Data& data)> HitCallback;
+ typedef std::function<void(const Interest&)> MissCallback;
+
/** \brief finds the best matching Data packet
+ * \param interest the Interest for lookup
+ * \param hitCallback a callback if a match is found; must not be empty
+ * \param missCallback a callback if there's no match; must not be empty
+ * \note A lookup invokes either callback exactly once.
+ * The callback may be invoked either before or after find() returns
*/
- const Data*
- find(const Interest& interest) const;
+ void
+ find(const Interest& interest,
+ const HitCallback& hitCallback,
+ const MissCallback& missCallback) const;
void
erase(const Name& exactName)