
org.summerb.utils.collection.OneWayList Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of summerb Show documentation
Show all versions of summerb Show documentation
summerb - is a set of building blocks for real-world java-based web apps
package org.summerb.utils.collection;
import java.util.Iterator;
import com.google.common.base.Preconditions;
/**
* This is one way linked list intended for use in concurrent scenarios where we
* try to avoid using locking (lock-free algorithms). It is not completely lock
* free, but at least for read it's lock free.
*
* @author sergeyk
*
* @param
*/
public class OneWayList implements Iterable {
private volatile Entry first;
private volatile Entry last;
private Object syncRoot = new Object();
public OneWayList() {
}
public boolean isEmpty() {
return first == null;
}
public T getFirst() {
Entry f = first;
return f == null ? null : f.data;
}
public T getLast() {
Entry l = last;
return l == null ? null : l.data;
}
@Override
public OneWayIterator iterator() {
return new OneWayIterator(first);
}
public void append(T data) {
Entry newEntry = new Entry(data);
if (first == null) {
first = last = newEntry;
return;
}
Entry curLast = last;
last = newEntry;
curLast.next = newEntry;
}
public void appendThreadSafe(T data) {
synchronized (syncRoot) {
append(data);
}
}
public class OneWayIterator implements Iterator {
private Entry current;
private Entry startingElement;
private Entry prevCur;
public OneWayIterator(Entry first) {
this.startingElement = first;
}
@Override
public boolean hasNext() {
Entry cur = getCurrent();
if (cur == null) {
return startingElement != null;
}
return cur.next != null;
}
@Override
public T next() {
if (!hasNext()) {
throw new IndexOutOfBoundsException("No more elements");
}
Entry cur = getCurrent();
if (cur == null) {
setCurrent(startingElement);
return startingElement.data;
}
Entry next = cur.next;
setCurrent(next);
return next.data;
}
public void shiftListHead() {
Entry cur = getCurrent();
if (cur == null) {
throw new IndexOutOfBoundsException("No more elements");
}
OneWayList.this.first = (Entry) cur;
}
public void insertNewBeforeCurrent(T newItem) {
Preconditions.checkState(current != null, "Cannot insertNewBeforeCurrent for iteration that not started");
Entry e = new Entry(newItem);
e.next = current;
if (prevCur == null) {
// ok, this is new first item
first = e;
} else {
// ok, inserted item in the middle
prevCur.next = e;
}
}
@Override
public void remove() {
throw new IllegalStateException("Remove operation is not supported by OneWayList");
}
private Entry getCurrent() {
return current;
}
private void setCurrent(Entry cur) {
prevCur = this.current;
this.current = cur;
}
}
private static class Entry {
T data;
volatile Entry next;
public Entry(T data) {
this.data = data;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy