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
diff --git a/src/storage/index.hpp b/src/storage/index.hpp
new file mode 100644
index 0000000..90f7436
--- /dev/null
+++ b/src/storage/index.hpp
@@ -0,0 +1,247 @@
+/* -*- 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/>.
+ */
+
+#ifndef REPO_STORAGE_INDEX_HPP
+#define REPO_STORAGE_INDEX_HPP
+
+#include "common.hpp"
+#include "skiplist.hpp"
+#include <queue>
+
+namespace repo {
+
+class Index : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  class Entry
+  {
+  public:
+    class Error : public std::runtime_error
+    {
+    public:
+      explicit
+      Error(const std::string& what)
+        : std::runtime_error(what)
+      {
+      }
+    };
+
+  public:
+
+    /**
+     * @brief used by skiplist to construct node
+     */
+    Entry()
+    {
+    };
+
+    /**
+     * @brief construct Entry by data and id number
+     */
+    Entry(const Data& data, const int64_t id);
+
+    /**
+     * @brief construct Entry by fullName, keyLocator and id number
+     */
+    Entry(const Name& fullName, const KeyLocator& keyLocator, const int64_t id);
+
+    /**
+     * @brief construct Entry by fullName, keyLocatorHash and id number
+     * @param  fullName        full name with digest computed from data
+     * @param  keyLocatorHash  keyLocator hashed by sha256
+     * @param  id              record ID from database
+     */
+    Entry(const Name& fullName, const ndn::ConstBufferPtr& keyLocatorHash, const int64_t id);
+
+    /**
+     *  @brief implicit construct Entry by full name
+     *
+     *  Allow implicit conversion from Name for SkipList lookups by Name
+     */
+    Entry(const Name& name);
+
+    /**
+     *  @brief get the name of entry
+     */
+    const Name&
+    getName() const
+    {
+      return m_name;
+    }
+
+    /**
+     *  @brief get the keyLocator hash value of the entry
+     */
+    const ndn::ConstBufferPtr&
+    getKeyLocatorHash() const
+    {
+      return m_keyLocatorHash;
+    }
+
+    /**
+     *  @brief get record ID from database
+     */
+    const int64_t
+    getId() const
+    {
+      return m_id;
+    }
+
+    bool
+    operator>(const Entry& entry) const
+    {
+      return m_name > entry.getName();
+    }
+
+    bool
+    operator<(const Entry& entry) const
+    {
+      return m_name < entry.getName();
+    }
+
+    bool
+    operator==(const Entry& entry) const
+    {
+      return m_name == entry.getName();
+    }
+
+    bool
+    operator!=(const Entry& entry) const
+    {
+      return m_name != entry.getName();
+    }
+
+  private:
+    Name m_name;
+    ndn::ConstBufferPtr m_keyLocatorHash;
+    int64_t m_id;
+  };
+
+private:
+
+  typedef SkipList<Entry> IndexSkipList;
+
+public:
+  explicit
+  Index(const size_t nMaxPackets);
+
+  /**
+   *  @brief insert entries into index
+   *  @param  data    used to construct entries
+   *  @param  id      obtained from database
+   */
+  bool
+  insert(const Data& data, const int64_t id);
+
+  /**
+   *  @brief insert entries into index
+   *  @param  data    used to construct entries
+   *  @param  id      obtained from database
+   */
+  bool
+  insert(const Name& fullName, const int64_t id,
+         const ndn::ConstBufferPtr& keyLocatorHash);
+
+  /**
+   *  @brief erase the entry in index by its fullname
+   */
+  bool
+  erase(const Name& fullName);
+
+  /** @brief find the Entry for best match of an Interest
+   * @return ID and fullName of the Entry, or (0,ignored) if not found
+   */
+  std::pair<int64_t, Name>
+  find(const Interest& interest) const;
+
+  /** @brief find the first Entry under a Name prefix
+   * @return ID and fullName of the Entry, or (0,ignored) if not found
+   */
+  std::pair<int64_t, Name>
+  find(const Name& name) const;
+
+  /**
+   *  @brief determine whether same Data is already in the index
+   *  @return true if identical Data exists, false otherwise
+   */
+  bool
+  hasData(const Data& data) const;
+
+  /**
+    *  @brief compute the hash value of keyLocator
+    */
+  static const ndn::ConstBufferPtr
+  computeKeyLocatorHash(const KeyLocator& keyLocator);
+
+  const size_t
+  size() const
+  {
+    return m_size;
+  }
+
+private:
+  /**
+   *  @brief select entries which satisfy the selectors in interest and return their name
+   *  @param  interest   used to select entries by comparing the name and checking selectors
+   *  @param  idName    save the id and name of found entries
+   *  @param  startingPoint the entry whose name is equal or larger than the interest name
+   */
+  std::pair<int64_t, Name>
+  selectChild(const Interest& interest,
+              IndexSkipList::const_iterator startingPoint) const;
+
+  /**
+   *  @brief check whether the index is full
+   */
+  bool
+  isFull() const
+  {
+    return m_size >= m_maxPackets;
+  }
+
+  /**
+   *  @brief find the first entry with the prefix
+   *  @param  prefix        used to request the entries
+   *  @param  startingPoint the entry whose name is equal or larger than the interest name
+   *  @return int64_t  the id number of found entry
+   *  @return Name     the name of found entry
+   */
+  std::pair<int64_t, Name>
+  findFirstEntry(const Name& prefix,
+                 IndexSkipList::const_iterator startingPoint) const;
+
+private:
+  IndexSkipList m_skipList;
+  size_t m_maxPackets;
+  size_t m_size;
+};
+
+} // namespace repo
+
+#endif // REPO_STORAGE_INDEX_HPP
