package de.invesdwin.util.collections.concurrent; import java.lang.reflect.Array; import java.util.Collection; import javax.annotation.concurrent.NotThreadSafe; import de.invesdwin.util.collections.ADelegateList; import de.invesdwin.util.collections.iterable.ICloseableIterable; import de.invesdwin.util.collections.iterable.ICloseableIterator; import de.invesdwin.util.collections.iterable.buffer.BufferingIterator; @NotThreadSafe public abstract class AFastIterableDelegateList<E> extends ADelegateList<E> implements ICloseableIterable<E> { //arraylist wins in raw iterator speed compared to bufferingIterator since no remove is needed, though we need protection against concurrent modification private BufferingIterator<E> fastIterable; private E[] array; private boolean empty; private int size; public AFastIterableDelegateList() { refreshFastIterable(); } @Override public boolean add(final E e) { final boolean added = super.add(e); if (added) { addToFastIterable(e); } return added; } protected void addToFastIterable(final E e) { if (fastIterable != null) { fastIterable.add(e); } array = null; empty = false; size++; } @Override public boolean addAll(final Collection<? extends E> c) { final boolean added = super.addAll(c); if (added) { refreshFastIterable(); } return added; } @Override public boolean addAll(final int index, final Collection<? extends E> c) { final boolean added = super.addAll(index, c); if (added) { refreshFastIterable(); } return added; } @Override public void add(final int index, final E element) { super.add(index, element); refreshFastIterable(); } @Override public boolean remove(final Object o) { final boolean removed = super.remove(o); if (removed) { refreshFastIterable(); } return removed; } @Override public boolean removeAll(final Collection<?> c) { final boolean removed = super.removeAll(c); if (removed) { refreshFastIterable(); } return removed; } @Override public E remove(final int index) { final E removed = super.remove(index); refreshFastIterable(); return removed; } /** * protected so it can be used inside addToFastIterable to refresh instead if desired by overriding */ protected void refreshFastIterable() { fastIterable = null; array = null; size = getDelegate().size(); empty = size == 0; } @Override public void clear() { super.clear(); fastIterable = new BufferingIterator<E>(); array = null; empty = true; size = 0; } @Override public ICloseableIterator<E> iterator() { if (fastIterable == null) { fastIterable = new BufferingIterator<E>(getDelegate()); } return fastIterable.iterator(); } @Override public boolean isEmpty() { return empty; } @Override public int size() { return size; } @SuppressWarnings("unchecked") public E[] asArray(final Class<E> type) { if (array == null) { final E[] empty = (E[]) Array.newInstance(type, size()); array = toArray(empty); } return array; } }