package linkedlists.lockbased;
import java.util.Collection;
import java.util.Random;
import linkedlists.lockbased.lazyutils.Node;
import contention.abstractions.AbstractCompositionalIntSet;
/**
* The code follows the lazy list-based set of Ch.9 of Herlihy and Shavit's book:
* "The Art of Multiprocessor Programming".
*
* @author gramoli
*
*/
public class LazyListBasedSet extends AbstractCompositionalIntSet {
final public Node head;
final public Node tail;
public LazyListBasedSet() {
head = new Node(Integer.MIN_VALUE);
tail = new Node(Integer.MAX_VALUE);
head.next = tail;
tail.next = null;
}
@Override
public void fill(int range, long size) {
int i = 0;
while (i < size)
if (addInt(new Random().nextInt(range)))
i++;
}
private boolean validate(Node pred, Node curr) {
return !pred.marked && pred.next == curr;
}
@Override
public boolean addInt(int v) {
while (true) {
Node pred = head;
Node curr = head.next;
while (curr.value < v) {
pred = curr;
curr = curr.next;
}
pred.lock();
curr.lock();
try {
if (validate(pred, curr)) {
if (curr.value == v) {
return false;
} else {
Node node = new Node(v);
node.next = curr;
pred.next = node;
return true;
}
}
} finally {
curr.unlock();
pred.unlock();
}
}
}
@Override
public boolean removeInt(int v) {
while (true) {
Node pred = head;
Node curr = head.next;
while (curr.value < v) {
pred = curr;
curr = curr.next;
}
pred.lock();
try {
curr.lock();
try {
if (validate(pred, curr)) {
if (curr.value != v) {
return false;
} else {
curr.marked = true;
pred.next = curr.next;
return true;
}
}
} finally {
curr.unlock();
}
} finally {
pred.unlock();
}
}
}
@Override
public boolean containsInt(int v) {
Node curr = head;
while (curr.value < v) {
curr = curr.next;
}
return curr.value == v && !curr.marked;
}
@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() {
int cpt = 0;
Node curr = head;
while (curr.value < Integer.MAX_VALUE)
curr = curr.next;
if (!curr.marked)
cpt++;
return cpt;
}
@Override
public void clear() {
head.next = tail;
}
}