diff --git a/src/storage/index.cpp b/src/storage/index.cpp
new file mode 100644
index 0000000..d2472fb
--- /dev/null
+++ b/src/storage/index.cpp
@@ -0,0 +1,258 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng 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.
+ *
+ * repo-ng 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
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "index.hpp"
+#include "skiplist.hpp"
+
+#include <ndn-cxx/util/crypto.hpp>
+#include "ndn-cxx/security/signature-sha256-with-rsa.hpp"
+
+namespace repo {
+
+/** @brief determines if entry can satisfy interest
+ *  @param hash SHA256 hash of PublisherPublicKeyLocator if exists in interest, otherwise ignored
+ */
+static bool
+matchesSimpleSelectors(const Interest& interest, ndn::ConstBufferPtr& hash,
+                       const Index::Entry& entry)
+{
+  const Name& fullName = entry.getName();
+
+  if (!interest.getName().isPrefixOf(fullName))
+    return false;
+
+  size_t nSuffixComponents = fullName.size() - interest.getName().size();
+  if (interest.getMinSuffixComponents() >= 0 &&
+      nSuffixComponents < static_cast<size_t>(interest.getMinSuffixComponents()))
+    return false;
+  if (interest.getMaxSuffixComponents() >= 0 &&
+      nSuffixComponents > static_cast<size_t>(interest.getMaxSuffixComponents()))
+    return false;
+
+  if (!interest.getExclude().empty() &&
+      entry.getName().size() > interest.getName().size() &&
+      interest.getExclude().isExcluded(entry.getName()[interest.getName().size()]))
+    return false;
+  if (!interest.getPublisherPublicKeyLocator().empty())
+    {
+      if (*entry.getKeyLocatorHash() != *hash)
+          return false;
+    }
+  return true;
+}
+
+Index::Index(const size_t nMaxPackets)
+  : m_maxPackets(nMaxPackets)
+  , m_size(0)
+{
+}
+
+
+bool
+Index::insert(const Data& data, const int64_t id)
+{
+  if (isFull())
+    throw Error("The Index is Full. Cannot Insert Any Data!");
+  Entry entry(data, id);
+  bool isInserted = m_skipList.insert(entry).second;
+  if (isInserted)
+    ++m_size;
+  return isInserted;
+}
+
+bool
+Index::insert(const Name& fullName, const int64_t id,
+              const ndn::ConstBufferPtr& keyLocatorHash)
+{
+  if (isFull())
+    throw Error("The Index is Full. Cannot Insert Any Data!");
+  Entry entry(fullName, keyLocatorHash, id);
+  bool isInserted = m_skipList.insert(entry).second;
+  if (isInserted)
+    ++m_size;
+  return isInserted;
+}
+
+std::pair<int64_t,Name>
+Index::find(const Interest& interest) const
+{
+  Name name = interest.getName();
+  IndexSkipList::const_iterator result = m_skipList.lower_bound(name);
+  if (result != m_skipList.end())
+    {
+      return selectChild(interest, result);
+    }
+  else
+    {
+      return std::pair<int64_t,Name>();
+    }
+}
+
+std::pair<int64_t,Name>
+Index::find(const Name& name) const
+{
+  IndexSkipList::const_iterator result = m_skipList.lower_bound(name);
+  if (result != m_skipList.end())
+    {
+      return findFirstEntry(name, result);
+    }
+  else
+    {
+      return std::pair<int64_t,Name>();
+    }
+}
+
+bool
+Index::hasData(const Data& data) const
+{
+  Index::Entry entry(data, -1); // the id number is useless
+  IndexSkipList::const_iterator result = m_skipList.find(entry);
+  return result != m_skipList.end();
+
+}
+
+std::pair<int64_t,Name>
+Index::findFirstEntry(const Name& prefix,
+                      IndexSkipList::const_iterator startingPoint) const
+{
+  BOOST_ASSERT(startingPoint != m_skipList.end());
+  if (prefix.isPrefixOf(startingPoint->getName()))
+    {
+      return std::make_pair(startingPoint->getId(), startingPoint->getName());
+    }
+  else
+    {
+      return std::pair<int64_t,Name>();
+    }
+}
+
+bool
+Index::erase(const Name& fullName)
+{
+  Entry entry(fullName);
+  IndexSkipList::const_iterator findIterator = m_skipList.find(entry);
+  if (findIterator != m_skipList.end())
+    {
+      m_skipList.erase(findIterator);
+      m_size--;
+      return true;
+    }
+  else
+    return false;
+}
+
+const ndn::ConstBufferPtr
+Index::computeKeyLocatorHash(const KeyLocator& keyLocator)
+{
+  const Block& block = keyLocator.wireEncode();
+  ndn::ConstBufferPtr keyLocatorHash = ndn::crypto::sha256(block.wire(), block.size());
+  return keyLocatorHash;
+}
+
+std::pair<int64_t,Name>
+Index::selectChild(const Interest& interest,
+                   IndexSkipList::const_iterator startingPoint) const
+{
+  BOOST_ASSERT(startingPoint != m_skipList.end());
+  bool isLeftmost = (interest.getChildSelector() <= 0);
+  ndn::ConstBufferPtr hash;
+  if (!interest.getPublisherPublicKeyLocator().empty())
+    {
+      KeyLocator keyLocator = interest.getPublisherPublicKeyLocator();
+      const Block& block = keyLocator.wireEncode();
+      hash = ndn::crypto::sha256(block.wire(), block.size());
+    }
+
+  if (isLeftmost)
+    {
+      for (IndexSkipList::const_iterator it = startingPoint;
+           it != m_skipList.end(); ++it)
+        {
+          if (!interest.getName().isPrefixOf(it->getName()))
+            return std::pair<int64_t,Name>();
+          if (matchesSimpleSelectors(interest, hash, (*it)))
+            return std::make_pair(it->getId(), it->getName());
+        }
+    }
+  else
+    {
+      IndexSkipList::const_iterator boundary = m_skipList.lower_bound(interest.getName());
+      if (boundary == m_skipList.end() || !interest.getName().isPrefixOf(boundary->getName()))
+        return std::pair<int64_t,Name>();
+      Name successor = interest.getName().getSuccessor();
+      IndexSkipList::const_iterator last = interest.getName().size() == 0 ?
+                    m_skipList.end() : m_skipList.lower_bound(interest.getName().getSuccessor());
+      while (true)
+        {
+          IndexSkipList::const_iterator prev = last;
+          --prev;
+          if (prev == boundary)
+            {
+              bool isMatch = matchesSimpleSelectors(interest, hash, (*prev));
+              if (isMatch)
+                {
+                  return std::make_pair(prev->getId(), prev->getName());
+                }
+              else
+                return std::pair<int64_t,Name>();
+            }
+          IndexSkipList::const_iterator first =
+            m_skipList.lower_bound(prev->getName().getPrefix(interest.getName().size() + 1));
+          IndexSkipList::const_iterator match =
+                     std::find_if(first, last, bind(&matchesSimpleSelectors, interest, hash, _1));
+          if (match != last)
+            {
+              return std::make_pair(match->getId(), match->getName());
+            }
+          last = first;
+        }
+    }
+  return std::pair<int64_t,Name>();
+}
+
+Index::Entry::Entry(const Data& data, const int64_t id)
+  : m_name(data.getFullName())
+  , m_id(id)
+{
+  const ndn::Signature& signature = data.getSignature();
+  if (signature.hasKeyLocator())
+    m_keyLocatorHash = computeKeyLocatorHash(signature.getKeyLocator());
+}
+
+Index::Entry::Entry(const Name& fullName, const KeyLocator& keyLocator, const int64_t id)
+  : m_name(fullName)
+  , m_keyLocatorHash(computeKeyLocatorHash(keyLocator))
+  , m_id(id)
+{
+}
+
+Index::Entry::Entry(const Name& fullName,
+                    const ndn::ConstBufferPtr& keyLocatorHash, const int64_t id)
+  : m_name(fullName)
+  , m_keyLocatorHash(keyLocatorHash)
+  , m_id(id)
+{
+}
+
+Index::Entry::Entry(const Name& name)
+  : m_name(name)
+{
+}
+
+} // namespace repo
