Skip to content

Commit 97db79d

Browse files
committed
[cpp][17_skiplist] automatically grow within insertion.
1 parent 3c3e28e commit 97db79d

File tree

2 files changed

+49
-6
lines changed

2 files changed

+49
-6
lines changed

c-cpp/17_skiplist/skiplist_tr.hpp

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ class random_level {
4949
enum class erase_policy { ALL, SINGLE };
5050

5151
template <typename Value,
52-
typename Hash = std::hash<Value>>
52+
typename Hash = std::hash<Value>,
53+
size_t Factor = 2>
5354
class skiplist {
5455
public:
5556
using value_type = Value;
@@ -65,7 +66,7 @@ class skiplist {
6566
"STATIC ASSERT FAILED! iterator type differs.");
6667

6768
private:
68-
size_type max_lv_ = 8;
69+
size_type max_lv_ = 2;
6970
double prob_ = 0.5;
7071
mutable skiplist_detail::random_level<size_type> rl_;
7172
container cont_;
@@ -233,20 +234,56 @@ class skiplist {
233234
const_iterator cend() const {
234235
return cont_.cend();
235236
}
237+
void grow(const size_type new_max_lv) {
238+
if (max_lv_ < new_max_lv) {
239+
#ifdef LIAM_UT_DEBUG_
240+
std::cerr << "grow from [" << max_lv_ << "] to ["
241+
<< new_max_lv << "]!\n";
242+
#endif
243+
max_lv_ = new_max_lv;
244+
245+
iterator tail = std::prev(cont_.end());
246+
auto beg_tail = tail->forwards.end();
247+
tail->forwards.resize(max_lv_, cont_.end());
248+
249+
iterator head = cont_.begin();
250+
auto beg_head = head->forwards.end();
251+
head->forwards.resize(max_lv_, tail);
252+
253+
return;
254+
} else {
255+
#ifdef LIAM_UT_DEBUG_
256+
std::cerr << "abandon growing!\n";
257+
#endif
258+
return;
259+
}
260+
}
261+
void grow() {
262+
grow(Factor * max_lv_);
263+
}
264+
size_type capability() const {
265+
return std::pow(Factor, max_lv_);
266+
}
236267

237268
public:
238269
const_iterator find(const value_type& target) const {
239270
#ifdef LIAM_UT_DEBUG_
240-
std::cerr << "finding [" << target << "]!!!!!!!!!!!!!!!!!!!!\n";
271+
std::cerr << "finding [" << target << "]!\n";
241272
#endif
242273
const hash_type key = hasher()(target);
243274
const_iterator iter = find_helper(key);
244275
return (iter->key == key) ? iter : cont_.end();
245276
}
246277
void insert(const value_type& target) {
247278
#ifdef LIAM_UT_DEBUG_
248-
std::cerr << "inserting [" << target << "]!!!!!!!!!!!!!!!!!!!!\n";
279+
std::cerr << "inserting [" << target << "]!\n";
280+
#endif
281+
if (size() > static_cast<double>(Factor - 1) / Factor * capability()) {
282+
#ifdef LIAM_UT_DEBUG_
283+
std::cerr << "size[" << size() << "], Factor[" << Factor << "], capability[" << capability() << "]!\n";
249284
#endif
285+
grow();
286+
}
250287
const hash_type key = hasher()(target);
251288
const size_type lv = rl_();
252289
std::vector<iterator> predecessors = find_predecessors(key, lv);
@@ -277,7 +314,7 @@ class skiplist {
277314
void erase(const value_type& target,
278315
const erase_policy policy = erase_policy::ALL) {
279316
#ifdef LIAM_UT_DEBUG_
280-
std::cerr << "erasing [" << target << "]!!!!!!!!!!!!!!!!!!!!\n";
317+
std::cerr << "erasing [" << target << "]!\n";
281318
#endif
282319
const hash_type key = hasher()(target);
283320
std::vector<iterator> predecessors = find_predecessors(key, max_lv_);

c-cpp/17_skiplist/skiplist_tr_test.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ int main() {
2323
// 2. UT for skiplist(), init_internally(), size(), empty()
2424
skiplist<std::string> sl_default;
2525
assert(sl_default.empty());
26+
// 2.1. UT for grow with abandon
27+
sl_default.grow(1);
28+
assert(sl_default.capability() == 4);
29+
// 2.2. UT for grow
30+
sl_default.grow(10);
31+
assert(sl_default.capability() == 1024);
2632

2733
// 3. UT for constructor of initializer_list and InputIt, init_internally(), insert(),
2834
// find_predecessors()
@@ -81,7 +87,7 @@ int main() {
8187
assert(search != sl.cend());
8288
assert(search != sl.end());
8389
assert(search->values.count("world") == 2);
84-
// 7.1. same word
90+
// 7.1. same word, also UT for grow()
8591
search = sl.find("hello");
8692
assert(search == sl.cend());
8793
assert(search == sl.end());

0 commit comments

Comments
 (0)