Fix LeafContainer

Change-Id: Ie708e64c1d30751d902f99d17ce0cae0c8d5d08a
diff --git a/src/leaf-container.cpp b/src/leaf-container.cpp
new file mode 100644
index 0000000..8bad5eb
--- /dev/null
+++ b/src/leaf-container.cpp
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012-2014 University of California, Los Angeles
+ *
+ * This file is part of ChronoSync, synchronization library for distributed realtime
+ * applications for NDN.
+ *
+ * ChronoSync is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * ChronoSync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ChronoSync, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
+ * @author Chaoyi Bian <bcy@pku.edu.cn>
+ * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
+ * @author Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "leaf-container.hpp"
+// Simply check whether LeafContainer can compile
diff --git a/src/leaf-container.hpp b/src/leaf-container.hpp
new file mode 100644
index 0000000..51470b7
--- /dev/null
+++ b/src/leaf-container.hpp
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012-2014 University of California, Los Angeles
+ *
+ * This file is part of ChronoSync, synchronization library for distributed realtime
+ * applications for NDN.
+ *
+ * ChronoSync is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * ChronoSync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ChronoSync, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
+ * @author Chaoyi Bian <bcy@pku.edu.cn>
+ * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
+ * @author Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef CHRONOSYNC_LEAF_CONTAINER_HPP
+#define CHRONOSYNC_LEAF_CONTAINER_HPP
+
+#include "mi-tag.hpp"
+#include "leaf.hpp"
+
+#include <ndn-cxx/util/crypto.hpp>
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/mem_fun.hpp>
+
+
+
+namespace chronosync {
+
+namespace mi = boost::multi_index;
+
+struct SessionNameHash
+{
+  std::size_t
+  operator()(const Name& prefix) const
+  {
+    ndn::ConstBufferPtr buffer =
+      ndn::crypto::sha256(prefix.wireEncode().wire(), prefix.wireEncode().size());
+
+    BOOST_ASSERT(buffer->size() > sizeof(std::size_t));
+
+    return *reinterpret_cast<const std::size_t*>(buffer->buf());
+  }
+};
+
+struct SessionNameEqual
+{
+  bool
+  operator()(const Name& prefix1, const Name& prefix2) const
+  {
+    return prefix1 == prefix2;
+  }
+};
+
+struct SessionNameCompare : public std::less<Name>
+{
+  bool
+  operator()(const Name& prefix1, const Name& prefix2) const
+  {
+    return prefix1 < prefix2;
+  }
+};
+
+/**
+ * @brief Container for chronosync leaves
+ */
+struct LeafContainer : public mi::multi_index_container<
+  LeafPtr,
+  mi::indexed_by<
+    // For fast access to elements using SessionName
+    mi::hashed_unique<
+      mi::tag<hashed>,
+      mi::const_mem_fun<Leaf, const Name&, &Leaf::getSessionName>,
+      SessionNameHash,
+      SessionNameEqual
+      >,
+
+    mi::ordered_unique<
+      mi::tag<ordered>,
+      mi::const_mem_fun<Leaf, const Name&, &Leaf::getSessionName>,
+      SessionNameCompare
+      >
+    >
+  >
+{
+};
+
+} // namespace chronosync
+
+#endif // CHRONOSYNC_LEAF_CONTAINER_HPP
diff --git a/src/mi-tag.hpp b/src/mi-tag.hpp
new file mode 100644
index 0000000..1abafc4
--- /dev/null
+++ b/src/mi-tag.hpp
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012-2014 University of California, Los Angeles
+ *
+ * This file is part of ChronoSync, synchronization library for distributed realtime
+ * applications for NDN.
+ *
+ * ChronoSync is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * ChronoSync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ChronoSync, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
+ * @author Chaoyi Bian <bcy@pku.edu.cn>
+ * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
+ * @author Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef CHRONOSYNC_MI_TAG_HPP
+#define CHRONOSYNC_MI_TAG_HPP
+
+namespace chronosync {
+
+// Multi-Index-Container Tags
+struct hashed
+{
+};
+
+struct ordered
+{
+};
+
+struct sequenced
+{
+};
+
+struct timed
+{
+};
+
+
+} // namespace chronosync
+
+#endif // CHRONOSYNC_MI_TAG_HPP
diff --git a/src/sync-state-leaf-container.h b/src/sync-state-leaf-container.h
deleted file mode 100644
index d6d982a..0000000
--- a/src/sync-state-leaf-container.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2012-2014 University of California, Los Angeles
- *
- * This file is part of ChronoSync, synchronization library for distributed realtime
- * applications for NDN.
- *
- * ChronoSync is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation, either
- * version 3 of the License, or (at your option) any later version.
- *
- * ChronoSync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * ChronoSync, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
- * @author Chaoyi Bian <bcy@pku.edu.cn>
- * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#ifndef SYNC_STATE_LEAF_CONTAINER
-#define SYNC_STATE_LEAF_CONTAINER
-
-#include "sync-leaf.h"
-#include "sync-name-info.h"
-
-#include <boost/multi_index_container.hpp>
-// #include <boost/multi_index/tag.hpp>
-#include <boost/multi_index/ordered_index.hpp>
-// #include <boost/multi_index/composite_key.hpp>
-#include <boost/multi_index/hashed_index.hpp>
-// #include <boost/multi_index/random_access_index.hpp>
-// #include <boost/multi_index/member.hpp>
-#include <boost/multi_index/mem_fun.hpp>
-
-namespace mi = boost::multi_index;
-
-namespace Sync {
-
-struct NameInfoHash : public std::unary_function<NameInfo, std::size_t>
-{
-  std::size_t
-  operator() (NameInfoConstPtr prefix) const
-  {
-    return prefix->getHashId ();
-  }
-};
-
-struct NameInfoEqual : public std::unary_function<NameInfo, std::size_t>
-{
-  bool
-  operator() (NameInfoConstPtr prefix1, NameInfoConstPtr prefix2) const
-  {
-    return *prefix1 == *prefix2;
-  }
-};
-
-struct NameInfoCompare : public std::unary_function<NameInfo, std::size_t>
-{
-  bool
-  operator() (NameInfoConstPtr prefix1, NameInfoConstPtr prefix2) const
-  {
-    return *prefix1 < *prefix2;
-  }
-};
-
-/// @cond include_hidden
-struct hashed { };
-struct ordered { };
-/// @endcond
-
-/**
- * \ingroup sync
- * @brief Container for SYNC leaves
- */
-struct LeafContainer : public mi::multi_index_container<
-  LeafPtr,
-  mi::indexed_by<
-    // For fast access to elements using NameInfo
-    mi::hashed_unique<
-      mi::tag<hashed>,
-      mi::const_mem_fun<Leaf, NameInfoConstPtr, &Leaf::getInfo>,
-      NameInfoHash,
-      NameInfoEqual
-      >,
-
-    mi::ordered_unique<
-      mi::tag<ordered>,
-      mi::const_mem_fun<Leaf, NameInfoConstPtr, &Leaf::getInfo>,
-      NameInfoCompare
-      >
-    >
-  >
-{
-};
-
-} // Sync
-
-#endif // SYNC_STATE_LEAF_CONTAINER
diff --git a/tests/unit-tests/test-leaf.cpp b/tests/unit-tests/test-leaf.cpp
index a8f3101..5553a05 100644
--- a/tests/unit-tests/test-leaf.cpp
+++ b/tests/unit-tests/test-leaf.cpp
@@ -17,7 +17,9 @@
  * ChronoSync, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+
 #include "leaf.hpp"
