Name prefix table entries keep pointers instead of keeping a copy of the object for routing table entries.

refs: #2863

Change-Id: I3271c9f96dfc8721a0ca7c900542c6ddb0b321ac
diff --git a/src/route/name-prefix-table.hpp b/src/route/name-prefix-table.hpp
index d8a3bc1..3443d7e 100644
--- a/src/route/name-prefix-table.hpp
+++ b/src/route/name-prefix-table.hpp
@@ -23,9 +23,12 @@
 #define NLSR_NAME_PREFIX_TABLE_HPP
 
 #include "name-prefix-table-entry.hpp"
-#include "routing-table-entry.hpp"
+#include "routing-table-pool-entry.hpp"
+
+#include "test-access-control.hpp"
 
 #include <list>
+#include <unordered_map>
 
 namespace nlsr {
 class Nlsr;
@@ -37,34 +40,78 @@
   typedef std::list<NamePrefixTableEntry> NptEntryList;
   typedef NptEntryList::const_iterator const_iterator;
 
+  typedef std::unordered_map<ndn::Name, std::shared_ptr<RoutingTablePoolEntry>>
+           RtpEntryMap;
+
   NamePrefixTable(Nlsr& nlsr)
     : m_nlsr(nlsr)
   {
   }
 
-  /*! \brief Adds an entry to the NPT.
-    \param name The name prefix that is being advertised.
-    \param destRouter The destination router that is advertising the prefix.
+  /*! \brief Adds a destination to the specified name prefix.
+    \param name The name prefix
+    \param destRouter The destination router prefix
 
-    Adds a destination router to the name prefix. If there isn't
-    currently an entry present for the prefix, one is made and
-    added. If there is no routing table entry available for the
-    destination router, a placeholder routing table entry without next
-    hops will be made. Since this function can be called when a
-    routing table entry has been updated to have no hops (i.e. is
-    unreachable), this function will check for the number of next hops
-    an entry has. If it is found to have no next hops, the NPT will
-    inform the FIB to remove that prefix.
-  */
+    This method adds a router to a name prefix table entry. If the
+    name prefix table entry does not exist, it is created. The method
+    will first look through its local pool of cached entries to find
+    the routing information for destRouter. If it is not found there,
+    it will construct one and fill it with information from an
+    appropriate RoutingTableEntry in the routing table. If there isn't
+    a match, it will instantiate it with no next hops. The FIB will be
+    notified of the change to the NPT entry, too.
+   */
   void
   addEntry(const ndn::Name& name, const ndn::Name& destRouter);
 
+  /*! \brief Removes a destination from a name prefix table entry.
+    \param name The name prefix
+    \param destRouter The destination.
+
+    This method removes a destination from an entry. It will not fail
+    if an invalid name/destination pair are passed. After removal, if
+    the RoutingTablePoolEntry has a use count of 0, it is deleted from
+    the table. Additionally, if the name prefix has no routing table
+    entries associated with it, it is deleted from the NPT. In any
+    case, the FIB is informed of the changes.
+   */
   void
   removeEntry(const ndn::Name& name, const ndn::Name& destRouter);
 
+  /*! \brief Updates all routing information in the NPT.
+
+    Naively iterates over all the NPT entries, then over each of their
+    RoutingTablePoolEntries, passing the name/destination pair back to
+    addEntry after updating the pool entry with new information. This
+    ensures that the FIB is appropriately apprised of any changes to a
+    prefix's preferred next hops.
+   */
   void
   updateWithNewRoute();
 
+  /*! \brief Adds a pool entry to the pool.
+    \param rtpe The entry.
+
+    \return A shared_ptr to the entry, now in the pool.
+
+    Adds a RoutingTablePoolEntry to the NPT's local pool. Shared
+    pointers are used because it eliminates complicated hacks to deal
+    with lifetime issues, and to simplify memory management.
+   */
+  std::shared_ptr<RoutingTablePoolEntry>
+  addRtpeToPool(RoutingTablePoolEntry& rtpe);
+
+  /*! \brief Removes a pool entry from the pool.
+    \param rtpePtr The shared_ptr to the entry.
+
+    Removes a pool entry from the pool. Comparing these shared_ptrs
+    should not be a problem, because the same pointer is moved around,
+    all sourced from this central location. A more robust solution is
+    certainly possible, though.
+  */
+  void
+  deleteRtpeFromPool(std::shared_ptr<RoutingTablePoolEntry> rtpePtr);
+
   void
   writeLog();
 
@@ -74,21 +121,13 @@
   const_iterator
   end() const;
 
-private:
-  /*! \brief Adds an entry to the NPT table.
-    \param name The name prefix to add to the table.
-    \param rte The routing table entry with the next hop information to
-    reach the prefix.
-  */
-  void
-  addEntry(const ndn::Name& name, RoutingTableEntry& rte);
-
-  void
-  removeEntry(const ndn::Name& name, RoutingTableEntry& rte);
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  RtpEntryMap m_rtpool;
+  NptEntryList m_table;
 
 private:
   Nlsr& m_nlsr;
-  std::list<NamePrefixTableEntry> m_table;
+
 };
 
 inline NamePrefixTable::const_iterator
@@ -103,6 +142,9 @@
   return m_table.end();
 }
 
+bool
+npteCompare(NamePrefixTableEntry& npte, const ndn::Name& name);
+
 std::ostream&
 operator<<(std::ostream& os, const NamePrefixTable& table);