replace hash2prefix/prefix2hash with boost::bimap

refs: #5065

Change-Id: I32f690f0a85d5129c56ac2cfda382facbdaaaa49
diff --git a/PSync/full-producer.cpp b/PSync/full-producer.cpp
index 583f88e..ef0770a 100644
--- a/PSync/full-producer.cpp
+++ b/PSync/full-producer.cpp
@@ -198,10 +198,14 @@
 
   State state;
   for (const auto& hash : positive) {
-    const ndn::Name& prefix = m_hash2prefix[hash];
-    // Don't sync up sequence number zero
-    if (m_prefixes[prefix] != 0 && !isFutureHash(prefix.toUri(), negative)) {
-      state.addContent(ndn::Name(prefix).appendNumber(m_prefixes[prefix]));
+    auto nameIt = m_biMap.left.find(hash);
+    if (nameIt != m_biMap.left.end()) {
+      ndn::Name nameWithoutSeq = nameIt->second.getPrefix(-1);
+      // Don't sync up sequence number zero
+      if (m_prefixes[nameWithoutSeq] != 0 &&
+          !isFutureHash(nameWithoutSeq.toUri(), negative)) {
+        state.addContent(nameIt->second);
+      }
     }
   }
 
@@ -276,7 +280,7 @@
   NDN_LOG_DEBUG("Sync Data Received: " << state);
 
   for (const auto& content : state.getContent()) {
-    const ndn::Name& prefix = content.getPrefix(-1);
+    ndn::Name prefix = content.getPrefix(-1);
     uint64_t seq = content.get(content.size() - 1).toNumber();
 
     if (m_prefixes.find(prefix) == m_prefixes.end() || m_prefixes[prefix] < seq) {
@@ -324,10 +328,11 @@
 
     State state;
     for (const auto& hash : positive) {
-      ndn::Name prefix = m_hash2prefix[hash];
-
-      if (m_prefixes[prefix] != 0) {
-        state.addContent(ndn::Name(prefix).appendNumber(m_prefixes[prefix]));
+      auto nameIt = m_biMap.left.find(hash);
+      if (nameIt != m_biMap.left.end()) {
+        if (m_prefixes[nameIt->second.getPrefix(-1)] != 0) {
+          state.addContent(nameIt->second);
+        }
       }
     }
 
diff --git a/PSync/partial-producer.cpp b/PSync/partial-producer.cpp
index 513ed34..b3cd3ea 100644
--- a/PSync/partial-producer.cpp
+++ b/PSync/partial-producer.cpp
@@ -173,11 +173,13 @@
   NDN_LOG_TRACE("Size of positive set " << positive.size());
   NDN_LOG_TRACE("Size of negative set " << negative.size());
   for (const auto& hash : positive) {
-    ndn::Name prefix = m_hash2prefix[hash];
-    if (bf.contains(prefix.toUri())) {
-      // generate data
-      state.addContent(ndn::Name(prefix).appendNumber(m_prefixes[prefix]));
-      NDN_LOG_DEBUG("Content: " << prefix << " " << std::to_string(m_prefixes[prefix]));
+    auto nameIt = m_biMap.left.find(hash);
+    if (nameIt != m_biMap.left.end()) {
+      if (bf.contains(nameIt->second.getPrefix(-1).toUri())) {
+        // generate data
+        state.addContent(nameIt->second);
+        NDN_LOG_DEBUG("Content: " << nameIt->second << " " << nameIt->first);
+      }
     }
   }
 
diff --git a/PSync/producer-base.cpp b/PSync/producer-base.cpp
index 48e1a89..d33e6d8 100644
--- a/PSync/producer-base.cpp
+++ b/PSync/producer-base.cpp
@@ -74,12 +74,10 @@
     m_prefixes.erase(it);
 
     ndn::Name prefixWithSeq = ndn::Name(prefix).appendNumber(seqNo);
-    auto hashIt = m_prefix2hash.find(prefixWithSeq);
-    if (hashIt != m_prefix2hash.end()) {
-      uint32_t hash = hashIt->second;
-      m_prefix2hash.erase(hashIt);
-      m_hash2prefix.erase(hash);
-      m_iblt.erase(hash);
+    auto hashIt = m_biMap.right.find(prefixWithSeq);
+    if (hashIt != m_biMap.right.end()) {
+      m_iblt.erase(hashIt->second);
+      m_biMap.right.erase(hashIt);
     }
   }
 }
@@ -108,21 +106,18 @@
   // Because we don't insert zeroth prefix in IBF so no need to delete that
   if (oldSeq != 0) {
     ndn::Name prefixWithSeq = ndn::Name(prefix).appendNumber(oldSeq);
-    auto hashIt = m_prefix2hash.find(prefixWithSeq);
-    if (hashIt != m_prefix2hash.end()) {
-      uint32_t hash = hashIt->second;
-      m_prefix2hash.erase(hashIt);
-      m_hash2prefix.erase(hash);
-      m_iblt.erase(hash);
+    auto hashIt = m_biMap.right.find(prefixWithSeq);
+    if (hashIt != m_biMap.right.end()) {
+      m_iblt.erase(hashIt->second);
+      m_biMap.right.erase(hashIt);
     }
   }
 
-  // Insert the new seq no
+  // Insert the new seq no in m_prefixes, m_biMap, and m_iblt
   it->second = seq;
   ndn::Name prefixWithSeq = ndn::Name(prefix).appendNumber(seq);
   uint32_t newHash = murmurHash3(N_HASHCHECK, prefixWithSeq.toUri());
-  m_prefix2hash[prefixWithSeq] = newHash;
-  m_hash2prefix[newHash] = prefix;
+  m_biMap.insert({newHash, prefixWithSeq});
   m_iblt.insert(newHash);
 }
 
@@ -149,4 +144,4 @@
   BOOST_THROW_EXCEPTION(Error(msg));
 }
 
-} // namespace psync
+} // namespace psync
\ No newline at end of file
diff --git a/PSync/producer-base.hpp b/PSync/producer-base.hpp
index 9583259..510546e 100644
--- a/PSync/producer-base.hpp
+++ b/PSync/producer-base.hpp
@@ -33,11 +33,14 @@
 #include <ndn-cxx/security/key-chain.hpp>
 #include <ndn-cxx/security/validator-config.hpp>
 
+#include <boost/bimap.hpp>
+#include <boost/bimap/unordered_set_of.hpp>
+
 #include <map>
-#include <unordered_set>
 
 namespace psync {
 
+namespace bm = boost::bimaps;
 using namespace ndn::time_literals;
 
 const ndn::time::milliseconds SYNC_REPLY_FRESHNESS = 1_s;
@@ -121,7 +124,7 @@
    * Whoever calls this needs to make sure that prefix is in m_prefixes
    * We remove already existing prefix/seq from IBF
    * (unless seq is zero because we don't insert zero seq into IBF)
-   * Then we update m_prefix, m_prefix2hash, m_hash2prefix, and IBF
+   * Then we update m_prefixes, m_biMap, and IBF
    *
    * @param prefix prefix of the update
    * @param seq sequence number of the update
@@ -155,6 +158,9 @@
   void
   onRegisterFailed(const ndn::Name& prefix, const std::string& msg) const;
 
+  using HashNameBiMap = bm::bimap<bm::unordered_set_of<uint32_t>,
+                                  bm::unordered_set_of<ndn::Name, std::hash<ndn::Name>>>;
+
 PSYNC_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
   IBLT m_iblt;
   uint32_t m_expectedNumEntries;
@@ -164,11 +170,7 @@
 
   // prefix and sequence number
   std::map<ndn::Name, uint64_t> m_prefixes;
-  // Just for looking up hash faster (instead of calculating it again)
-  // Only used in updateSeqNo, prefix/seqNo is the key
-  std::map<ndn::Name, uint32_t> m_prefix2hash;
-  // Value is prefix (and not prefix/seqNo)
-  std::map<uint32_t, ndn::Name> m_hash2prefix;
+  HashNameBiMap m_biMap;
 
   ndn::Face& m_face;
   ndn::KeyChain m_keyChain;
diff --git a/tests/test-full-sync.cpp b/tests/test-full-sync.cpp
index d79e012..34bef0c 100644
--- a/tests/test-full-sync.cpp
+++ b/tests/test-full-sync.cpp
@@ -54,7 +54,7 @@
   shared_ptr<FullProducer> nodes[4];
 };
 
-BOOST_FIXTURE_TEST_SUITE(FullSync, FullSyncFixture)
+BOOST_FIXTURE_TEST_SUITE(TestFullSync, FullSyncFixture)
 
 BOOST_AUTO_TEST_CASE(TwoNodesSimple)
 {
diff --git a/tests/test-partial-sync.cpp b/tests/test-partial-sync.cpp
index 8938483..fae7958 100644
--- a/tests/test-partial-sync.cpp
+++ b/tests/test-partial-sync.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2019,  The University of Memphis
+ * Copyright (c) 2014-2020,  The University of Memphis
  *
  * This file is part of PSync.
  * See AUTHORS.md for complete list of PSync authors and contributors.
@@ -147,7 +147,7 @@
   int numSyncDataRcvd;
 };
 
-BOOST_FIXTURE_TEST_SUITE(PartialSync, PartialSyncFixture)
+BOOST_FIXTURE_TEST_SUITE(TestPartialSync, PartialSyncFixture)
 
 BOOST_AUTO_TEST_CASE(Simple)
 {
@@ -430,4 +430,4 @@
 
 BOOST_AUTO_TEST_SUITE_END()
 
-} // namespace psync
\ No newline at end of file
+} // namespace psync
diff --git a/tests/test-producer-base.cpp b/tests/test-producer-base.cpp
index e775ad8..c5f1112 100644
--- a/tests/test-producer-base.cpp
+++ b/tests/test-producer-base.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2019,  The University of Memphis
+ * Copyright (c) 2014-2020,  The University of Memphis
  *
  * This file is part of PSync.
  * See AUTHORS.md for complete list of PSync authors and contributors.
@@ -51,18 +51,19 @@
   BOOST_CHECK(producerBase.getSeqNo(userNode.toUri()).value() == 1);
 
   std::string prefixWithSeq = Name(userNode).appendNumber(1).toUri();
-  uint32_t hash = producerBase.m_prefix2hash[prefixWithSeq];
-  BOOST_CHECK_EQUAL(producerBase.m_hash2prefix[hash], userNode.toUri());
+  uint32_t hash = producerBase.m_biMap.right.find(prefixWithSeq)->second;
+  Name prefix(producerBase.m_biMap.left.find(hash)->second);
+  BOOST_CHECK_EQUAL(prefix.getPrefix(-1), userNode);
 
   producerBase.removeUserNode(userNode);
   BOOST_CHECK(producerBase.getSeqNo(userNode.toUri()) == ndn::nullopt);
-  BOOST_CHECK(producerBase.m_prefix2hash.find(prefixWithSeq) == producerBase.m_prefix2hash.end());
-  BOOST_CHECK(producerBase.m_hash2prefix.find(hash) == producerBase.m_hash2prefix.end());
+  BOOST_CHECK(producerBase.m_biMap.right.find(prefixWithSeq) == producerBase.m_biMap.right.end());
+  BOOST_CHECK(producerBase.m_biMap.left.find(hash) == producerBase.m_biMap.left.end());
 
   Name nonExistentUserNode("/notAUser");
   producerBase.updateSeqNo(nonExistentUserNode, 1);
-  BOOST_CHECK(producerBase.m_prefix2hash.find(Name(nonExistentUserNode).appendNumber(1).toUri()) ==
-              producerBase.m_prefix2hash.end());
+  BOOST_CHECK(producerBase.m_biMap.right.find(Name(nonExistentUserNode).appendNumber(1).toUri()) ==
+              producerBase.m_biMap.right.end());
 }
 
 BOOST_AUTO_TEST_CASE(ApplicationNack)