package linkedlists.lockfree;
import java.util.Collection;
import contention.abstractions.AbstractCompositionalIntSet;
/**
* A Java variant of Harris-Michael that uses run-time type identification to
* determine whether a node is marked as logically deleted. This is the code
* used in:
*
* A Concurrency-Optimal List-Based Set. Gramoli, Kuznetsov, Ravi, Shang. 2015.
*
* @author Di Shang
*/
public class NonBlockingLinkedListSetRTTI extends AbstractCompositionalIntSet {
private final NodeLinked tail;
private final NodeLinked head;
public NonBlockingLinkedListSetRTTI() {
tail = new NodeLinked(Integer.MAX_VALUE, null);
head = new NodeLinked(Integer.MIN_VALUE, tail);
}
class Window {
public NodeBase pred, curr;
public Window(NodeBase pred, NodeBase curr) {
this.pred = pred;
this.curr = curr;
}
}
public Window find(NodeBase head, int value) {
NodeBase pred = null, curr = null, succ = null;
boolean snip;
NodeLinked notMarked;
retry: while (true) {
pred = head;
curr = pred.next();
while (true) {
succ = curr.next();
while (succ instanceof NodeMarked) {
notMarked = ((NodeMarked) succ).getNonMarked();
snip = pred.casNext(curr, notMarked);
if (!snip) {
continue retry;
}
curr = notMarked;
succ = curr.next();
}
if (curr.value() >= value) {
return new Window(pred, curr);
}
pred = curr;
curr = succ;
}
}
}
@Override
public void fill(int range, long size) {
throw new RuntimeException("unimplemented method");
// TODO Auto-generated method stub
}
@Override
public boolean addInt(int x) {
while (true) {
Window window = find(head, x);
NodeBase pred = window.pred, curr = window.curr;
if (curr.value() == x) {
return false;
} else {
NodeLinked node = new NodeLinked(x, curr);
if (pred.casNext(curr, node)) {
return true;
}
}
}
}
@Override
public boolean removeInt(int x) {
boolean snip;
while (true) {
Window window = find(head, x);
NodeBase pred = window.pred, curr = window.curr;
if (curr.value() != x) {
return false;
} else {
NodeBase succ = curr.next();
if (succ instanceof NodeMarked) {
continue;
}
snip = curr.casNext(succ, new NodeMarked((NodeLinked) succ));
if (!snip) {
continue;
}
pred.casNext(curr, succ);
return true;
}
}
}
@Override
public boolean containsInt(int x) {
NodeBase curr = head;
while (curr.value() < x) {
curr = curr.next();
}
return (curr.value() == x && !(curr.next() instanceof NodeMarked));
}
@Override
public Object getInt(int x) {
throw new RuntimeException("unimplemented method");
// TODO Auto-generated method stub
}
@Override
public boolean addAll(Collection<Integer> c) {
throw new RuntimeException("unimplemented method");
// TODO Auto-generated method stub
}
@Override
public boolean removeAll(Collection<Integer> c) {
throw new RuntimeException("unimplemented method");
// TODO Auto-generated method stub
}
@Override
public int size() {
NodeBase succ;
int size = 0;
for (NodeBase curr = head.next(); curr != tail;) {
succ = curr.next();
if (!(succ instanceof NodeMarked)) {
size++;
}
curr = succ;
}
return size;
}
@Override
public void clear() {
head.setNext(tail);
}
}