Skiplist minor bugfixes

Summary: Skiplist - fixed support for insertion of (const T&) objects. Before only (T&&) worked.

Test Plan: Tested already with slightliy modified tests.

Reviewers: buda

Reviewed By: buda

Subscribers: pullbot, florijan, buda

Differential Revision: https://phabricator.memgraph.io/D48
This commit is contained in:
Florijan Stamenkovic 2017-02-07 11:19:14 +01:00
parent 10c7514c8a
commit 6d981c9cd0
2 changed files with 53 additions and 7 deletions

View File

@ -145,7 +145,11 @@ class SkipList : private Lockable<lock_t> {
}
static Node *create(const T &item, uint8_t height) {
return create(height, item);
auto node = allocate(height);
// we have raw memory and we need to construct an object
// of type Node on it
return new (node) Node(item, height);
}
static Node *create(T &&item, uint8_t height) {
@ -188,6 +192,10 @@ class SkipList : private Lockable<lock_t> {
this->data.emplace(std::forward<Args>(args)...);
}
Node(const T &data, uint8_t height) : Node(height) {
this->data.set(data);
}
Node(T &&data, uint8_t height) : Node(height) {
this->data.set(std::move(data));
}
@ -940,6 +948,42 @@ class SkipList : private Lockable<lock_t> {
}
}
/**
* Insert unique data
*
* F - type of funct which will create new node if needed. Recieves height
* of node.
*/
// TODO this code is not DRY w.r.t. the other insert function (rvalue ref)
std::pair<Iterator, bool> insert(Node *preds[], Node *succs[], const T &data) {
while (true) {
// TODO: before here was data.first
auto level = find_path(this, H - 1, data, preds, succs);
if (level != -1) {
auto found = succs[level];
if (found->flags.is_marked()) continue;
while (!found->flags.is_fully_linked()) usleep(250);
return {Iterator{succs[level]}, false};
}
auto height = rnd();
guard_t guards[H];
// try to acquire the locks for predecessors up to the height of
// the new node. release the locks and try again if someone else
// has the locks
if (!lock_nodes<true>(height, guards, preds, succs)) continue;
return {insert_here(Node::create(data, height), preds, succs,
height, guards),
true};
}
}
/**
* Insert unique data
*

View File

@ -15,7 +15,7 @@ int main()
init_log();
memory_check(THREADS_NO, [] {
set_t skiplist;
ConcurrentSet<std::string> skiplist;
auto futures = run<std::vector<long>>(
THREADS_NO, skiplist, [](auto acc, auto index) {
@ -25,14 +25,16 @@ int main()
std::vector<long> set(key_range);
do {
size_t num = rand();
int num = rand();
std::string num_str = std::to_string(num);
if (rand_op()) {
if (acc.remove(num)) {
if (acc.remove(num_str)) {
downcount--;
set[num]--;
}
} else {
if (acc.insert(num).second) {
std::string num_str = std::to_string(num);
if (acc.insert(num_str).second) {
downcount--;
set[num]++;
}
@ -52,12 +54,12 @@ int main()
auto accessor = skiplist.access();
for (int i = 0; i < key_range; i++) {
permanent_assert(set[i] == 0 || set[i] == 1 ||
(set[i] == 1) ^ accessor.contains(i),
(set[i] == 1) ^ accessor.contains(std::to_string(i)),
"Set doesn't hold it's guarantees.");
}
for (auto &e : accessor) {
set[e]--;
set[std::stoi(e)]--;
}
check_zero(key_range, set, "Set");