package linkedlists.lockbased;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.Set;
import contention.abstractions.CompositionalIntSet;
import linkedlists.sequential.SequentialLinkedListIntSet;
/*
* Lock-based Linked List based on the sequential version
* using the Collections.SynchronizedList wrapper that acts
* as a coarse-grained lock but offers reusability as
* described in:
*
* V. Gramoli and R. Guerraoui. Reusable Concurrent Data
* Types. ECOOP 2014.
*
* @author Vincent Gramoli
*
*/
public class LockedLinkedListIntSet implements CompositionalIntSet {
private List<Integer> s;
/** The thread-private PRNG */
final private static ThreadLocal<Random> s_random = new ThreadLocal<Random>() {
@Override
protected synchronized Random initialValue() {
return new Random();
}
};
public LockedLinkedListIntSet() {
s = (List<Integer>) Collections.synchronizedList(new LinkedList<Integer>());
}
@Override
public boolean addInt(int x) {
return s.add(x);
}
@Override
public boolean addAll(Collection<Integer> c) {
boolean result = true;
synchronized(s) {
for (Integer x : c) result &= s.add(x);
}
return result;
}
@Override
public boolean containsInt(int x) {
return s.contains(x);
}
/**
* {@inheritDoc}
* Does not need to be made thread-safe
*/
@Override
public void fill(int range, long size) {
while (this.size() < size) {
this.addInt(s_random.get().nextInt(range));
}
}
@Override
public boolean removeInt(int x) {
return s.remove((Object) new Integer(x));
}
/**
* {@inheritDoc}
* Iterating method that is manually synchronized
*/
@Override
public boolean removeAll(Collection<Integer> c) {
boolean result = true;
synchronized(s) {
for (Integer x : c) result &= this.removeInt(x);
}
return result;
}
/**
* {@inheritDoc}
* Iterating method that is manually synchronized
*/
@Override
public int size() {
synchronized(s) {
return s.size();
}
}
/**
* 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
public Object getInt(int x) {
if (!containsInt(x)) return false;
return x;
}
@Override
public Object putIfAbsent(int x, int y) {
synchronized(s) {
if (!containsInt(x)) addInt(y);
}
return null;
}
}