+#include "leaf-container.hpp"
 #include <ndn-cxx/encoding/buffer-stream.hpp>
 
 #include "boost-test.hpp"
@@ -63,6 +65,62 @@
   BOOST_CHECK(*result == *digest);
 }
 
+BOOST_AUTO_TEST_CASE(Container)
+{
+  LeafPtr leaf1 = make_shared<Leaf>(Name("/test/name"), 1, 10);
+  LeafPtr leaf2 = make_shared<Leaf>(Name("/test/name"), 2, 10);
+
+  LeafContainer container;
+
+  container.insert(leaf1);
+  container.insert(leaf2);
+
+  Name idx1("/test/name");
+  idx1.appendNumber(1);
+
+  Name idx2("/test/name");
+  idx2.appendNumber(2);
+
+  Name idx3("/test/name");
+  idx3.appendNumber(3);
+
+  Name idx4("/test/mane");
+  idx4.appendNumber(4);
+
+  LeafContainer::index<hashed>::type& hashedIndex = container.get<hashed>();
+
+  BOOST_CHECK_EQUAL(container.get<ordered>().size(), 2);
+  BOOST_CHECK_EQUAL(container.get<hashed>().size(), 2);
+  BOOST_CHECK(container.find(idx1) != container.end());
+  BOOST_CHECK(container.find(idx2) != container.end());
+  BOOST_CHECK(container.find(idx3) == container.end());
+
+  BOOST_CHECK(hashedIndex.find(idx1) != hashedIndex.end());
+  BOOST_CHECK(hashedIndex.find(idx2) != hashedIndex.end());
+  BOOST_CHECK(hashedIndex.find(idx3) == hashedIndex.end());
+
+  LeafPtr leaf3 = make_shared<Leaf>(Name("/test/mane"), 3, 10);
+  container.insert(leaf3);
+
+  Name idx0("/test/mane");
+  idx0.appendNumber(3);
+
+  LeafContainer::index<ordered>::type::iterator it = container.get<ordered>().begin();
+  BOOST_CHECK_EQUAL((*it)->getSessionName(), idx0);
+  it++;
+  BOOST_REQUIRE(it != container.get<ordered>().end());
+  BOOST_CHECK_EQUAL((*it)->getSessionName(), idx1);
+  it++;
+  BOOST_REQUIRE(it != container.get<ordered>().end());
+  BOOST_CHECK_EQUAL((*it)->getSessionName(), idx2);
+
+
+  BOOST_CHECK(hashedIndex.find(idx0) != hashedIndex.end());
+  BOOST_CHECK(hashedIndex.find(idx1) != hashedIndex.end());
+  BOOST_CHECK(hashedIndex.find(idx2) != hashedIndex.end());
+  BOOST_CHECK(hashedIndex.find(idx4) == hashedIndex.end());
+}
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // namespace test