table: NameTree::getEntry

NameTree::get is renamed to NameTree::lookup.
NameTree::getEntry is introduced to return the NameTreeEntry on which a table entry is attached.
tableEntry::m_nameTreeEntry is changed to weak_ptr to avoid circular shared_ptr reference.

refs #3608, #3619

Change-Id: I425b6a2eb5fe3024bbaff4ff766eb6739be54b02
diff --git a/daemon/table/fib-entry.hpp b/daemon/table/fib-entry.hpp
index 4a6116e..9106d9f 100644
--- a/daemon/table/fib-entry.hpp
+++ b/daemon/table/fib-entry.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.
@@ -33,7 +33,7 @@
 class NameTree;
 namespace name_tree {
 class Entry;
-}
+} // namespace name_tree
 
 namespace fib {
 
@@ -105,7 +105,7 @@
   Name m_prefix;
   NextHopList m_nextHops;
 
-  shared_ptr<name_tree::Entry> m_nameTreeEntry;
+  weak_ptr<name_tree::Entry> m_nameTreeEntry;
   friend class nfd::NameTree;
   friend class nfd::name_tree::Entry;
 };
diff --git a/daemon/table/fib.cpp b/daemon/table/fib.cpp
index 7d60dfa..946652e 100644
--- a/daemon/table/fib.cpp
+++ b/daemon/table/fib.cpp
@@ -59,7 +59,7 @@
 static inline bool
 predicate_NameTreeEntry_hasFibEntry(const name_tree::Entry& entry)
 {
-  return static_cast<bool>(entry.getFibEntry());
+  return entry.getFibEntry() != nullptr;
 }
 
 shared_ptr<fib::Entry>
