table: ensure NameTree::lookup(tableEntry) does not return nullptr

NameTree::lookup(tableEntry) is always equivalent to NameTree::lookup(Name).
NameTree::getEntry(tableEntry) should be used when inserting new name tree entry is undesired.

refs #3687

Change-Id: I0b17cd07dde83341976cfe66c85855dfb2fa6e89
diff --git a/daemon/table/name-tree.cpp b/daemon/table/name-tree.cpp
index 9056b8a..fa3b558 100644
--- a/daemon/table/name-tree.cpp
+++ b/daemon/table/name-tree.cpp
@@ -62,10 +62,16 @@
 }
 
 shared_ptr<Entry>
-NameTree::lookup(const fib::Entry& fibEntry) const
+NameTree::lookup(const fib::Entry& fibEntry)
 {
   shared_ptr<Entry> nte = this->getEntry(fibEntry);
-  BOOST_ASSERT(nte == nullptr || nte->getFibEntry() == &fibEntry);
+  if (nte == nullptr) {
+    // special case: Fib::s_emptyEntry is unattached
+    BOOST_ASSERT(fibEntry.getPrefix().empty());
+    return this->lookup(fibEntry.getPrefix());
+  }
+
+  BOOST_ASSERT(nte->getFibEntry() == &fibEntry);
   return nte;
 }
 
@@ -73,32 +79,41 @@
 NameTree::lookup(const pit::Entry& pitEntry)
 {
   shared_ptr<Entry> nte = this->getEntry(pitEntry);
-  if (nte == nullptr) {
-    return nullptr;
-  }
+  BOOST_ASSERT(nte != nullptr);
+
+  BOOST_ASSERT(std::count_if(nte->getPitEntries().begin(), nte->getPitEntries().end(),
+    [&pitEntry] (const shared_ptr<pit::Entry>& pitEntry1) {
+      return pitEntry1.get() == &pitEntry;
+    }) == 1);
 
   if (nte->getName().size() == pitEntry.getName().size()) {
     return nte;
   }
 
+  // special case: PIT entry whose Interest name ends with an implicit digest
+  // are attached to the name tree entry with one-shorter-prefix.
   BOOST_ASSERT(pitEntry.getName().at(-1).isImplicitSha256Digest());
   BOOST_ASSERT(nte->getName() == pitEntry.getName().getPrefix(-1));
   return this->lookup(pitEntry.getName());
 }
 
 shared_ptr<Entry>
-NameTree::lookup(const measurements::Entry& measurementsEntry) const
+NameTree::lookup(const measurements::Entry& measurementsEntry)
 {
   shared_ptr<Entry> nte = this->getEntry(measurementsEntry);
-  BOOST_ASSERT(nte == nullptr || nte->getMeasurementsEntry() == &measurementsEntry);
+  BOOST_ASSERT(nte != nullptr);
+
+  BOOST_ASSERT(nte->getMeasurementsEntry() == &measurementsEntry);
   return nte;
 }
 
 shared_ptr<Entry>
-NameTree::lookup(const strategy_choice::Entry& strategyChoiceEntry) const
+NameTree::lookup(const strategy_choice::Entry& strategyChoiceEntry)
 {
   shared_ptr<Entry> nte = this->getEntry(strategyChoiceEntry);
-  BOOST_ASSERT(nte == nullptr || nte->getStrategyChoiceEntry() == &strategyChoiceEntry);
+  BOOST_ASSERT(nte != nullptr);
+
+  BOOST_ASSERT(nte->getStrategyChoiceEntry() == &strategyChoiceEntry);
   return nte;
 }
 
@@ -161,27 +176,28 @@
 }
 
 Entry*
-NameTree::findLongestPrefixMatch(const pit::Entry& pitEntry) const
+NameTree::findLongestPrefixMatch(const pit::Entry& pitEntry, const EntrySelector& entrySelector) const
 {
-  shared_ptr<Entry> nte = this->getEntry(pitEntry);
+  const Entry* nte = this->getEntry(pitEntry).get();
   BOOST_ASSERT(nte != nullptr);
-  if (nte->getName().size() == pitEntry.getName().size()) {
-    return nte.get();
+
+  if (nte->getName().size() < pitEntry.getName().size()) {
+    // special case: PIT entry whose Interest name ends with an implicit digest
+    // are attached to the name tree entry with one-shorter-prefix.
+    BOOST_ASSERT(pitEntry.getName().at(-1).isImplicitSha256Digest());
+    BOOST_ASSERT(nte->getName() == pitEntry.getName().getPrefix(-1));
+    const Entry* exact = this->findExactMatch(pitEntry.getName());
+    if (exact != nullptr) {
+      nte = exact;
+    }
   }
 
-  // special case: PIT entry whose Interest name ends with an implicit digest
-  // are attached to the name tree entry with one-shorter-prefix.
-  BOOST_ASSERT(pitEntry.getName().at(-1).isImplicitSha256Digest());
-  BOOST_ASSERT(nte->getName() == pitEntry.getName().getPrefix(-1));
-  Entry* exact = this->findExactMatch(pitEntry.getName());
-  return exact == nullptr ? nte.get() : exact;
+  return this->findLongestPrefixMatch(*nte, entrySelector);
 }
 
 boost::iterator_range<NameTree::const_iterator>
 NameTree::findAllMatches(const Name& name, const EntrySelector& entrySelector) const
 {
-  NFD_LOG_TRACE("NameTree::findAllMatches" << name);
-
   // As we are using Name Prefix Hash Table, and the current LPM() is
   // implemented as starting from full name, and reduce the number of
   // components by 1 each time, we could use it here.
@@ -195,8 +211,6 @@
 boost::iterator_range<NameTree::const_iterator>
 NameTree::fullEnumerate(const EntrySelector& entrySelector) const
 {
-  NFD_LOG_TRACE("fullEnumerate");
-
   return {Iterator(make_shared<FullEnumerationImpl>(*this, entrySelector), nullptr), end()};
 }
 
@@ -204,7 +218,6 @@
 NameTree::partialEnumerate(const Name& prefix,
                            const EntrySubTreeSelector& entrySubTreeSelector) const
 {
-  // the first step is to process the root node
   Entry* entry = this->findExactMatch(prefix);
   return {Iterator(make_shared<PartialEnumerationImpl>(*this, entrySubTreeSelector), entry), end()};
 }