-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNonBlockingBST.cpp
83 lines (70 loc) · 2.01 KB
/
NonBlockingBST.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: NonBlockingBST.cpp
* Author: devesh
*
* Created on 14 April, 2016, 12:37 AM
*/
#include <atomic>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include "BSTclass.h"
using namespace std;
bool NonBlockingBST::insert(int k)
{
treeNode *p, *newInternal, *l, *newSibling, *newNode;
infoRecord * op;
newNode = new treeNode(k, true);
while(true) {
searchResult * s = search(k);
p = s->p.load();
l = s->l.load();
updateRecord &pupdate = s->pupdate;
if (l->data == k) return false; // data already found
if (pupdate.isDirty)
// help whoever else is trying to insert
helpInsert(pupdate.info);
else {
newSibling = new treeNode(l->data, true);
if (newNode->data < newSibling->data)
newInternal = new treeNode(max(k, l->data), false, newNode, newSibling);
else
newInternal = new treeNode(max(k, l->data), false, newSibling, newNode);
op = new infoRecord(p, l, newInternal);
updateRecord dirty = {true, op};
bool iflag = p->update.compare_exchange_strong(pupdate, dirty);
if (iflag) {
helpInsert(op);
return true;
}
else
helpInsert(pupdate.info);
}
}
}
void NonBlockingBST::helpInsert(infoRecord* op)
{
treeNode *p, *l, *s;
p = op->parent.load();
l = op->leaf.load();
s = op->subtree.load();
updateRecord dirty = {true, op},
clean = {false, op};
CASChild(p, l, s);
op->parent.load()->update.
compare_exchange_strong(dirty, clean);
}
bool NonBlockingBST::CASChild(treeNode *parent, treeNode *oldNode, treeNode *newNode)
{
atomic<treeNode*> *childToChange;
if (newNode->data < parent->data)
childToChange = &(parent->left);
else
childToChange = &(parent->right);
return childToChange->compare_exchange_strong(oldNode, newNode);
}