lsdb: rebuild using boost::multi_index to replace 3 LSA lists

refs: #4127

Co-authored-by: Nick Gordon <nmgordon@memphis.edu>

Change-Id: Ic179f90019e472157b0d61c6db02a4afaf4843b6
diff --git a/src/lsa/adj-lsa.cpp b/src/lsa/adj-lsa.cpp
index e7dbf95..f3b04da 100644
--- a/src/lsa/adj-lsa.cpp
+++ b/src/lsa/adj-lsa.cpp
@@ -24,7 +24,7 @@
 
 namespace nlsr {
 
-AdjLsa::AdjLsa(const ndn::Name& originRouter, uint32_t seqNo,
+AdjLsa::AdjLsa(const ndn::Name& originRouter, uint64_t seqNo,
                const ndn::time::system_clock::TimePoint& timepoint,
                uint32_t noLink, AdjacencyList& adl)
   : Lsa(originRouter, seqNo, timepoint)
@@ -72,7 +72,7 @@
 const ndn::Block&
 AdjLsa::wireEncode() const
 {
-  if (m_wire.hasWire() && m_baseWire.hasWire()) {
+  if (m_wire.hasWire()) {
     return m_wire;
   }
 
@@ -99,7 +99,7 @@
 
   m_wire.parse();
 
-  ndn::Block::element_const_iterator val = m_wire.elements_begin();
+  auto val = m_wire.elements_begin();
 
   if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Lsa) {
     Lsa::wireDecode(*val);
@@ -123,22 +123,29 @@
   m_adl = adl;
 }
 
-std::ostream&
-operator<<(std::ostream& os, const AdjLsa& lsa)
+std::string
+AdjLsa::toString() const
 {
-  os << lsa.toString();
-  os << "      Adjacents:\n";
+  std::ostringstream os;
+  os << Lsa::toString();
+  os << "      Adjacent(s):\n";
 
   int adjacencyIndex = 0;
 
-  for (const Adjacent& adjacency : lsa.getAdl()) {
-  os << "        Adjacent " << adjacencyIndex++
-     << ": (name=" << adjacency.getName()
-     << ", uri="   << adjacency.getFaceUri()
-     << ", cost="  << adjacency.getLinkCost() << ")\n";
+  for (const auto& adjacency : m_adl) {
+    os << "        Adjacent " << adjacencyIndex++
+       << ": (name=" << adjacency.getName()
+       << ", uri="   << adjacency.getFaceUri()
+       << ", cost="  << adjacency.getLinkCost() << ")\n";
   }
 
-  return os;
+  return os.str();
+}
+
+std::ostream&
+operator<<(std::ostream& os, const AdjLsa& lsa)
+{
+  return os << lsa.toString();
 }
 
 } // namespace nlsr
diff --git a/src/lsa/adj-lsa.hpp b/src/lsa/adj-lsa.hpp
index 12e9346..9857cc8 100644
--- a/src/lsa/adj-lsa.hpp
+++ b/src/lsa/adj-lsa.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
@@ -17,7 +17,7 @@
  *
  * You should have received a copy of the GNU General Public License along with
  * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
 
 #ifndef NLSR_LSA_ADJ_LSA_HPP
 #define NLSR_LSA_ADJ_LSA_HPP
@@ -41,7 +41,7 @@
 
   AdjLsa() = default;
 
-  AdjLsa(const ndn::Name& originR, uint32_t seqNo,
+  AdjLsa(const ndn::Name& originR, uint64_t seqNo,
          const ndn::time::system_clock::TimePoint& timepoint,
          uint32_t noLink, AdjacencyList& adl);
 
@@ -50,6 +50,12 @@
   Lsa::Type
   getType() const override
   {
+    return type();
+  }
+
+  static constexpr Lsa::Type
+  type()
+  {
     return Lsa::Type::ADJACENCY;
   }
 
@@ -99,18 +105,19 @@
   wireEncode(ndn::EncodingImpl<TAG>& block) const;
 
   const ndn::Block&
-  wireEncode() const;
+  wireEncode() const override;
 
   void
   wireDecode(const ndn::Block& wire);
 
+  std::string
+  toString() const override;
+
 private:
   uint32_t m_noLink;
 
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   AdjacencyList m_adl;
-
-  mutable ndn::Block m_wire;
 };
 
 NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(AdjLsa);
diff --git a/src/lsa/coordinate-lsa.cpp b/src/lsa/coordinate-lsa.cpp
index b195e39..4109c64 100644
--- a/src/lsa/coordinate-lsa.cpp
+++ b/src/lsa/coordinate-lsa.cpp
@@ -26,7 +26,7 @@
 
 namespace nlsr {
 
-CoordinateLsa::CoordinateLsa(const ndn::Name& originRouter, uint32_t seqNo,
+CoordinateLsa::CoordinateLsa(const ndn::Name& originRouter, uint64_t seqNo,
                              const ndn::time::system_clock::TimePoint& timepoint,
                              double radius, std::vector<double> angles)
   : Lsa(originRouter, seqNo, timepoint)
@@ -84,7 +84,7 @@
 const ndn::Block&
 CoordinateLsa::wireEncode() const
 {
-  if (m_wire.hasWire() && m_baseWire.hasWire()) {
+  if (m_wire.hasWire()) {
     return m_wire;
   }
 
@@ -113,7 +113,7 @@
 
   m_wire.parse();
 
-  ndn::Block::element_const_iterator val = m_wire.elements_begin();
+  auto val = m_wire.elements_begin();
 
   if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Lsa) {
     Lsa::wireDecode(*val);
@@ -143,17 +143,24 @@
   m_hyperbolicAngles = angles;
 }
 
-std::ostream&
-operator<<(std::ostream& os, const CoordinateLsa& lsa)
+std::string
+CoordinateLsa::toString() const
 {
-  os << lsa.toString();
-  os << "      Hyperbolic Radius  : " << lsa.getCorRadius() << "\n";
+  std::ostringstream os;
+  os << Lsa::toString();
+  os << "      Hyperbolic Radius  : " << m_hyperbolicRadius << "\n";
   int i = 0;
-  for (const auto& value : lsa.getCorTheta()) {
+  for (const auto& value : m_hyperbolicAngles) {
     os << "      Hyperbolic Theta " << i++ << " : " << value << "\n";
   }
 
-  return os;
+  return os.str();
+}
+
+std::ostream&
+operator<<(std::ostream& os, const CoordinateLsa& lsa)
+{
+  return os << lsa.toString();
 }
 
 } // namespace nlsr
diff --git a/src/lsa/coordinate-lsa.hpp b/src/lsa/coordinate-lsa.hpp
index abeea2c..4b07627 100644
--- a/src/lsa/coordinate-lsa.hpp
+++ b/src/lsa/coordinate-lsa.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
@@ -17,7 +17,7 @@
  *
  * You should have received a copy of the GNU General Public License along with
  * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
 
 #ifndef NLSR_LSA_COORDINATE_LSA_HPP
 #define NLSR_LSA_COORDINATE_LSA_HPP
@@ -38,7 +38,7 @@
 public:
   CoordinateLsa() = default;
 
-  CoordinateLsa(const ndn::Name& originRouter, uint32_t seqNo,
+  CoordinateLsa(const ndn::Name& originRouter, uint64_t seqNo,
                 const ndn::time::system_clock::TimePoint& timepoint,
                 double radius, std::vector<double> angles);
 
@@ -47,6 +47,12 @@
   Lsa::Type
   getType() const override
   {
+    return type();
+  }
+
+  static constexpr Lsa::Type
+  type()
+  {
     return Lsa::Type::COORDINATE;
   }
 
@@ -84,16 +90,17 @@
   wireEncode(ndn::EncodingImpl<TAG>& block) const;
 
   const ndn::Block&
-  wireEncode() const;
+  wireEncode() const override;
 
   void
   wireDecode(const ndn::Block& wire);
 
+  std::string
+  toString() const override;
+
 private:
   double m_hyperbolicRadius = 0.0;
   std::vector<double> m_hyperbolicAngles;
-
-  mutable ndn::Block m_wire;
 };
 
 NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(CoordinateLsa);
diff --git a/src/lsa/lsa.cpp b/src/lsa/lsa.cpp
index 73ddbe7..dd8267e 100644
--- a/src/lsa/lsa.cpp
+++ b/src/lsa/lsa.cpp
@@ -27,7 +27,7 @@
 
 namespace nlsr {
 
-Lsa::Lsa(const ndn::Name& originRouter, uint32_t seqNo,
+Lsa::Lsa(const ndn::Name& originRouter, uint64_t seqNo,
          ndn::time::system_clock::TimePoint expirationTimePoint)
   : m_originRouter(originRouter)
   , m_seqNo(seqNo)
@@ -35,12 +35,6 @@
 {
 }
 
-ndn::Name
-Lsa::getKey() const
-{
-  return ndn::Name(m_originRouter).append(boost::lexical_cast<std::string>((getType())));
-}
-
 template<ndn::encoding::Tag TAG>
 size_t
 Lsa::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
@@ -70,20 +64,12 @@
   m_originRouter.clear();
   m_seqNo = 0;
 
-  m_baseWire = wire;
+  ndn::Block baseWire = wire;
+  baseWire.parse();
 
-  if (m_baseWire.type() != ndn::tlv::nlsr::Lsa) {
-    std::stringstream error;
-    error << "Expected Lsa Block, but Block is of a different type: #"
-          << m_baseWire.type();
-    BOOST_THROW_EXCEPTION(Error(error.str()));
-  }
+  auto val = baseWire.elements_begin();
 
-  m_baseWire.parse();
-
-  ndn::Block::element_const_iterator val = m_baseWire.elements_begin();
-
-  if (val != m_baseWire.elements_end() && val->type() == ndn::tlv::Name) {
+  if (val != baseWire.elements_end() && val->type() == ndn::tlv::Name) {
     m_originRouter.wireDecode(*val);
   }
   else {
@@ -92,7 +78,7 @@
 
   ++val;
 
-  if (val != m_baseWire.elements_end() && val->type() == ndn::tlv::nlsr::SequenceNumber) {
+  if (val != baseWire.elements_end() && val->type() == ndn::tlv::nlsr::SequenceNumber) {
     m_seqNo = ndn::readNonNegativeInteger(*val);
     ++val;
   }
@@ -100,7 +86,7 @@
     BOOST_THROW_EXCEPTION(Error("Missing required SequenceNumber field"));
   }
 
-  if (val != m_baseWire.elements_end() && val->type() == ndn::tlv::nlsr::ExpirationTime) {
+  if (val != baseWire.elements_end() && val->type() == ndn::tlv::nlsr::ExpirationTime) {
     m_expirationTimePoint = ndn::time::fromString(readString(*val));
   }
   else {
diff --git a/src/lsa/lsa.hpp b/src/lsa/lsa.hpp
index 1bd4382..a44a594 100644
--- a/src/lsa/lsa.hpp
+++ b/src/lsa/lsa.hpp
@@ -60,7 +60,7 @@
   };
 
 protected:
-  Lsa(const ndn::Name& originRouter, uint32_t seqNo,
+  Lsa(const ndn::Name& originRouter, uint64_t seqNo,
       ndn::time::system_clock::TimePoint expirationTimePoint);
 
   Lsa() = default;
@@ -70,16 +70,13 @@
   ~Lsa() = default;
 
   virtual Type
-  getType() const
-  {
-    return Type::BASE;
-  }
+  getType() const = 0;
 
   void
   setSeqNo(uint64_t seqNo)
   {
     m_seqNo = seqNo;
-    m_baseWire.reset();
+    m_wire.reset();
   }
 
   uint64_t
@@ -94,6 +91,12 @@
     return m_originRouter;
   }
 
+  ndn::Name
+  getOriginRouterCopy() const
+  {
+    return m_originRouter;
+  }
+
   const ndn::time::system_clock::TimePoint&
   getExpirationTimePoint() const
   {
@@ -104,7 +107,7 @@
   setExpirationTimePoint(const ndn::time::system_clock::TimePoint& lt)
   {
     m_expirationTimePoint = lt;
-    m_baseWire.reset();
+    m_wire.reset();
   }
 
   void
@@ -119,18 +122,15 @@
     return m_expiringEventId;
   }
 
-  /*! \brief Gets the key for this LSA.
-
-    Format is: \<router name\>/\<LSA type>\
-   */
-  ndn::Name
-  getKey() const;
-
   /*! Get data common to all LSA types.
    */
-  std::string
+  virtual std::string
   toString() const;
 
+  virtual const ndn::Block&
+  wireEncode() const = 0;
+
+protected:
   template<ndn::encoding::Tag TAG>
   size_t
   wireEncode(ndn::EncodingImpl<TAG>& block) const;
@@ -144,7 +144,7 @@
   ndn::time::system_clock::TimePoint m_expirationTimePoint;
   ndn::scheduler::EventId m_expiringEventId;
 
-  mutable ndn::Block m_baseWire;
+  mutable ndn::Block m_wire;
 };
 
 NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Lsa);
diff --git a/src/lsa/name-lsa.cpp b/src/lsa/name-lsa.cpp
index f73014b..cfdfd77 100644
--- a/src/lsa/name-lsa.cpp
+++ b/src/lsa/name-lsa.cpp
@@ -24,9 +24,9 @@
 
 namespace nlsr {
 
-NameLsa::NameLsa(const ndn::Name& originRouter, uint32_t seqNo,
+NameLsa::NameLsa(const ndn::Name& originRouter, uint64_t seqNo,
                  const ndn::time::system_clock::TimePoint& timepoint,
-                 NamePrefixList& npl)
+                 const NamePrefixList& npl)
   : Lsa(originRouter, seqNo, timepoint)
 {
   for (const auto& name : npl.getNames()) {
@@ -64,7 +64,7 @@
 const ndn::Block&
 NameLsa::wireEncode() const
 {
-  if (m_wire.hasWire() && m_baseWire.hasWire()) {
+  if (m_wire.hasWire()) {
     return m_wire;
   }
 
@@ -91,7 +91,7 @@
 
   m_wire.parse();
 
-  ndn::Block::element_const_iterator val = m_wire.elements_begin();
+  auto val = m_wire.elements_begin();
 
   if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Lsa) {
     Lsa::wireDecode(*val);
@@ -121,18 +121,24 @@
   return m_npl == other.getNpl();
 }
 
-std::ostream&
-operator<<(std::ostream& os, const NameLsa& lsa)
+std::string
+NameLsa::toString() const
 {
-  os << lsa.toString();
+  std::ostringstream os;
+  os << Lsa::toString();
   os << "      Names:\n";
   int i = 0;
-  auto names = lsa.getNpl().getNames();
-  for (const auto& name : names) {
+  for (const auto& name : m_npl.getNames()) {
     os << "        Name " << i++ << ": " << name << "\n";
   }
 
-  return os;
+  return os.str();
+}
+
+std::ostream&
+operator<<(std::ostream& os, const NameLsa& lsa)
+{
+  return os << lsa.toString();
 }
 
 } // namespace nlsr
diff --git a/src/lsa/name-lsa.hpp b/src/lsa/name-lsa.hpp
index 3223839..5e9c8d5 100644
--- a/src/lsa/name-lsa.hpp
+++ b/src/lsa/name-lsa.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
@@ -17,7 +17,7 @@
  *
  * You should have received a copy of the GNU General Public License along with
  * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
 
 #ifndef NLSR_LSA_NAME_LSA_HPP
 #define NLSR_LSA_NAME_LSA_HPP
@@ -37,15 +37,21 @@
 public:
   NameLsa() = default;
 
-  NameLsa(const ndn::Name& originRouter, uint32_t seqNo,
+  NameLsa(const ndn::Name& originRouter, uint64_t seqNo,
           const ndn::time::system_clock::TimePoint& timepoint,
-          NamePrefixList& npl);
+          const NamePrefixList& npl);
 
   NameLsa(const ndn::Block& block);
 
   Lsa::Type
   getType() const override
   {
+    return type();
+  }
+
+  static constexpr Lsa::Type
+  type()
+  {
     return Lsa::Type::NAME;
   }
 
@@ -83,14 +89,16 @@
   wireEncode(ndn::EncodingImpl<TAG>& block) const;
 
   const ndn::Block&
-  wireEncode() const;
+  wireEncode() const override;
 
   void
   wireDecode(const ndn::Block& wire);
 
+  std::string
+  toString() const override;
+
 private:
   NamePrefixList m_npl;
-  mutable ndn::Block m_wire;
 };
 
 NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(NameLsa);