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