CompositeIterator removed

This commit is contained in:
Alexey Kudravtsev
2013-01-18 15:09:47 +04:00
parent 3b8177c3dc
commit f5a39cc5dd
8 changed files with 272 additions and 129 deletions
@@ -33,7 +33,7 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
import com.intellij.util.containers.SequenceIterator;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.diff.FilesTooBigForDiffException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -187,8 +187,7 @@ public class MergeList implements UserDataHolder {
}
public Iterator<Change> getAllChanges() {
return SequenceIterator.create(myBaseToLeftChangeList.getChanges().iterator(),
myBaseToRightChangeList.getChanges().iterator());
return ContainerUtil.concatIterators(myBaseToLeftChangeList.getChanges().iterator(), myBaseToRightChangeList.getChanges().iterator());
}
public void addListener(ChangeList.Listener listener) {
@@ -1,84 +0,0 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.util.containers;
import java.util.Iterator;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: Irina.Chernushina
* Date: 9/28/11
* Time: 12:38 PM
*/
public class CompositeIterator<Key> implements Iterator<Key> {
private int myPreviousIdx;
private int myIdx;
private final List<Iterator<Key>> myIterators;
private boolean myIsOnLast;
public CompositeIterator(final List<Iterator<Key>> iterators) {
myIterators = iterators;
myIdx = -1;
myPreviousIdx = -1;
for (int i = 0; i < myIterators.size(); i++) {
final Iterator<Key> iterator = myIterators.get(i);
if (iterator.hasNext()) {
myIdx = i;
break;
}
}
}
@Override
public boolean hasNext() {
return (myIdx >= 0) && myIterators.get(myIdx).hasNext();
}
@Override
public Key next() {
final Key result = myIterators.get(myIdx).next();
myIsOnLast = false;
recalculateCurrent();
return result;
}
private void recalculateCurrent() {
if (myIdx == -1) return;
if (! myIterators.get(myIdx).hasNext()) {
myIsOnLast = true;
myPreviousIdx = myIdx;
myIdx = -1;
for (int i = myPreviousIdx; i < myIterators.size(); i++) {
final Iterator<Key> iterator = myIterators.get(i);
if (iterator.hasNext()) {
myIdx = i;
break;
}
}
}
}
@Override
public void remove() {
if (myIsOnLast) {
// last element
myIterators.get(myPreviousIdx).remove(); // already on last position
} else {
myIterators.get(myIdx).remove();
}
}
}
@@ -1044,10 +1044,21 @@ public class ContainerUtil extends ContainerUtilRt {
Iterable<? extends T> iterable = iterables[i];
iterators[i] = iterable.iterator();
}
return new SequenceIterator<T>(iterators);
return concatIterators(iterators);
}
};
}
@NotNull
public static <T> Iterator<T> concatIterators(@NotNull Iterator<T>... iterators) {
return new SequenceIterator<T>(iterators);
}
@NotNull
public static <T> Iterator<T> concatIterators(@NotNull Collection<Iterator<T>> iterators) {
return new SequenceIterator<T>(iterators);
}
@NotNull
public static <T> Iterable<T> concat(@NotNull final T[]... iterables) {
return new Iterable<T>() {
@@ -1058,7 +1069,7 @@ public class ContainerUtil extends ContainerUtilRt {
T[] iterable = iterables[i];
iterators[i] = Arrays.asList(iterable).iterator();
}
return new SequenceIterator<T>(iterators);
return concatIterators(iterators);
}
};
}
@@ -17,44 +17,48 @@ package com.intellij.util.containers;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class SequenceIterator<T> implements Iterator<T> {
private final Iterator[] myIterators;
private final Iterator<T>[] myIterators;
private int myCurrentIndex;
public SequenceIterator(@NotNull Iterator... iterators){
public SequenceIterator(@NotNull Iterator<T>... iterators){
myIterators = new Iterator[iterators.length];
System.arraycopy(iterators, 0, myIterators, 0, iterators.length);
}
public boolean hasNext(){
if(myCurrentIndex >= myIterators.length){
return false;
}
else if(myIterators[myCurrentIndex] == null){
myCurrentIndex++;
return hasNext();
}
else if(myIterators[myCurrentIndex].hasNext()){
return true;
}
else{
myCurrentIndex++;
return hasNext();
}
public SequenceIterator(@NotNull Collection<Iterator<T>> iterators) {
this(iterators.toArray(new Iterator[iterators.size()]));
}
@Override
public boolean hasNext(){
for (int index = myCurrentIndex; index < myIterators.length; index++) {
Iterator iterator = myIterators[index];
if (iterator != null && iterator.hasNext()) {
myCurrentIndex = index;
return true;
}
}
return false;
}
@Override
public T next(){
if(hasNext()){
return (T)myIterators[myCurrentIndex].next();
if(hasNext()) {
return myIterators[myCurrentIndex].next();
}
throw new NoSuchElementException("Iterator has no more elements");
}
@Override
public void remove(){
throw new UnsupportedOperationException("Remove not supported");
if(myCurrentIndex >= myIterators.length){
throw new IllegalStateException();
}
myIterators[myCurrentIndex].remove();
}
public static <T> SequenceIterator<T> create(Iterator<T> first, Iterator<T> second) {
@@ -23,41 +23,254 @@ import junit.framework.TestCase;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class SequenceIteratorTest extends TestCase {
private final Assertion CHECK = new Assertion();
public void testOneIterator() {
Iterator<Object> iterator = iterate("1", "2");
com.intellij.util.containers.SequenceIterator seq = new com.intellij.util.containers.SequenceIterator(new Iterator[]{iterator});
CHECK.compareAll(new Object[]{"1", "2"}, com.intellij.util.containers.ContainerUtil.collect(seq));
Iterator<Object> seq = ContainerUtil.concatIterators(iterator);
CHECK.compareAll(new Object[]{"1", "2"}, ContainerUtil.collect(seq));
}
public void testTwoNotEmpties() {
Iterator<Object> seq = com.intellij.util.containers.SequenceIterator.create(iterate("1", "2"), iterate("3", "4"));
CHECK.compareAll(new Object[]{"1", "2", "3", "4"}, com.intellij.util.containers.ContainerUtil.collect(seq));
Iterator<Object> seq = ContainerUtil.concatIterators(iterate("1", "2"), iterate("3", "4"));
CHECK.compareAll(new Object[]{"1", "2", "3", "4"}, ContainerUtil.collect(seq));
}
public void testAllEmpty() {
Assert.assertFalse(new com.intellij.util.containers.SequenceIterator(new Iterator[]{empty()}).hasNext());
Assert.assertFalse(new com.intellij.util.containers.SequenceIterator(new Iterator[]{empty(), empty()}).hasNext());
Assert.assertFalse(ContainerUtil.concatIterators(empty()).hasNext());
Assert.assertFalse(ContainerUtil.concatIterators(empty(), empty()).hasNext());
}
public void testIntermediateEmpty() {
com.intellij.util.containers.SequenceIterator seq = com.intellij.util.containers.SequenceIterator.create(iterate("1", "2"), empty(), iterate("3", "4"));
CHECK.compareAll(new Object[]{"1", "2", "3", "4"}, com.intellij.util.containers.ContainerUtil.collect(seq));
Iterator<Object> seq = ContainerUtil.concatIterators(iterate("1", "2"), empty(), iterate("3", "4"));
CHECK.compareAll(new Object[]{"1", "2", "3", "4"}, ContainerUtil.collect(seq));
}
public void testFirstEmpty() {
com.intellij.util.containers.SequenceIterator seq = com.intellij.util.containers.SequenceIterator.create(empty(), iterate("1", "2"));
CHECK.compareAll(new Object[]{"1", "2"}, com.intellij.util.containers.ContainerUtil.collect(seq));
Iterator<Object> seq = ContainerUtil.concatIterators(empty(), iterate("1", "2"));
CHECK.compareAll(new Object[]{"1", "2"}, ContainerUtil.collect(seq));
}
private Iterator<Object> iterate(String first, String second) {
private static Iterator<Object> iterate(String first, String second) {
return Arrays.asList(new Object[]{first, second}).iterator();
}
private Iterator empty() {
private static Iterator empty() {
return new ArrayList().iterator();
}
public void testSimple() throws Exception {
final Iterator<Integer> iterator = compose(Arrays.<Iterator<Integer>>asList(iter(arr1), iter(arr2), iter(arr3)));
int cnt = 0;
while (iterator.hasNext()) {
Integer next = iterator.next();
System.out.println(next);
++ cnt;
}
Assert.assertEquals(arr1.length + arr2.length + arr3.length, cnt);
}
private static Iterator<Integer> compose(List<Iterator<Integer>> iterators) {
return ContainerUtil.concatIterators(iterators);
}
public void testOne() throws Exception {
final Iterator<Integer> iterator = compose(Arrays.<Iterator<Integer>>asList(iter(arr1)));
int cnt = 0;
while (iterator.hasNext()) {
Integer next = iterator.next();
System.out.println(next);
++ cnt;
}
Assert.assertEquals(arr1.length, cnt);
}
public void testOneOne() throws Exception {
final Iterator<Integer> iterator = compose(Arrays.<Iterator<Integer>>asList(iter(new Integer[]{1})));
int cnt = 0;
while (iterator.hasNext()) {
Integer next = iterator.next();
System.out.println(next);
++ cnt;
}
Assert.assertEquals(1, cnt);
}
public void testEmpty() throws Exception {
final Iterator<Integer> iterator = compose(Arrays.<Iterator<Integer>>asList(iter(new Integer[]{})));
int cnt = 0;
while (iterator.hasNext()) {
Integer next = iterator.next();
System.out.println(next);
++ cnt;
}
Assert.assertEquals(0, cnt);
}
public void testManyEmpty() throws Exception {
final Iterator<Integer> iterator =
compose(Arrays.<Iterator<Integer>>asList(iter(new Integer[]{}), iter(new Integer[]{}), iter(new Integer[]{})));
int cnt = 0;
while (iterator.hasNext()) {
Integer next = iterator.next();
System.out.println(next);
++ cnt;
}
Assert.assertEquals(0, cnt);
}
public void testRemoveSimple() throws Exception {
final ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(arr1));
final ArrayList<Integer> list2 = new ArrayList<Integer>(Arrays.asList(arr2));
final ArrayList<Integer> list3 = new ArrayList<Integer>(Arrays.asList(arr3));
final Iterator<Integer> iterator =
compose(Arrays.<Iterator<Integer>>asList(list1.iterator(), list2.iterator(), list3.iterator()));
int cnt = 0;
while (iterator.hasNext()) {
Integer next = iterator.next();
System.out.println("next: " + next);
if ((cnt - 2) % 5 == 0) {
iterator.remove();
System.out.println("REMOVED");
}
++ cnt;
}
Assert.assertTrue(! list1.contains(3));
Assert.assertTrue(! list2.contains(13));
Assert.assertTrue(! list3.contains(103));
}
public void testRemoveAfterLast() throws Exception {
final ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(arr1));
final Iterator<Integer> it1 = list1.iterator();
while (it1.hasNext()) {
Integer next = it1.next();
}
it1.remove(); // ok, removes last
Assert.assertTrue(! list1.contains(5));
list1.add(5);
final ArrayList<Integer> list2 = new ArrayList<Integer>(Arrays.asList(arr2));
final ArrayList<Integer> list3 = new ArrayList<Integer>(Arrays.asList(arr3));
final Iterator<Integer> iterator =
compose(Arrays.<Iterator<Integer>>asList(list1.iterator(), list2.iterator(), list3.iterator()));
while (iterator.hasNext()) {
Integer next = iterator.next();
}
iterator.remove();
Assert.assertTrue(! list3.contains(105));
}
public void testRemoveOnlyOne() throws Exception {
final ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(new Integer[]{1}));
final Iterator<Integer> iterator = compose(Arrays.<Iterator<Integer>>asList(list1.iterator()));
iterator.next();
iterator.remove();
Assert.assertTrue(list1.isEmpty());
}
public void testIterateWithEmptyInside() throws Exception {
final Iterator<Integer> iterator = compose(Arrays.<Iterator<Integer>>asList(iter(arr1), iter(new Integer[]{}), iter(arr3)));
int cnt = 0;
int sum = 0;
while (iterator.hasNext()) {
Integer next = iterator.next();
System.out.println(next);
++ cnt;
sum += next;
}
Assert.assertEquals(arr1.length + arr3.length, cnt);
Assert.assertEquals(530, sum);
}
public void testRemoveIfNextNotCalled() throws Exception {
final ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(new Integer[]{1}));
final Iterator<Integer> iterator = compose(Arrays.<Iterator<Integer>>asList(list1.iterator()));
try {
iterator.remove();
Assert.assertTrue(false);
} catch (IllegalStateException e) {
// ok
}
}
public void testRemoveTwice() throws Exception {
final ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(new Integer[]{1,2,3,4,5}));
final Iterator<Integer> iterator = compose(Arrays.<Iterator<Integer>>asList(list1.iterator()));
try {
iterator.next();
iterator.remove();
iterator.remove(); // wrong, next() should be called inside
Assert.assertTrue(false);
} catch (IllegalStateException e) {
// ok
}
}
public void testRemoveAll() throws Exception {
final ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(1,2));
final ArrayList<Integer> list2 = new ArrayList<Integer>(Arrays.asList(3,4));
final ArrayList<Integer> list3 = new ArrayList<Integer>(Arrays.asList(5,6));
final Iterator<Integer> iterator =
compose(Arrays.<Iterator<Integer>>asList(list1.iterator(), list2.iterator(), list3.iterator()));
while (iterator.hasNext()) {
Integer next = iterator.next();
System.out.println(next);
iterator.remove();
}
Assert.assertTrue(list1.isEmpty());
Assert.assertTrue(list2.isEmpty());
Assert.assertTrue(list3.isEmpty());
}
public void testRemoveAllWithEmptyInside() throws Exception {
final ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(1,2));
final ArrayList<Integer> list2 = new ArrayList<Integer>();
final ArrayList<Integer> list3 = new ArrayList<Integer>(Arrays.asList(5,6));
final Iterator<Integer> iterator =
compose(Arrays.<Iterator<Integer>>asList(list1.iterator(), list2.iterator(), list3.iterator()));
while (iterator.hasNext()) {
Integer next = iterator.next();
System.out.println(next);
iterator.remove();
}
Assert.assertTrue(list1.isEmpty());
Assert.assertTrue(list2.isEmpty());
Assert.assertTrue(list3.isEmpty());
}
public void testRemoveLastAndFirstINNext() throws Exception {
final ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(1,2));
final ArrayList<Integer> list2 = new ArrayList<Integer>(Arrays.asList(3,4));
final ArrayList<Integer> list3 = new ArrayList<Integer>(Arrays.asList(5,6));
final Iterator<Integer> iterator =
compose(Arrays.<Iterator<Integer>>asList(list1.iterator(), list2.iterator(), list3.iterator()));
iterator.next();
iterator.next();
iterator.remove();
iterator.next();
iterator.remove();
Assert.assertTrue(list1.size() == 1 && ! list1.contains(2));
Assert.assertTrue(list2.size() == 1 && ! list1.contains(3));
Assert.assertTrue(list3.size() == 2);
}
private static final Integer[] arr1 = {1,2,3,4,5};
private static final Integer[] arr2 = {11,12,13,14,15};
private static final Integer[] arr3= {101,102,103,104,105};
private Iterator<Integer> iter(final Integer[] arr) {
return Arrays.asList(arr).iterator();
}
}
@@ -25,7 +25,7 @@ import com.intellij.openapi.util.text.LineTokenizer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.BeforeAfter;
import com.intellij.util.Consumer;
import com.intellij.util.containers.CompositeIterator;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.*;
@@ -737,8 +737,8 @@ public class GenericPatchApplier {
}
private Iterator<Integer> getMatchingIterator(final String line, final int originalStart, final int maxWalkFromBinding) {
return new CompositeIterator<Integer>(Arrays.<Iterator<Integer>>asList(new WalkingIterator(line, originalStart, maxWalkFromBinding, true),
new WalkingIterator(line, originalStart, maxWalkFromBinding, false)));
return ContainerUtil.concatIterators(new WalkingIterator(line, originalStart, maxWalkFromBinding, true),
new WalkingIterator(line, originalStart, maxWalkFromBinding, false));
}
private class WalkingIterator implements Iterator<Integer> {
@@ -29,7 +29,7 @@ import com.intellij.util.Consumer;
import com.intellij.util.PairProcessor;
import com.intellij.util.Processor;
import com.intellij.util.SmartList;
import com.intellij.util.containers.CompositeIterator;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Convertor;
import com.intellij.util.containers.MultiMap;
import gnu.trove.THashSet;
@@ -72,7 +72,7 @@ public class VcsDirtyScopeImpl extends VcsModifiableDirtyScope {
for (THashSet<FilePath> paths : myDirtyFiles.values()) {
iteratorList.add(paths.iterator());
}
return new CompositeIterator<FilePath>(iteratorList);
return ContainerUtil.concatIterators(iteratorList);
}
@Nullable
@@ -15,7 +15,7 @@
*/
package git4idea.history.wholeTree;
import com.intellij.util.containers.CompositeIterator;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.SLRUMap;
import java.util.*;
@@ -74,7 +74,7 @@ public class CommitIdsHolder<Item> {
final List<Iterator<Key>> iterators = new ArrayList<Iterator<Key>>(2);
iterators.add(myProbationalQueue.keySet().iterator());
iterators.add(myProtectedQueue.keySet().iterator());
return new CompositeIterator<Key>(iterators);
return ContainerUtil.concatIterators(iterators);
}
}
}