@@ -67,7 +67,7 @@
 {
   shared_ptr<name_tree::Entry> nameTreeEntry =
     m_nameTree.findLongestPrefixMatch(prefix, &predicate_NameTreeEntry_hasFibEntry);
-  if (static_cast<bool>(nameTreeEntry)) {
+  if (nameTreeEntry != nullptr) {
     return nameTreeEntry->getFibEntry();
   }
   return s_emptyEntry;
@@ -77,13 +77,15 @@
 Fib::findLongestPrefixMatch(shared_ptr<name_tree::Entry> nameTreeEntry) const
 {
   shared_ptr<fib::Entry> entry = nameTreeEntry->getFibEntry();
-  if (static_cast<bool>(entry))
+  if (entry != nullptr)
     return entry;
+
   nameTreeEntry = m_nameTree.findLongestPrefixMatch(nameTreeEntry,
                                                     &predicate_NameTreeEntry_hasFibEntry);
-  if (static_cast<bool>(nameTreeEntry)) {
+  if (nameTreeEntry != nullptr) {
     return nameTreeEntry->getFibEntry();
   }
+
   return s_emptyEntry;
 }
 
@@ -98,9 +100,8 @@
 shared_ptr<fib::Entry>
 Fib::findLongestPrefixMatch(const measurements::Entry& measurementsEntry) const
 {
-  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.get(measurementsEntry);
-
-  BOOST_ASSERT(static_cast<bool>(nameTreeEntry));
+  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.lookup(measurementsEntry);
+  BOOST_ASSERT(nameTreeEntry != nullptr);
 
   return findLongestPrefixMatch(nameTreeEntry);
 }
@@ -109,9 +110,10 @@
 Fib::findExactMatch(const Name& prefix) const
 {
   shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.findExactMatch(prefix);
-  if (static_cast<bool>(nameTreeEntry))
+  if (nameTreeEntry != nullptr)
     return nameTreeEntry->getFibEntry();
-  return shared_ptr<fib::Entry>();
+
+  return nullptr;
 }
 
 std::pair<shared_ptr<fib::Entry>, bool>
@@ -119,8 +121,9 @@
 {
   shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.lookup(prefix);
   shared_ptr<fib::Entry> entry = nameTreeEntry->getFibEntry();
-  if (static_cast<bool>(entry))
+  if (entry != nullptr)
     return std::make_pair(entry, false);
+
   entry = make_shared<fib::Entry>(prefix);
   nameTreeEntry->setFibEntry(entry);
   ++m_nItems;
@@ -139,7 +142,7 @@
 Fib::erase(const Name& prefix)
 {
   shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.findExactMatch(prefix);
-  if (static_cast<bool>(nameTreeEntry)) {
+  if (nameTreeEntry != nullptr) {
     this->erase(nameTreeEntry);
   }
 }
@@ -147,8 +150,8 @@
 void
 Fib::erase(const fib::Entry& entry)
 {
-  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.get(entry);
-  if (static_cast<bool>(nameTreeEntry)) {
+  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.lookup(entry);
+  if (nameTreeEntry != nullptr) {
     this->erase(nameTreeEntry);
   }
 }
diff --git a/daemon/table/measurements-entry.hpp b/daemon/table/measurements-entry.hpp
index f2dd627..0c9bc48 100644
--- a/daemon/table/measurements-entry.hpp
+++ b/daemon/table/measurements-entry.hpp
@@ -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,
@@ -36,7 +36,7 @@
 
 namespace name_tree {
 class Entry;
-}
+} // namespace name_tree
 
 class Measurements;
 
@@ -60,7 +60,7 @@
 private: // lifetime
   time::steady_clock::TimePoint m_expiry;
   scheduler::EventId m_cleanup;
-  shared_ptr<name_tree::Entry> m_nameTreeEntry;
+  weak_ptr<name_tree::Entry> m_nameTreeEntry;
 
   friend class nfd::NameTree;
   friend class nfd::name_tree::Entry;
diff --git a/daemon/table/measurements.cpp b/daemon/table/measurements.cpp
index 247a584..5981371 100644
--- a/daemon/table/measurements.cpp
+++ b/daemon/table/measurements.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,
@@ -66,7 +66,7 @@
 shared_ptr<Entry>
 Measurements::get(const fib::Entry& fibEntry)
 {
-  shared_ptr<name_tree::Entry> nte = m_nameTree.get(fibEntry);
+  shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(fibEntry);
   if (nte == nullptr) {
     // must be Fib::s_emptyEntry that is unattched
     BOOST_ASSERT(fibEntry.getPrefix().empty());
@@ -80,9 +80,9 @@
 shared_ptr<Entry>
 Measurements::get(const pit::Entry& pitEntry)
 {
-  shared_ptr<name_tree::Entry> nte = m_nameTree.get(pitEntry);
-
+  shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(pitEntry);
   BOOST_ASSERT(nte != nullptr);
+
   return this->get(*nte);
 }
 
@@ -93,7 +93,7 @@
     return nullptr;
   }
 
-  shared_ptr<name_tree::Entry> nteChild = m_nameTree.get(child);
+  shared_ptr<name_tree::Entry> nteChild = m_nameTree.lookup(child);
   shared_ptr<name_tree::Entry> nte = nteChild->getParent();
   BOOST_ASSERT(nte != nullptr);
   return this->get(*nte);
@@ -126,7 +126,8 @@
 Measurements::findLongestPrefixMatch(const pit::Entry& pitEntry,
                                      const measurements::EntryPredicate& pred) const
 {
-  shared_ptr<name_tree::Entry> nte = m_nameTree.get(pitEntry);
+  shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(pitEntry);
+  BOOST_ASSERT(nte != nullptr);
   return this->findLongestPrefixMatchImpl(nte, pred);
 }
 
@@ -140,12 +141,10 @@
 }
 
 void
-Measurements::extendLifetime(Entry& entry,
-                             const time::nanoseconds& lifetime)
+Measurements::extendLifetime(Entry& entry, const time::nanoseconds& lifetime)
 {
-  shared_ptr<name_tree::Entry> nte = m_nameTree.get(entry);
-  if (nte == nullptr ||
-      nte->getMeasurementsEntry().get() != &entry) {
+  shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(entry);
+  if (nte == nullptr || nte->getMeasurementsEntry().get() != &entry) {
     // entry is already gone; it is a dangling reference
     return;
   }
@@ -164,7 +163,7 @@
 void
 Measurements::cleanup(Entry& entry)
 {
-  shared_ptr<name_tree::Entry> nte = m_nameTree.get(entry);
+  shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(entry);
   if (nte != nullptr) {
     nte->setMeasurementsEntry(nullptr);
     m_nameTree.eraseEntryIfEmpty(nte);
diff --git a/daemon/table/name-tree-entry.cpp b/daemon/table/name-tree-entry.cpp
index 017dbfe..889ed97 100644
--- a/daemon/table/name-tree-entry.cpp
+++ b/daemon/table/name-tree-entry.cpp
@@ -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.
@@ -58,24 +58,23 @@
 Entry::isEmpty() const
 {
   return m_children.empty() &&
-         !static_cast<bool>(m_fibEntry) &&
+         m_fibEntry == nullptr &&
          m_pitEntries.empty() &&
-         !static_cast<bool>(m_measurementsEntry) &&
-         !static_cast<bool>(m_strategyChoiceEntry);
+         m_measurementsEntry == nullptr &&
+         m_strategyChoiceEntry == nullptr;
 }
 
 void
 Entry::setFibEntry(shared_ptr<fib::Entry> fibEntry)
 {
-  if (static_cast<bool>(fibEntry)) {
-    BOOST_ASSERT(!static_cast<bool>(fibEntry->m_nameTreeEntry));
-  }
+  BOOST_ASSERT(fibEntry == nullptr || fibEntry->m_nameTreeEntry.expired());
 
-  if (static_cast<bool>(m_fibEntry)) {
+  if (m_fibEntry != nullptr) {
     m_fibEntry->m_nameTreeEntry.reset();
   }
   m_fibEntry = fibEntry;
-  if (static_cast<bool>(m_fibEntry)) {
+
+  if (m_fibEntry != nullptr) {
     m_fibEntry->m_nameTreeEntry = this->shared_from_this();
   }
 }
@@ -83,8 +82,8 @@
 void
 Entry::insertPitEntry(shared_ptr<pit::Entry> pitEntry)
 {
-  BOOST_ASSERT(static_cast<bool>(pitEntry));
-  BOOST_ASSERT(!static_cast<bool>(pitEntry->m_nameTreeEntry));
+  BOOST_ASSERT(pitEntry != nullptr);
+  BOOST_ASSERT(pitEntry->m_nameTreeEntry.expired());
 
   m_pitEntries.push_back(pitEntry);
   pitEntry->m_nameTreeEntry = this->shared_from_this();
@@ -93,11 +92,10 @@
 void
 Entry::erasePitEntry(shared_ptr<pit::Entry> pitEntry)
 {
-  BOOST_ASSERT(static_cast<bool>(pitEntry));
-  BOOST_ASSERT(pitEntry->m_nameTreeEntry.get() == this);
+  BOOST_ASSERT(pitEntry != nullptr);
+  BOOST_ASSERT(pitEntry->m_nameTreeEntry.lock().get() == this);
 
-  std::vector<shared_ptr<pit::Entry> >::iterator it =
-    std::find(m_pitEntries.begin(), m_pitEntries.end(), pitEntry);
+  auto it = std::find(m_pitEntries.begin(), m_pitEntries.end(), pitEntry);
   BOOST_ASSERT(it != m_pitEntries.end());
 
   *it = m_pitEntries.back();
@@ -108,15 +106,14 @@
 void
 Entry::setMeasurementsEntry(shared_ptr<measurements::Entry> measurementsEntry)
 {
-  if (static_cast<bool>(measurementsEntry)) {
-    BOOST_ASSERT(!static_cast<bool>(measurementsEntry->m_nameTreeEntry));
-  }
+  BOOST_ASSERT(measurementsEntry == nullptr || measurementsEntry->m_nameTreeEntry.expired());
 
-  if (static_cast<bool>(m_measurementsEntry)) {
+  if (m_measurementsEntry != nullptr) {
     m_measurementsEntry->m_nameTreeEntry.reset();
   }
   m_measurementsEntry = measurementsEntry;
-  if (static_cast<bool>(m_measurementsEntry)) {
+
+  if (m_measurementsEntry != nullptr) {
     m_measurementsEntry->m_nameTreeEntry = this->shared_from_this();
   }
 }
@@ -124,15 +121,14 @@
 void
 Entry::setStrategyChoiceEntry(shared_ptr<strategy_choice::Entry> strategyChoiceEntry)
 {
-  if (static_cast<bool>(strategyChoiceEntry)) {
-    BOOST_ASSERT(!static_cast<bool>(strategyChoiceEntry->m_nameTreeEntry));
-  }
+  BOOST_ASSERT(strategyChoiceEntry == nullptr || strategyChoiceEntry->m_nameTreeEntry.expired());
 
-  if (static_cast<bool>(m_strategyChoiceEntry)) {
+  if (m_strategyChoiceEntry != nullptr) {
     m_strategyChoiceEntry->m_nameTreeEntry.reset();
   }
+
   m_strategyChoiceEntry = strategyChoiceEntry;
-  if (static_cast<bool>(m_strategyChoiceEntry)) {
+  if (m_strategyChoiceEntry != nullptr) {
     m_strategyChoiceEntry->m_nameTreeEntry = this->shared_from_this();
   }
 }
diff --git a/daemon/table/name-tree-entry.hpp b/daemon/table/name-tree-entry.hpp
index d0e3587..378d285 100644
--- a/daemon/table/name-tree-entry.hpp
+++ b/daemon/table/name-tree-entry.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.
@@ -110,7 +110,7 @@
   bool
   hasPitEntries() const;
 
-  const std::vector<shared_ptr<pit::Entry> >&
+  const std::vector<shared_ptr<pit::Entry>>&
   getPitEntries() const;
 
   void
@@ -199,7 +199,7 @@
   return !m_pitEntries.empty();
 }
 
-inline const std::vector<shared_ptr<pit::Entry> >&
+inline const std::vector<shared_ptr<pit::Entry>>&
 Entry::getPitEntries() const
 {
   return m_pitEntries;
diff --git a/daemon/table/name-tree.cpp b/daemon/table/name-tree.cpp
index 8e699c5..87d4154 100644
--- a/daemon/table/name-tree.cpp
+++ b/daemon/table/name-tree.cpp
@@ -240,6 +240,47 @@
   return entry;
 }
 
+shared_ptr<name_tree::Entry>
+NameTree::lookup(const fib::Entry& fibEntry) const
+{
+  shared_ptr<name_tree::Entry> nte = this->getEntry(fibEntry);
+  BOOST_ASSERT(nte == nullptr || nte->getFibEntry().get() == &fibEntry);
+  return nte;
+}
+
+shared_ptr<name_tree::Entry>
+NameTree::lookup(const pit::Entry& pitEntry)
+{
+  shared_ptr<name_tree::Entry> nte = this->getEntry(pitEntry);
+  if (nte == nullptr) {
+    return nullptr;
+  }
+
+  if (nte->getPrefix().size() == pitEntry.getName().size()) {
+    return nte;
+  }
+
+  BOOST_ASSERT(pitEntry.getName().at(-1).isImplicitSha256Digest());
+  BOOST_ASSERT(nte->getPrefix() == pitEntry.getName().getPrefix(-1));
+  return this->lookup(pitEntry.getName());
+}
+
+shared_ptr<name_tree::Entry>
+NameTree::lookup(const measurements::Entry& measurementsEntry) const
+{
+  shared_ptr<name_tree::Entry> nte = this->getEntry(measurementsEntry);
+  BOOST_ASSERT(nte == nullptr || nte->getMeasurementsEntry().get() == &measurementsEntry);
+  return nte;
+}
+
+shared_ptr<name_tree::Entry>
+NameTree::lookup(const strategy_choice::Entry& strategyChoiceEntry) const
+{
+  shared_ptr<name_tree::Entry> nte = this->getEntry(strategyChoiceEntry);
+  BOOST_ASSERT(nte == nullptr || nte->getStrategyChoiceEntry().get() == &strategyChoiceEntry);
+  return nte;
+}
+
 // return {false: this entry is not empty, true: this entry is empty and erased}
 bool
 NameTree::eraseEntryIfEmpty(shared_ptr<name_tree::Entry> entry)
@@ -320,19 +361,6 @@
   return false; // if this entry is not empty
 }
 
-shared_ptr<name_tree::Entry>
-NameTree::get(const pit::Entry& pitEntry)
-{
-  shared_ptr<name_tree::Entry> nte = pitEntry.m_nameTreeEntry;
-  if (nte->getPrefix().size() == pitEntry.getName().size()) {
-    return nte;
-  }
-
-  BOOST_ASSERT(pitEntry.getName().at(-1).isImplicitSha256Digest());
-  BOOST_ASSERT(nte->getPrefix() == pitEntry.getName().getPrefix(-1));
-  return this->lookup(pitEntry.getName());
-}
-
 // Exact Match
 shared_ptr<name_tree::Entry>
 NameTree::findExactMatch(const Name& prefix) const
@@ -420,7 +448,8 @@
 shared_ptr<name_tree::Entry>
 NameTree::findLongestPrefixMatch(const pit::Entry& pitEntry) const
 {
-  shared_ptr<name_tree::Entry> nte = pitEntry.m_nameTreeEntry;
+  shared_ptr<name_tree::Entry> nte = this->getEntry(pitEntry);
+  BOOST_ASSERT(nte != nullptr);
   if (nte->getPrefix().size() == pitEntry.getName().size()) {
     return nte;
   }
diff --git a/daemon/table/name-tree.hpp b/daemon/table/name-tree.hpp
index 15a717b..b047696 100644
--- a/daemon/table/name-tree.hpp
+++ b/daemon/table/name-tree.hpp
@@ -101,6 +101,12 @@
   size_t
   getNBuckets() const;
 
+  /** \return Name Tree Entry on which a table entry is attached
+   */
+  template<typename ENTRY>
+  shared_ptr<name_tree::Entry>
+  getEntry(const ENTRY& tableEntry) const;
+
   /**
    * \brief Dump all the information stored in the Name Tree for debugging.
    */
@@ -121,6 +127,34 @@
   shared_ptr<name_tree::Entry>
   lookup(const Name& prefix);
 
+  /** \brief get NameTree entry from FIB entry
+   *
+   *  This is equivalent to .lookup(fibEntry.getPrefix())
+   */
+  shared_ptr<name_tree::Entry>
+  lookup(const fib::Entry& fibEntry) const;
+
+  /** \brief get NameTree entry from PIT entry
+   *
+   *  This is equivalent to .lookup(pitEntry.getName()).
+   */
+  shared_ptr<name_tree::Entry>
+  lookup(const pit::Entry& pitEntry);
+
+  /** \brief get NameTree entry from Measurements entry
+   *
+   *  This is equivalent to .lookup(measurementsEntry.getName())
+   */
+  shared_ptr<name_tree::Entry>
+  lookup(const measurements::Entry& measurementsEntry) const;
+
+  /** \brief get NameTree entry from StrategyChoice entry
+   *
+   *  This is equivalent to .lookup(strategyChoiceEntry.getName())
+   */
+  shared_ptr<name_tree::Entry>
+  lookup(const strategy_choice::Entry& strategyChoiceEntry) const;
+
   /**
    * \brief Delete a Name Tree Entry if this entry is empty.
    * \param entry The entry to be deleted if empty.
@@ -132,35 +166,6 @@
   bool
   eraseEntryIfEmpty(shared_ptr<name_tree::Entry> entry);
 
-public: // shortcut access
-  /** \brief get NameTree entry from FIB entry
-   *
-   *  This is equivalent to .lookup(fibEntry.getPrefix())
-   */
-  shared_ptr<name_tree::Entry>
-  get(const fib::Entry& fibEntry) const;
-
-  /** \brief get NameTree entry from PIT entry
-   *
-   *  This is equivalent to .lookup(pitEntry.getName()).
-   */
-  shared_ptr<name_tree::Entry>
-  get(const pit::Entry& pitEntry);
-
-  /** \brief get NameTree entry from Measurements entry
-   *
-   *  This is equivalent to .lookup(measurementsEntry.getName())
-   */
-  shared_ptr<name_tree::Entry>
-  get(const measurements::Entry& measurementsEntry) const;
-
-  /** \brief get NameTree entry from StrategyChoice entry
-   *
-   *  This is equivalent to .lookup(strategyChoiceEntry.getName())
-   */
-  shared_ptr<name_tree::Entry>
-  get(const strategy_choice::Entry& strategyChoiceEntry) const;
-
 public: // matching
   /**
    * \brief Exact match lookup for the given name prefix.
@@ -312,6 +317,17 @@
 
 private:
   /**
+   * \brief Create a Name Tree Entry if it does not exist, or return the existing
+   * Name Tree Entry address.
+   * \details Called by lookup() only.
+   * \return The first item is the Name Tree Entry address, the second item is
+   * a bool value indicates whether this is an old entry (false) or a new
+   * entry (true).
+   */
+  std::pair<shared_ptr<name_tree::Entry>, bool>
+  insert(const Name& prefix);
+
+  /**
    * \brief Resize the hash table size when its load factor reaches a threshold.
    * \details As we are currently using a hand-written hash table implementation
    * for the Name Tree, the hash table resize() function should be kept in the
@@ -334,17 +350,6 @@
   name_tree::Node**             m_buckets; // Name Tree Buckets in the NPHT
   shared_ptr<name_tree::Entry>  m_end;
   const_iterator                m_endIterator;
-
-  /**
-   * \brief Create a Name Tree Entry if it does not exist, or return the existing
-   * Name Tree Entry address.
-   * \details Called by lookup() only.
-   * \return The first item is the Name Tree Entry address, the second item is
-   * a bool value indicates whether this is an old entry (false) or a new
-   * entry (true).
-   */
-  std::pair<shared_ptr<name_tree::Entry>, bool>
-  insert(const Name& prefix);
 };
 
 inline NameTree::const_iterator::~const_iterator()
@@ -363,22 +368,11 @@
   return m_nBuckets;
 }
 
+template<typename ENTRY>
 inline shared_ptr<name_tree::Entry>
-NameTree::get(const fib::Entry& fibEntry) const
+NameTree::getEntry(const ENTRY& tableEntry) const
 {
-  return fibEntry.m_nameTreeEntry;
-}
-
-inline shared_ptr<name_tree::Entry>
-NameTree::get(const measurements::Entry& measurementsEntry) const
-{
-  return measurementsEntry.m_nameTreeEntry;
-}
-
-inline shared_ptr<name_tree::Entry>
-NameTree::get(const strategy_choice::Entry& strategyChoiceEntry) const
-{
-  return strategyChoiceEntry.m_nameTreeEntry;
+  return tableEntry.m_nameTreeEntry.lock();
 }
 
 inline NameTree::const_iterator
diff --git a/daemon/table/pit-entry.hpp b/daemon/table/pit-entry.hpp
index e432c4e..282d1df 100644
--- a/daemon/table/pit-entry.hpp
+++ b/daemon/table/pit-entry.hpp
@@ -38,8 +38,6 @@
 class Entry;
 } // namespace name_tree
 
-class Pit;
-
 namespace pit {
 
 /** \brief an unordered collection of in-records
@@ -196,11 +194,10 @@
   InRecordCollection m_inRecords;
   OutRecordCollection m_outRecords;
 
-  shared_ptr<name_tree::Entry> m_nameTreeEntry;
+  weak_ptr<name_tree::Entry> m_nameTreeEntry;
 
   friend class nfd::NameTree;
   friend class nfd::name_tree::Entry;
-  friend class nfd::Pit;
 };
 
 inline const Interest&
diff --git a/daemon/table/pit.cpp b/daemon/table/pit.cpp
index ae5a5cd..7286cbe 100644
--- a/daemon/table/pit.cpp
+++ b/daemon/table/pit.cpp
@@ -113,8 +113,8 @@
 void
 Pit::erase(shared_ptr<pit::Entry> pitEntry)
 {
-  shared_ptr<name_tree::Entry> nameTreeEntry = pitEntry->m_nameTreeEntry;
-  BOOST_ASSERT(static_cast<bool>(nameTreeEntry));
+  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.getEntry(*pitEntry);
+  BOOST_ASSERT(nameTreeEntry != nullptr);
 
   nameTreeEntry->erasePitEntry(pitEntry);
   m_nameTree.eraseEntryIfEmpty(nameTreeEntry);
diff --git a/daemon/table/strategy-choice-entry.hpp b/daemon/table/strategy-choice-entry.hpp
index 857a313..9261039 100644
--- a/daemon/table/strategy-choice-entry.hpp
+++ b/daemon/table/strategy-choice-entry.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.
@@ -21,7 +21,7 @@
  *
  * You should have received a copy of the GNU General Public License along with
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
 
 #ifndef NFD_DAEMON_TABLE_STRATEGY_CHOICE_ENTRY_HPP
 #define NFD_DAEMON_TABLE_STRATEGY_CHOICE_ENTRY_HPP
@@ -33,10 +33,10 @@
 class NameTree;
 namespace name_tree {
 class Entry;
-}
+} // namespace name_tree
 namespace fw {
 class Strategy;
-}
+} // namespace fw
 
 namespace strategy_choice {
 
@@ -63,7 +63,7 @@
   Name m_prefix;
   fw::Strategy* m_strategy;
 
-  shared_ptr<name_tree::Entry> m_nameTreeEntry;
+  weak_ptr<name_tree::Entry> m_nameTreeEntry;
   friend class nfd::NameTree;
   friend class nfd::name_tree::Entry;
 };
diff --git a/daemon/table/strategy-choice.cpp b/daemon/table/strategy-choice.cpp
index 85aade6..de7cb13 100644
--- a/daemon/table/strategy-choice.cpp
+++ b/daemon/table/strategy-choice.cpp
@@ -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.
@@ -50,14 +50,14 @@
     return m_strategyInstances.count(strategyName) > 0;
   }
   else {
-    return static_cast<bool>(this->getStrategy(strategyName));
+    return this->getStrategy(strategyName) != nullptr;
   }
 }
 
 bool
 StrategyChoice::install(shared_ptr<Strategy> strategy)
 {
-  BOOST_ASSERT(static_cast<bool>(strategy));
+  BOOST_ASSERT(strategy != nullptr);
   const Name& strategyName = strategy->getName();
 
   if (this->hasStrategy(strategyName, true)) {
@@ -98,7 +98,7 @@
   shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(prefix);
   shared_ptr<Entry> entry = nte->getStrategyChoiceEntry();
   Strategy* oldStrategy = nullptr;
-  if (static_cast<bool>(entry)) {
+  if (entry != nullptr) {
     if (entry->getStrategy().getName() == strategy->getName()) {
       NFD_LOG_TRACE("insert(" << prefix << ") not changing " << strategy->getName());
       return true;
@@ -108,7 +108,7 @@
                   " to " << strategy->getName());
   }
 
-  if (!static_cast<bool>(entry)) {
+  if (entry == nullptr) {
     oldStrategy = &this->findEffectiveStrategy(prefix);
     entry = make_shared<Entry>(prefix);
     nte->setStrategyChoiceEntry(entry);
@@ -127,12 +127,12 @@
   BOOST_ASSERT(prefix.size() > 0);
 
   shared_ptr<name_tree::Entry> nte = m_nameTree.findExactMatch(prefix);
-  if (!static_cast<bool>(nte)) {
+  if (nte == nullptr) {
     return;
   }
 
   shared_ptr<Entry> entry = nte->getStrategyChoiceEntry();
-  if (!static_cast<bool>(entry)) {
+  if (entry == nullptr) {
     return;
   }
 
@@ -150,12 +150,12 @@
 StrategyChoice::get(const Name& prefix) const
 {
   shared_ptr<name_tree::Entry> nte = m_nameTree.findExactMatch(prefix);
-  if (!static_cast<bool>(nte)) {
+  if (nte == nullptr) {
     return { false, Name() };
   }
 
   shared_ptr<Entry> entry = nte->getStrategyChoiceEntry();
-  if (!static_cast<bool>(entry)) {
+  if (entry == nullptr) {
     return { false, Name() };
   }
 
@@ -167,10 +167,10 @@
 {
   shared_ptr<name_tree::Entry> nte = m_nameTree.findLongestPrefixMatch(prefix,
     [] (const name_tree::Entry& entry) {
-      return static_cast<bool>(entry.getStrategyChoiceEntry());
+      return entry.getStrategyChoiceEntry() != nullptr;
     });
 
-  BOOST_ASSERT(static_cast<bool>(nte));
+  BOOST_ASSERT(nte != nullptr);
   return nte->getStrategyChoiceEntry()->getStrategy();
 }
 
@@ -178,33 +178,33 @@
 StrategyChoice::findEffectiveStrategy(shared_ptr<name_tree::Entry> nte) const
 {
   shared_ptr<strategy_choice::Entry> entry = nte->getStrategyChoiceEntry();
-  if (static_cast<bool>(entry))
+  if (entry != nullptr)
     return entry->getStrategy();
 
   nte = m_nameTree.findLongestPrefixMatch(nte,
     [] (const name_tree::Entry& entry) {
-      return static_cast<bool>(entry.getStrategyChoiceEntry());
+      return entry.getStrategyChoiceEntry() != nullptr;
     });
 
-  BOOST_ASSERT(static_cast<bool>(nte));
+  BOOST_ASSERT(nte != nullptr);
   return nte->getStrategyChoiceEntry()->getStrategy();
 }
 
 Strategy&
 StrategyChoice::findEffectiveStrategy(const pit::Entry& pitEntry) const
 {
-  shared_ptr<name_tree::Entry> nte = m_nameTree.get(pitEntry);
+  shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(pitEntry);
+  BOOST_ASSERT(nte != nullptr);
 
-  BOOST_ASSERT(static_cast<bool>(nte));
   return this->findEffectiveStrategy(nte);
 }
 
 Strategy&
 StrategyChoice::findEffectiveStrategy(const measurements::Entry& measurementsEntry) const
 {
-  shared_ptr<name_tree::Entry> nte = m_nameTree.get(measurementsEntry);
+  shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(measurementsEntry);
+  BOOST_ASSERT(nte != nullptr);
 
-  BOOST_ASSERT(static_cast<bool>(nte));
   return this->findEffectiveStrategy(nte);
 }
 
@@ -238,7 +238,7 @@
       const_cast<pit::OutRecord&>(outRecord).clearStrategyInfo();
     }
   }
-  if (static_cast<bool>(nte.getMeasurementsEntry())) {
+  if (nte.getMeasurementsEntry() != nullptr) {
     nte.getMeasurementsEntry()->clearStrategyInfo();
   }
 }
@@ -258,13 +258,13 @@
 
   // reset StrategyInfo on a portion of NameTree,
   // where entry's effective strategy is covered by the changing StrategyChoice entry
-  const name_tree::Entry* rootNte = m_nameTree.get(entry).get();
+  const name_tree::Entry* rootNte = m_nameTree.lookup(entry).get();
   auto&& ntChanged = m_nameTree.partialEnumerate(entry.getPrefix(),
     [&rootNte] (const name_tree::Entry& nte) -> std::pair<bool, bool> {
       if (&nte == rootNte) {
         return {true, true};
       }
-      if (static_cast<bool>(nte.getStrategyChoiceEntry())) {
+      if (nte.getStrategyChoiceEntry() != nullptr) {
         return {false, false};
       }
       return {true, true};
@@ -279,7 +279,7 @@
 {
   auto&& enumerable = m_nameTree.fullEnumerate(
     [] (const name_tree::Entry& entry) {
-      return static_cast<bool>(entry.getStrategyChoiceEntry());
+      return entry.getStrategyChoiceEntry() != nullptr;
     });
   return const_iterator(enumerable.begin());
 }