Move CachedIteratorArrayList from core to router

This commit is contained in:
zzz
2016-01-14 13:54:53 +00:00
parent 308c9da384
commit cdfd4ca2f4
3 changed files with 4 additions and 4 deletions

View File

@ -17,9 +17,9 @@ import net.i2p.data.Hash;
import net.i2p.data.SessionKey;
import net.i2p.router.OutNetMessage;
import net.i2p.router.RouterContext;
import net.i2p.router.util.CachedIteratorArrayList;
import net.i2p.router.util.CoDelPriorityBlockingQueue;
import net.i2p.router.util.PriBlockingQueue;
import net.i2p.util.CachedIteratorArrayList;
import net.i2p.util.Log;
import net.i2p.util.ConcurrentHashSet;

View File

@ -0,0 +1,109 @@
package net.i2p.router.util;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* ArrayList that uses a single iterator. Useful to avoid object churn
* while keeping the conveniences of an iterator.
*
* @since 0.9.4 moved from net.i2p.util in 0.9.24
*
* @author zab
*/
public class CachedIteratorArrayList<E> extends ArrayList<E> {
private static final long serialVersionUID = 4863212596318574111L;
private final CachedIterator iterator = new CachedIterator();
public CachedIteratorArrayList() {
super();
}
public CachedIteratorArrayList(Collection<? extends E> c) {
super(c);
}
public CachedIteratorArrayList(int initialCapacity) {
super(initialCapacity);
}
@Override
public Iterator<E> iterator() {
iterator.reset();
return iterator;
}
private class CachedIterator implements Iterator<E>, Serializable {
/**
* Index of element to be returned by subsequent call to next.
*/
int cursor = 0;
/**
* Index of element returned by most recent call to next or
* previous. Reset to -1 if this element is deleted by a call
* to remove.
*/
int lastRet = -1;
/**
* The modCount value that the iterator believes that the backing
* List should have. If this expectation is violated, the iterator
* has detected concurrent modification.
*/
int expectedModCount = modCount;
void reset() {
cursor = 0;
lastRet = -1;
expectedModCount = modCount;
}
public boolean hasNext() {
return cursor != size();
}
public E next() {
checkForComodification();
try {
int i = cursor;
E next = get(i);
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
CachedIteratorArrayList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
}

View File

@ -0,0 +1,92 @@
package net.i2p.router.util;
import static org.junit.Assert.*;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
public class CachedIteratorArrayListTest {
private List<Character> l;
private Iterator<Character> iter;
@Before
public void setUp() {
l = new CachedIteratorArrayList<Character>();
l.add('a');
l.add('b');
l.add('c');
iter = l.iterator();
}
/** test iterations work */
@Test
public void test() {
String total = "";
// two full for-each iterations
for (char i : l)
total += i;
assertEquals("abc", total);
for (char i : l)
total += i;
assertEquals("abcabc", total);
// and one partial
total = "";
iter = l.iterator();
total += iter.next();
total += iter.next();
iter = l.iterator();
total += iter.next();
assertEquals("aba",total);
}
@Test
public void testSameness() {
Iterator<Character> two = l.iterator();
Iterator<Character> one = l.iterator();
assertSame(one, two);
}
@Test
public void testRemove() {
iter.next();
iter.remove();
// test proper removal
assertEquals(2,l.size());
assertEquals('b',l.get(0).charValue());
assertEquals('c',l.get(1).charValue());
// test iterator still workx after removal
assertTrue(iter.hasNext());
assertEquals('b',iter.next().charValue());
assertEquals('c',iter.next().charValue());
assertFalse(iter.hasNext());
}
/**
* tests the Collections.sort method because that is used
* in the router and internally creates iterators
*/
@Test
public void testSorting() {
List<Integer> li = new CachedIteratorArrayList<Integer>();
li.add(3);
li.add(2);
li.add(1);
Collections.sort(li);
Iterator<Integer> ii = li.iterator();
assertEquals(1,ii.next().intValue());
assertEquals(2,ii.next().intValue());
assertEquals(3,ii.next().intValue());
assertFalse(ii.hasNext());
}
}