Skip to content

Commit

Permalink
[cpp][17_skiplist] automatically grow within insertion.
Browse files Browse the repository at this point in the history
  • Loading branch information
Liam0205 committed Nov 1, 2018
1 parent 3c3e28e commit 97db79d
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 6 deletions.
47 changes: 42 additions & 5 deletions c-cpp/17_skiplist/skiplist_tr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ class random_level {
enum class erase_policy { ALL, SINGLE };

template <typename Value,
typename Hash = std::hash<Value>>
typename Hash = std::hash<Value>,
size_t Factor = 2>
class skiplist {
public:
using value_type = Value;
Expand All @@ -65,7 +66,7 @@ class skiplist {
"STATIC ASSERT FAILED! iterator type differs.");

private:
size_type max_lv_ = 8;
size_type max_lv_ = 2;
double prob_ = 0.5;
mutable skiplist_detail::random_level<size_type> rl_;
container cont_;
Expand Down Expand Up @@ -233,20 +234,56 @@ class skiplist {
const_iterator cend() const {
return cont_.cend();
}
void grow(const size_type new_max_lv) {
if (max_lv_ < new_max_lv) {
#ifdef LIAM_UT_DEBUG_
std::cerr << "grow from [" << max_lv_ << "] to ["
<< new_max_lv << "]!\n";
#endif
max_lv_ = new_max_lv;

iterator tail = std::prev(cont_.end());
auto beg_tail = tail->forwards.end();
tail->forwards.resize(max_lv_, cont_.end());

iterator head = cont_.begin();
auto beg_head = head->forwards.end();
head->forwards.resize(max_lv_, tail);

return;
} else {
#ifdef LIAM_UT_DEBUG_
std::cerr << "abandon growing!\n";
#endif
return;
}
}
void grow() {
grow(Factor * max_lv_);
}
size_type capability() const {
return std::pow(Factor, max_lv_);
}

public:
const_iterator find(const value_type& target) const {
#ifdef LIAM_UT_DEBUG_
std::cerr << "finding [" << target << "]!!!!!!!!!!!!!!!!!!!!\n";
std::cerr << "finding [" << target << "]!\n";
#endif
const hash_type key = hasher()(target);
const_iterator iter = find_helper(key);
return (iter->key == key) ? iter : cont_.end();
}
void insert(const value_type& target) {
#ifdef LIAM_UT_DEBUG_
std::cerr << "inserting [" << target << "]!!!!!!!!!!!!!!!!!!!!\n";
std::cerr << "inserting [" << target << "]!\n";
#endif
if (size() > static_cast<double>(Factor - 1) / Factor * capability()) {
#ifdef LIAM_UT_DEBUG_
std::cerr << "size[" << size() << "], Factor[" << Factor << "], capability[" << capability() << "]!\n";
#endif
grow();
}
const hash_type key = hasher()(target);
const size_type lv = rl_();
std::vector<iterator> predecessors = find_predecessors(key, lv);
Expand Down Expand Up @@ -277,7 +314,7 @@ class skiplist {
void erase(const value_type& target,
const erase_policy policy = erase_policy::ALL) {
#ifdef LIAM_UT_DEBUG_
std::cerr << "erasing [" << target << "]!!!!!!!!!!!!!!!!!!!!\n";
std::cerr << "erasing [" << target << "]!\n";
#endif
const hash_type key = hasher()(target);
std::vector<iterator> predecessors = find_predecessors(key, max_lv_);
Expand Down
8 changes: 7 additions & 1 deletion c-cpp/17_skiplist/skiplist_tr_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ int main() {
// 2. UT for skiplist(), init_internally(), size(), empty()
skiplist<std::string> sl_default;
assert(sl_default.empty());
// 2.1. UT for grow with abandon
sl_default.grow(1);
assert(sl_default.capability() == 4);
// 2.2. UT for grow
sl_default.grow(10);
assert(sl_default.capability() == 1024);

// 3. UT for constructor of initializer_list and InputIt, init_internally(), insert(),
// find_predecessors()
Expand Down Expand Up @@ -81,7 +87,7 @@ int main() {
assert(search != sl.cend());
assert(search != sl.end());
assert(search->values.count("world") == 2);
// 7.1. same word
// 7.1. same word, also UT for grow()
search = sl.find("hello");
assert(search == sl.cend());
assert(search == sl.end());
Expand Down

0 comments on commit 97db79d

Please sign in to comment.