Skip to content

Commit

Permalink
[cpp][17_skiplist] impl of find and find_helper, and their unit test.
Browse files Browse the repository at this point in the history
  • Loading branch information
Liam0205 committed Oct 31, 2018
1 parent f298cda commit 804d6f6
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 10 deletions.
63 changes: 53 additions & 10 deletions c-cpp/17_skiplist/skiplist_tr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,18 @@ class random_level {
} // namespace skiplist_detail

template <typename Value,
typename Compare = std::less<Value>,
typename Hash = std::hash<Value>>
class skiplist {
public:
using value_type = Value;
using compare = Compare;
using size_type = size_t;
using hasher = Hash;
using hash_type = typename Hash::result_type;
using node_type = skiplist_detail::InternalNode<hash_type, value_type>;
using container = std::list<node_type>;
using iterator = typename container::iterator;
using value_type = Value;
using size_type = size_t;
using hasher = Hash;
using hash_type = typename Hash::result_type;
using compare = std::less<hash_type>;
using node_type = skiplist_detail::InternalNode<hash_type, value_type>;
using container = std::list<node_type>;
using iterator = typename container::iterator;
using const_iterator = typename container::const_iterator;
static_assert(std::is_same<iterator, typename node_type::iterator>::value,
"STATIC ASSERT FAILED! iterator type differs.");

Expand Down Expand Up @@ -117,11 +117,29 @@ class skiplist {
for (auto it : std::next(cont_.begin())->forwards) {
assert(it == cont_.end());
}
std::cerr << "all assert in init() success!\n";
std::cerr << "UT_DEBUG: all assert in init() success!\n";
#endif

return;
}
/**
* @brief return a const_iterator points to the last element
* such that its hash_key <= target_hash_key
*/
const_iterator find_helper(const hash_type& key) const {
const_iterator iter = cont_.begin();
for (size_type i = 0; i != max_lv_; ++i) {
size_type focus = max_lv_ - 1 - i;
// invariant: iter->key <= key
for (const_iterator forward = iter->forwards[focus];
forward != cont_.end() and not compare()(forward->key, key);
forward = iter->forwards[focus]) {
iter = forward;
}
// result: iter->key <= key and iter->forwards[focus]->key > key
}
return iter;
}

public:
size_type size() const {
Expand All @@ -130,6 +148,31 @@ class skiplist {
bool empty() const {
return size() == 0;
}
iterator begin() {
return cont_.begin();
}
const_iterator begin() const {
return cont_.cbegin();
}
const_iterator cbegin() const {
return cont_.cbegin();
}
iterator end() {
return cont_.end();
}
const_iterator end() const {
return cont_.cend();
}
const_iterator cend() const {
return cont_.cend();
}

public:
const_iterator find(const value_type& target) const {
const hash_type key = hasher()(target);
const_iterator iter = find_helper(key);
return (iter->key == key) ? iter : cont_.end();
}
};

#endif // SKIPLIST_SKIPLIST_TR_HPP_
Expand Down
5 changes: 5 additions & 0 deletions c-cpp/17_skiplist/skiplist_tr_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ int main() {
// 2. UT for skiplist(), init(), size(), empty()
skiplist<std::string> sl_default;
assert(sl_default.empty());

// 3. UT for find() [nonexist element]
auto search = sl_default.find("nonexist");
assert(search == sl_default.cend());
assert(search == sl_default.end());
return 0;
}

0 comments on commit 804d6f6

Please sign in to comment.