diff --git a/src/common.hpp b/src/common.hpp
index 70d959f..1f27bb3 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -34,11 +34,15 @@
 #include <boost/utility.hpp>
 #include <boost/random/mersenne_twister.hpp>
 #include <boost/random/uniform_int_distribution.hpp>
+#include <boost/random/geometric_distribution.hpp>
 
 #include <map>
 #include <string>
 #include <vector>
+#include <queue>
+#include <list>
 #include <algorithm>
+#include <iostream>
 
 namespace repo {
 
diff --git a/src/storage/skiplist.hpp b/src/storage/skiplist.hpp
new file mode 100644
index 0000000..86602b5
--- /dev/null
+++ b/src/storage/skiplist.hpp
@@ -0,0 +1,370 @@
+/* -*- 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_SKIPLIST_HPP
+#define REPO_STORAGE_SKIPLIST_HPP
+
+#include "common.hpp"
+
+#include <boost/utility.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
+
+namespace repo {
+
+class SkipList32Layers25Probabilty
+{
+public:
+  static size_t
+  getMaxLayers()
+  {
+    return 32;
+  }
+
+  static double
+  getProbability()
+  {
+    return 0.25; /* 25% */
+  }
+};
+
+template<typename T, typename Compare = std::less<T>,
+         typename Traits = SkipList32Layers25Probabilty >
+class SkipList
+{
+public:
+  //@brief layer of skiplist is std::list
+  typedef std::list<T> SkipListLayer;
+  //@brief iterator of skiplist
+  typedef typename SkipListLayer::iterator iterator;
+
+public:
+  explicit
+  SkipList();
+
+  ~SkipList();
+
+  size_t
+  size() const;
+
+public: // enumeration
+
+  iterator
+  begin() const;
+
+  iterator
+  end() const;
+
+  iterator
+  find(const T& key);
+
+  iterator
+  lower_bound(const T& key);
+
+  std::pair<iterator, bool>
+  insert(const T& key);
+
+  iterator
+  erase(iterator it);
+
+private:
+  size_t
+  pickRandomLayer() const;
+
+private:
+  //@brief store multiple layers
+  typedef std::list<shared_ptr<SkipListLayer> > SkipListHeadLayer;
+  //@brief iterate one layer of skiplist
+  typedef typename SkipListLayer::iterator layer_iterator;
+  //@brief iterate among different layers
+  typedef typename SkipListHeadLayer::iterator head_iterator;
+  typedef typename SkipListHeadLayer::reverse_iterator head_reverse_iterator;
+
+private:
+  SkipListHeadLayer m_skipList;
+  //@brief keep the locations of iterator where element is inserted in each layer
+  //key of external map is the layer of skiplist
+  //value is the internal map which maps the key T with the iterator of each layer
+  std::map<size_t, std::map<T, layer_iterator, Compare> > m_layerToEntry;
+  Compare m_compare;
+};
+
+template<typename T, typename Compare, typename Traits>
+inline
+SkipList<T, Compare, Traits>::SkipList()
+{
+  shared_ptr<SkipListLayer> zeroLayer = make_shared<SkipListLayer>();
+  m_skipList.push_back(zeroLayer);
+}
+
+template<typename T, typename Compare, typename Traits>
+inline
+SkipList<T, Compare, Traits>::~SkipList()
+{
+}
+
+template<typename T, typename Compare, typename Traits>
+inline size_t
+SkipList<T, Compare, Traits>::size() const
+{
+  return (*m_skipList.begin())->size();
+}
+
+template<typename T, typename Compare, typename Traits>
+inline typename SkipList<T, Compare, Traits>::iterator
+SkipList<T, Compare, Traits>::begin() const
+{
+   return (*m_skipList.begin())->begin();
+}
+
+template<typename T, typename Compare, typename Traits>
+inline typename SkipList<T, Compare, Traits>::iterator
+SkipList<T, Compare, Traits>::end() const
+{
+  return (*m_skipList.begin())->end();
+}
+
+template<typename T, typename Compare, typename Traits>
+inline typename SkipList<T, Compare, Traits>::iterator
+SkipList<T, Compare, Traits>::find(const T& key)
+{
+  iterator it = this->lower_bound(key);
+  if (it == this->end() || *it != key)
+    return this->end();
+  return it;
+}
+
+template<typename T, typename Compare, typename Traits>
+inline typename SkipList<T, Compare, Traits>::iterator
+SkipList<T, Compare, Traits>::lower_bound(const T& key)
+{
+  bool isIterated = false;
+  bool isIdentical = false;
+  head_reverse_iterator topLayer = m_skipList.rbegin();
+  layer_iterator head = (*topLayer)->begin();
+
+  if (!(*topLayer)->empty()) {
+    size_t layer = m_skipList.size() - 1;
+    for (head_reverse_iterator headReverseIterator = topLayer;
+         headReverseIterator != m_skipList.rend(); ++headReverseIterator) {
+      if (!isIterated)
+        head = (*headReverseIterator)->begin();
+
+      if (head != (*headReverseIterator)->end()) {
+        if (!isIterated && (!m_compare(*head, key) && !m_compare(key, *head))) {
+          if (layer > 0) {
+            layer--;
+            continue; // try lower layer
+          }
+          else {
+            isIterated = true;
+            isIdentical = true;
+          }
+        }
+        else {
+          layer_iterator layerIterator = head;
+          while (m_compare((*layerIterator) , key)) {
+            head = layerIterator;
+            isIterated = true;
+
+            ++layerIterator;
+            if (layerIterator == (*headReverseIterator)->end())
+              break;
+          }
+
+        }
+      }
+
+      if (layer > 0) {
+        //find the head in the lower layer
+        head = m_layerToEntry[layer - 1][*head];
+      }
+      else {  //if we reached the first layer
+        if (isIterated) {
+          if (!isIdentical)
+            ++head;
+          //result = head;
+          return head;
+        }
+        else {
+          return head;
+        }
+      }
+
+      layer--;
+    }
+  }
+  return (*m_skipList.begin())->end();
+}
+
+template<typename T, typename Compare, typename Traits>
+inline size_t
+SkipList<T, Compare, Traits>::pickRandomLayer() const
+{
+  static boost::random::mt19937 gen;
+  static boost::random::geometric_distribution<size_t> dist(Traits::getProbability());
+  return std::min(dist(gen), Traits::getMaxLayers());
+}
+
+template<typename T, typename Compare, typename Traits>
+inline std::pair<typename SkipList<T, Compare, Traits>::iterator ,bool>
+SkipList<T, Compare, Traits>::insert(const T& key)
+{
+  bool insertInFront = false;
+  bool isIterated = false;
+  head_reverse_iterator topLayer = m_skipList.rbegin();
+  std::vector<layer_iterator> updateTable(Traits::getMaxLayers());
+  layer_iterator head = (*topLayer)->begin();
+
+  if (!(*topLayer)->empty()) {
+    size_t layer = m_skipList.size() - 1;
+    for (head_reverse_iterator headReverseIterator = topLayer;
+         headReverseIterator != m_skipList.rend(); ++headReverseIterator) {
+      if (!isIterated)
+        head = (*headReverseIterator)->begin();
+
+      updateTable[layer] = head;
+
+      if (head != (*headReverseIterator)->end()) {
+        if (!isIterated && !m_compare(*head, key)) {
+          --updateTable[layer];
+          insertInFront = true;
+        }
+        else {
+          layer_iterator layerIterator = head;
+
+          while (m_compare(*layerIterator , key)) {
+            head = layerIterator;
+            updateTable[layer] = layerIterator;
+            isIterated = true;
+
+            ++layerIterator;
+            if (layerIterator == (*headReverseIterator)->end())
+              break;
+          }
+
+        }
+      }
+
+      if (layer > 0)
+        head = m_layerToEntry[layer - 1][*head]; // move HEAD to the lower layer
+
+      layer--;
+    }
+  }
+  else {
+    updateTable[0] = (*topLayer)->begin(); //initialization
+  }
+
+  head = updateTable[0];
+  ++head;
+
+  bool isInBoundaries = (head != (*m_skipList.begin())->end());
+  bool isKeyIdentical = false;
+  if (isInBoundaries) {
+    isKeyIdentical = (!m_compare(*head, key) && !m_compare(key, *head));
+  }
+  if (isKeyIdentical) {
+    return std::make_pair(head, false);
+  }
+
+  size_t randomLayer = pickRandomLayer();
+
+  while (m_skipList.size() < randomLayer + 1) {
+     boost::shared_ptr<SkipListLayer> newLayer = make_shared<SkipListLayer>();
+    m_skipList.push_back(newLayer);
+
+    updateTable[(m_skipList.size() - 1)] = newLayer->begin();
+  }
+
+  size_t layer = 0;
+  layer_iterator result;
+
+  for (head_iterator headIterator = m_skipList.begin();
+       headIterator != m_skipList.end() && layer <= randomLayer; ++headIterator) {
+    if (updateTable[layer] == (*headIterator)->end() && !insertInFront) {
+      (*headIterator)->push_back(key);
+      layer_iterator last = (*headIterator)->end();
+      --last;
+      m_layerToEntry[layer][key] = last;
+
+    }
+    else if (updateTable[layer] == (*headIterator)->end() && insertInFront) {
+      (*headIterator)->push_front(key);
+      m_layerToEntry[layer][key] = (*headIterator)->begin();
+    }
+    else {
+      ++updateTable[layer]; // insert after
+      iterator position = (*headIterator)->insert(updateTable[layer], key);
+      m_layerToEntry[layer][key] = position;  // save iterator where item was inserted
+    }
+    if (layer == 0)
+      result = m_layerToEntry[layer][key];
+    layer++;
+  }
+  return make_pair(result, true);
+}
+
+template<typename T, typename Compare, typename Traits>
+inline typename SkipList<T, Compare, Traits>::iterator
+SkipList<T, Compare, Traits>::erase(typename SkipList<T, Compare, Traits>::iterator it)
+{
+  if (it != end()) {
+    int layer = 1;
+    head_iterator headIterator = m_skipList.begin();
+    headIterator++;
+    for (; headIterator != m_skipList.end();) {
+      const std::map<T, layer_iterator, Compare>& layerIterators = m_layerToEntry[layer];
+      if(!layerIterators.empty()) {
+        typename std::map<T, layer_iterator, Compare>::const_iterator eraseIterator =
+          layerIterators.find(*it);
+        if (eraseIterator != layerIterators.end()) {
+          (*headIterator)->erase(eraseIterator->second);
+          m_layerToEntry[layer].erase(*it);
+          //remove layers that do not contain any elements (starting from the second layer)
+          if ((*headIterator)->empty()) {
+            // delete headIterator;
+            headIterator = m_skipList.erase(headIterator);
+          }
+          else {
+            ++headIterator;
+          }
+          layer++;
+        }
+        else {
+          break;
+        }
+      }
+    }
+
+    m_layerToEntry[0].erase(*it);
+    m_skipList.end();
+    typename SkipList<T, Compare, Traits>::iterator returnIterator =
+      (*m_skipList.begin())->erase(it);
+
+    return returnIterator;
+  }
+  else {
+    return end();
+  }
+}
+
+} // namespace repo
+
+#endif // REPO_STORAGE_SKIPLIST_HPP
