blob: 86602b55c854d122659aee93f89faa04196af5a5 [file] [log] [blame]
Shuo Chen9a43f162014-07-01 13:43:54 +08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3* Copyright (c) 2014, Regents of the University of California.
4*
5* This file is part of NDN repo-ng (Next generation of NDN repository).
6* See AUTHORS.md for complete list of repo-ng authors and contributors.
7*
8* repo-ng is free software: you can redistribute it and/or modify it under the terms
9* of the GNU General Public License as published by the Free Software Foundation,
10* either version 3 of the License, or (at your option) any later version.
11*
12* repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14* PURPOSE. See the GNU General Public License for more details.
15*
16* You should have received a copy of the GNU General Public License along with
17* repo-ng, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#ifndef REPO_STORAGE_SKIPLIST_HPP
21#define REPO_STORAGE_SKIPLIST_HPP
22
23#include "common.hpp"
24
25#include <boost/utility.hpp>
26#include <boost/random/mersenne_twister.hpp>
27#include <boost/random/uniform_int_distribution.hpp>
28
29namespace repo {
30
31class SkipList32Layers25Probabilty
32{
33public:
34 static size_t
35 getMaxLayers()
36 {
37 return 32;
38 }
39
40 static double
41 getProbability()
42 {
43 return 0.25; /* 25% */
44 }
45};
46
47template<typename T, typename Compare = std::less<T>,
48 typename Traits = SkipList32Layers25Probabilty >
49class SkipList
50{
51public:
52 //@brief layer of skiplist is std::list
53 typedef std::list<T> SkipListLayer;
54 //@brief iterator of skiplist
55 typedef typename SkipListLayer::iterator iterator;
56
57public:
58 explicit
59 SkipList();
60
61 ~SkipList();
62
63 size_t
64 size() const;
65
66public: // enumeration
67
68 iterator
69 begin() const;
70
71 iterator
72 end() const;
73
74 iterator
75 find(const T& key);
76
77 iterator
78 lower_bound(const T& key);
79
80 std::pair<iterator, bool>
81 insert(const T& key);
82
83 iterator
84 erase(iterator it);
85
86private:
87 size_t
88 pickRandomLayer() const;
89
90private:
91 //@brief store multiple layers
92 typedef std::list<shared_ptr<SkipListLayer> > SkipListHeadLayer;
93 //@brief iterate one layer of skiplist
94 typedef typename SkipListLayer::iterator layer_iterator;
95 //@brief iterate among different layers
96 typedef typename SkipListHeadLayer::iterator head_iterator;
97 typedef typename SkipListHeadLayer::reverse_iterator head_reverse_iterator;
98
99private:
100 SkipListHeadLayer m_skipList;
101 //@brief keep the locations of iterator where element is inserted in each layer
102 //key of external map is the layer of skiplist
103 //value is the internal map which maps the key T with the iterator of each layer
104 std::map<size_t, std::map<T, layer_iterator, Compare> > m_layerToEntry;
105 Compare m_compare;
106};
107
108template<typename T, typename Compare, typename Traits>
109inline
110SkipList<T, Compare, Traits>::SkipList()
111{
112 shared_ptr<SkipListLayer> zeroLayer = make_shared<SkipListLayer>();
113 m_skipList.push_back(zeroLayer);
114}
115
116template<typename T, typename Compare, typename Traits>
117inline
118SkipList<T, Compare, Traits>::~SkipList()
119{
120}
121
122template<typename T, typename Compare, typename Traits>
123inline size_t
124SkipList<T, Compare, Traits>::size() const
125{
126 return (*m_skipList.begin())->size();
127}
128
129template<typename T, typename Compare, typename Traits>
130inline typename SkipList<T, Compare, Traits>::iterator
131SkipList<T, Compare, Traits>::begin() const
132{
133 return (*m_skipList.begin())->begin();
134}
135
136template<typename T, typename Compare, typename Traits>
137inline typename SkipList<T, Compare, Traits>::iterator
138SkipList<T, Compare, Traits>::end() const
139{
140 return (*m_skipList.begin())->end();
141}
142
143template<typename T, typename Compare, typename Traits>
144inline typename SkipList<T, Compare, Traits>::iterator
145SkipList<T, Compare, Traits>::find(const T& key)
146{
147 iterator it = this->lower_bound(key);
148 if (it == this->end() || *it != key)
149 return this->end();
150 return it;
151}
152
153template<typename T, typename Compare, typename Traits>
154inline typename SkipList<T, Compare, Traits>::iterator
155SkipList<T, Compare, Traits>::lower_bound(const T& key)
156{
157 bool isIterated = false;
158 bool isIdentical = false;
159 head_reverse_iterator topLayer = m_skipList.rbegin();
160 layer_iterator head = (*topLayer)->begin();
161
162 if (!(*topLayer)->empty()) {
163 size_t layer = m_skipList.size() - 1;
164 for (head_reverse_iterator headReverseIterator = topLayer;
165 headReverseIterator != m_skipList.rend(); ++headReverseIterator) {
166 if (!isIterated)
167 head = (*headReverseIterator)->begin();
168
169 if (head != (*headReverseIterator)->end()) {
170 if (!isIterated && (!m_compare(*head, key) && !m_compare(key, *head))) {
171 if (layer > 0) {
172 layer--;
173 continue; // try lower layer
174 }
175 else {
176 isIterated = true;
177 isIdentical = true;
178 }
179 }
180 else {
181 layer_iterator layerIterator = head;
182 while (m_compare((*layerIterator) , key)) {
183 head = layerIterator;
184 isIterated = true;
185
186 ++layerIterator;
187 if (layerIterator == (*headReverseIterator)->end())
188 break;
189 }
190
191 }
192 }
193
194 if (layer > 0) {
195 //find the head in the lower layer
196 head = m_layerToEntry[layer - 1][*head];
197 }
198 else { //if we reached the first layer
199 if (isIterated) {
200 if (!isIdentical)
201 ++head;
202 //result = head;
203 return head;
204 }
205 else {
206 return head;
207 }
208 }
209
210 layer--;
211 }
212 }
213 return (*m_skipList.begin())->end();
214}
215
216template<typename T, typename Compare, typename Traits>
217inline size_t
218SkipList<T, Compare, Traits>::pickRandomLayer() const
219{
220 static boost::random::mt19937 gen;
221 static boost::random::geometric_distribution<size_t> dist(Traits::getProbability());
222 return std::min(dist(gen), Traits::getMaxLayers());
223}
224
225template<typename T, typename Compare, typename Traits>
226inline std::pair<typename SkipList<T, Compare, Traits>::iterator ,bool>
227SkipList<T, Compare, Traits>::insert(const T& key)
228{
229 bool insertInFront = false;
230 bool isIterated = false;
231 head_reverse_iterator topLayer = m_skipList.rbegin();
232 std::vector<layer_iterator> updateTable(Traits::getMaxLayers());
233 layer_iterator head = (*topLayer)->begin();
234
235 if (!(*topLayer)->empty()) {
236 size_t layer = m_skipList.size() - 1;
237 for (head_reverse_iterator headReverseIterator = topLayer;
238 headReverseIterator != m_skipList.rend(); ++headReverseIterator) {
239 if (!isIterated)
240 head = (*headReverseIterator)->begin();
241
242 updateTable[layer] = head;
243
244 if (head != (*headReverseIterator)->end()) {
245 if (!isIterated && !m_compare(*head, key)) {
246 --updateTable[layer];
247 insertInFront = true;
248 }
249 else {
250 layer_iterator layerIterator = head;
251
252 while (m_compare(*layerIterator , key)) {
253 head = layerIterator;
254 updateTable[layer] = layerIterator;
255 isIterated = true;
256
257 ++layerIterator;
258 if (layerIterator == (*headReverseIterator)->end())
259 break;
260 }
261
262 }
263 }
264
265 if (layer > 0)
266 head = m_layerToEntry[layer - 1][*head]; // move HEAD to the lower layer
267
268 layer--;
269 }
270 }
271 else {
272 updateTable[0] = (*topLayer)->begin(); //initialization
273 }
274
275 head = updateTable[0];
276 ++head;
277
278 bool isInBoundaries = (head != (*m_skipList.begin())->end());
279 bool isKeyIdentical = false;
280 if (isInBoundaries) {
281 isKeyIdentical = (!m_compare(*head, key) && !m_compare(key, *head));
282 }
283 if (isKeyIdentical) {
284 return std::make_pair(head, false);
285 }
286
287 size_t randomLayer = pickRandomLayer();
288
289 while (m_skipList.size() < randomLayer + 1) {
290 boost::shared_ptr<SkipListLayer> newLayer = make_shared<SkipListLayer>();
291 m_skipList.push_back(newLayer);
292
293 updateTable[(m_skipList.size() - 1)] = newLayer->begin();
294 }
295
296 size_t layer = 0;
297 layer_iterator result;
298
299 for (head_iterator headIterator = m_skipList.begin();
300 headIterator != m_skipList.end() && layer <= randomLayer; ++headIterator) {
301 if (updateTable[layer] == (*headIterator)->end() && !insertInFront) {
302 (*headIterator)->push_back(key);
303 layer_iterator last = (*headIterator)->end();
304 --last;
305 m_layerToEntry[layer][key] = last;
306
307 }
308 else if (updateTable[layer] == (*headIterator)->end() && insertInFront) {
309 (*headIterator)->push_front(key);
310 m_layerToEntry[layer][key] = (*headIterator)->begin();
311 }
312 else {
313 ++updateTable[layer]; // insert after
314 iterator position = (*headIterator)->insert(updateTable[layer], key);
315 m_layerToEntry[layer][key] = position; // save iterator where item was inserted
316 }
317 if (layer == 0)
318 result = m_layerToEntry[layer][key];
319 layer++;
320 }
321 return make_pair(result, true);
322}
323
324template<typename T, typename Compare, typename Traits>
325inline typename SkipList<T, Compare, Traits>::iterator
326SkipList<T, Compare, Traits>::erase(typename SkipList<T, Compare, Traits>::iterator it)
327{
328 if (it != end()) {
329 int layer = 1;
330 head_iterator headIterator = m_skipList.begin();
331 headIterator++;
332 for (; headIterator != m_skipList.end();) {
333 const std::map<T, layer_iterator, Compare>& layerIterators = m_layerToEntry[layer];
334 if(!layerIterators.empty()) {
335 typename std::map<T, layer_iterator, Compare>::const_iterator eraseIterator =
336 layerIterators.find(*it);
337 if (eraseIterator != layerIterators.end()) {
338 (*headIterator)->erase(eraseIterator->second);
339 m_layerToEntry[layer].erase(*it);
340 //remove layers that do not contain any elements (starting from the second layer)
341 if ((*headIterator)->empty()) {
342 // delete headIterator;
343 headIterator = m_skipList.erase(headIterator);
344 }
345 else {
346 ++headIterator;
347 }
348 layer++;
349 }
350 else {
351 break;
352 }
353 }
354 }
355
356 m_layerToEntry[0].erase(*it);
357 m_skipList.end();
358 typename SkipList<T, Compare, Traits>::iterator returnIterator =
359 (*m_skipList.begin())->erase(it);
360
361 return returnIterator;
362 }
363 else {
364 return end();
365 }
366}
367
368} // namespace repo
369
370#endif // REPO_STORAGE_SKIPLIST_HPP