package skiplists.transactional;
import java.util.Collection;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import org.deuce.Atomic;
import contention.abstractions.CompositionalIntSet;
import contention.abstractions.CompositionalMap;
/**
* The Transactional Skip List implementation of integer set
*
* @author Vincent Gramoli
*
*/
public class TransactionalPughSkipListSet<K, V> implements CompositionalIntSet,
CompositionalMap<K, V> {
/** The maximum number of levels */
final private int maxLevel;
/** The first element of the list */
final public Node head;
/** The thread-private PRNG, used for fil(), not for height/level determination. */
final private static ThreadLocal<Random> s_random = new ThreadLocal<Random>() {
@Override
protected synchronized Random initialValue() {
return new Random();
}
};
public TransactionalPughSkipListSet() {
this(31);
}
public TransactionalPughSkipListSet(final int maxLevel) {
this.maxLevel = maxLevel;
this.head = new Node(maxLevel, Integer.MIN_VALUE);
final Node tail = new Node(maxLevel, Integer.MAX_VALUE);
for (int i = 0; i <= maxLevel; i++) {
head.setNext(i, tail);
}
}
public void fill(final int range, final long size) {
while (this.size() < size) {
this.addInt(s_random.get().nextInt(range));
}
}
protected int randomLevel() {
return Math.min((maxLevel - 1), (skiplists.RandomLevelGenerator.randomLevel()));
}
@Atomic(metainf = "NT")
public void test(int a) {
a = a + 1;
}
@Override
@Atomic(metainf = "elastic")
public boolean containsInt(final int value) {
boolean result;
Node node = head;
for (int i = maxLevel; i >= 0; i--) {
Node next = node.getNext(i);
while (next.getValue() < value) {
node = next;
next = node.getNext(i);
}
}
node = node.getNext(0);
result = (node.getValue() == value);
return result;
}
@Override
public Object getInt(final int value) {
if (containsInt(value))
return value;
else
return null;
}
@Override
@Atomic(metainf = "elastic")
public boolean addInt(final int value) {
if (containsInt(value))
return false;
boolean result;
Node[] update = new Node[maxLevel + 1];
Node node = head;
for (int i = maxLevel; i >= 0; i--) {
Node next = node.getNext(i);
while (next.getValue() < value) {
node = next;
next = node.getNext(i);
}
update[i] = node;
}
node = node.getNext(0);
if (node.getValue() == value) {
result = false;
} else {
int level = randomLevel();
node = new Node(level, value);
for (int i = 0; i <= level; i++) {
node.setNext(i, update[i].getNext(i));
update[i].setNext(i, node);
}
result = true;
}
return result;
}
@Override
@Atomic(metainf = "elastic")
public boolean removeInt(int value) {
if (!containsInt(value))
return false;
boolean result;
Node[] update = new Node[maxLevel + 1];
Node node = head;
for (int i = maxLevel; i >= 0; i--) {
Node next = node.getNext(i);
while (next.getValue() < value) {
node = next;
next = node.getNext(i);
}
update[i] = node;
}
node = node.getNext(0);
if (node.getValue() != value) {
result = false;
} else {
int maxLevel = node.getLevel();
for (int i = 0; i <= maxLevel; i++) {
update[i].setNext(i, node.getNext(i));
}
result = true;
}
return result;
}
@Override
@Atomic(metainf = "elastic")
public boolean addAll(Collection<Integer> c) {
boolean result = true;
for (int x : c)
result &= this.addInt(x);
return result;
}
@Override
@Atomic(metainf = "elastic")
public boolean removeAll(Collection<Integer> c) {
boolean result = true;
for (int x : c)
if (!removeInt(x))
result = false;
return result;
}
@Override
@Atomic(metainf = "regular")
public int size() {
int s = 0;
Node node = head.getNext(0).getNext(0);
while (node != null) {
node = node.getNext(0);
s++;
}
return s;
}
@Override
@Atomic
public String toString() {
// String str = new String();
// Node curr = head;
// int i, j;
// final int[] arr = new int[maxLevel+1];
//
// for (i=0; i<= maxLevel; i++) arr[i] = 0;
//
// do {
// str += curr.toString();
// arr[curr.getLevel()]++;
// curr = curr.getNext(0);
// } while (curr != null);
// for (j=0; j < maxLevel; j++)
// str += arr[j] + " nodes of level " + j + " ";
// return str;
return getBottom();
}
public String getBottom() {
String str = new String();
Node curr = head.getNext(0);
do {
str += curr.toString();
curr = curr.getNext(0);
} while (curr != null);
return str;
}
public class Node<K, V> {
final private int value;
final private Node[] next;
public Node(final int level, final int value) {
this.value = value;
next = new Node[level + 1];
}
public int getValue() {
return value;
}
public int getLevel() {
return next.length - 1;
}
public void setNext(final int level, final Node succ) {
next[level] = succ;
}
public Node getNext(final int level) {
return next[level];
}
@Override
public String toString() {
String result = "";
result += "<l=" + getLevel() + ",v=" + value + ">:";
for (int i = 0; i <= getLevel(); i++) {
result += " @[" + i + "]=";
if (next[i] != null) {
result += next[i].getValue();
} else {
result += "null";
}
}
return result;
}
}
// public class SLIterator implements CompositionalIterator<Integer> {
// Node next = head;
// Stack<Node> stack = new Stack<Node>();
//
// SLIterator() {
// while (next != null) {
// stack.push(next.next[0]);
// }
// }
//
// public boolean hasNext() {
// return next != null;
// }
//
// public void remove() {
// throw new UnsupportedOperationException();
// }
//
// public Integer next() {
// Node node = next;
// next = stack.pop();
// return node.getValue();
// }
// }
/**
* This is called after the JVM warmup phase to make sure the data structure
* is well initalized. No need to do anything for this.
*/
public void clear() {
return;
}
// @Override
// @Atomic(metainf = "regular")
// public Object putIfAbsent(final int x, final int y) {
// if (!contains(y))
// add(x);
// return null;
// }
@Override
@Atomic(metainf = "regular")
public V putIfAbsent(K x, V y) {
if (!containsInt((Integer) y))
addInt((Integer) x);
return null;
}
@Override
@Atomic(metainf = "regular")
public Object putIfAbsent(int x, int y) {
if (!containsInt(y))
addInt(x);
return null;
}
@Override
public V get(Object key) {
if (containsInt((Integer) key))
return (V) key;
else
return null;
}
// @Override
// public V putIfAbsent(K k, V v) {
// // TODO Auto-generated method stub
// return null;
// }
@Override
public V remove(Object key) {
if (removeInt((Integer) key))
return (V) key;
else
return null;
}
@Override
public boolean containsKey(Object key) {
return containsInt((Integer) key);
}
@Override
public boolean containsValue(Object value) {
// TODO Auto-generated method stub
return false;
}
@Override
public Set<java.util.Map.Entry<K, V>> entrySet() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return false;
}
@Override
public Set<K> keySet() {
// TODO Auto-generated method stub
return null;
}
@Override
public V put(K key, V value) {
// TODO Auto-generated method stub
return null;
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
// TODO Auto-generated method stub
}
@Override
public Collection<V> values() {
// TODO Auto-generated method stub
return null;
}
}