package linkedlists.transactional; import java.util.Collection; import java.util.Random; import java.util.Stack; import org.deuce.Atomic; import contention.abstractions.CompositionalIntSet; import contention.abstractions.CompositionalIterator; /** * Linked list implementation of integer set using * Elastic transactions as described in: * * P. Felber, V. Gramoli, R. Guerraoui. Elastic * Transactions. DISC 2009. * * @author Vincent Gramoli * */ public class ElasticLinkedListIntSet implements CompositionalIntSet { /** The first node of the list */ final private Node head; /** The thread-private PRNG */ final private static ThreadLocal<Random> s_random = new ThreadLocal<Random>() { @Override protected synchronized Random initialValue() { return new Random(); } }; public ElasticLinkedListIntSet() { Node min = new Node(Integer.MIN_VALUE); Node max = new Node(Integer.MAX_VALUE); min.setNext(max); head = min; } @Atomic(metainf = "elastic") public boolean addInt(int value) { boolean result; Node previous = head; Node next = previous.getNext(); int v; while ((v = next.getValue()) < value) { previous = next; next = previous.getNext(); } result = v != value; if (result) { previous.setNext(new Node(value, next)); } return result; } @Atomic(metainf = "elastic") public boolean removeInt(int value) { boolean result; Node previous = head; Node next = previous.getNext(); int v; while ((v = next.getValue()) < value) { previous = next; next = previous.getNext(); } result = v == value; if (result) { previous.setNext(next.getNext()); } return result; } @Atomic(metainf = "elastic") public boolean containsInt(int value) { boolean result; Node previous = head; Node next = previous.getNext(); int v; while ((v = next.getValue()) < value) { previous = next; next = previous.getNext(); } result = (v == value); return result; } @Override @Atomic(metainf = "elastic") public boolean addAll(Collection<Integer> c) { boolean result = true; for (Integer x : c) result &= this.addInt(x); return result; } @Override @Atomic(metainf = "elastic") public boolean removeAll(Collection<Integer> c) { boolean result = true; for (Integer x : c) result &= this.removeInt(x); return result; } @Atomic(metainf = "regular") public int size() { int n = 0; Node node = head; while (node.getNext().getValue() < Integer.MAX_VALUE) { n++; node = node.getNext(); } return n; } @Override public void fill(final int range, final long size) { while (this.size() < size) { this.addInt(s_random.get().nextInt(range)); } } public class Node { final private int value; private Node next; public Node(int value, Node next) { this.value = value; this.next = next; } public Node(int value) { this(value, null); } public int getValue() { return value; } public void setNext(Node next) { this.next = next; } public Node getNext() { return next; } } public class LLIterator implements CompositionalIterator<Integer> { Node next = head; Stack<Node> stack = new Stack<Node>(); LLIterator() { while (next != null) { stack.push(next.next); } } public boolean hasNext() { return next != null; } public void remove() { throw new UnsupportedOperationException(); } public Integer next() { Node node = next; next = stack.pop(); return node.getValue(); } } public void clear() { Node max = new Node(Integer.MAX_VALUE); head.setNext(max); } @Override public Object getInt(int x) { // TODO Auto-generated method stub return null; } @Override public Object putIfAbsent(int x, int y) { // TODO Auto-generated method stub return null; } }