diff --git a/pom.xml b/pom.xml
index 9ad4475d30..7f639e5c2f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.baidu.hugegraph
hugegraph-common
- 1.7.1
+ 1.7.2
hugegraph-common
https://github.com/hugegraph/hugegraph-common
@@ -218,7 +218,7 @@
- 1.7.1.0
+ 1.7.2.0
diff --git a/src/main/java/com/baidu/hugegraph/iterator/BatchMapperIterator.java b/src/main/java/com/baidu/hugegraph/iterator/BatchMapperIterator.java
new file mode 100644
index 0000000000..6b2a9135f9
--- /dev/null
+++ b/src/main/java/com/baidu/hugegraph/iterator/BatchMapperIterator.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You 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.baidu.hugegraph.iterator;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Function;
+
+import com.baidu.hugegraph.util.E;
+import com.baidu.hugegraph.util.InsertionOrderUtil;
+import com.google.common.collect.ImmutableList;
+
+public class BatchMapperIterator extends WrappedIterator {
+
+ private final int batch;
+ private final Iterator originIterator;
+ private final Function, Iterator> mapperCallback;
+
+ private Iterator batchIterator;
+
+ public BatchMapperIterator(int batch, Iterator origin,
+ Function, Iterator> mapper) {
+ E.checkArgument(batch > 0, "Expect batch > 0, but got %s", batch);
+ this.batch = batch;
+ this.originIterator = origin;
+ this.mapperCallback = mapper;
+ this.batchIterator = null;
+ }
+
+ @Override
+ protected Iterator originIterator() {
+ return this.originIterator;
+ }
+
+ @Override
+ protected final boolean fetch() {
+ if (this.batchIterator != null && this.fetchFromBatch()) {
+ return true;
+ }
+
+ List list = this.nextBatch();
+ if (!list.isEmpty()) {
+ assert this.batchIterator == null;
+ // Do fetch
+ this.batchIterator = this.mapperCallback.apply(list);
+ if (this.batchIterator != null && this.fetchFromBatch()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected final List nextBatch() {
+ if (!this.originIterator.hasNext()) {
+ return ImmutableList.of();
+ }
+ List list = InsertionOrderUtil.newList();
+ for (int i = 0; i < this.batch && this.originIterator.hasNext(); i++) {
+ T next = this.originIterator.next();
+ list.add(next);
+ }
+ return list;
+ }
+
+ protected final boolean fetchFromBatch() {
+ E.checkNotNull(this.batchIterator, "mapper results");
+ while (this.batchIterator.hasNext()) {
+ R result = this.batchIterator.next();
+ if (result != null) {
+ assert this.current == none();
+ this.current = result;
+ return true;
+ }
+ }
+ this.resetBatchIterator();
+ return false;
+ }
+
+ protected final void resetBatchIterator() {
+ if (this.batchIterator == null) {
+ return;
+ }
+ close(this.batchIterator);
+ this.batchIterator = null;
+ }
+}
diff --git a/src/main/java/com/baidu/hugegraph/iterator/IterableIterator.java b/src/main/java/com/baidu/hugegraph/iterator/CIter.java
similarity index 60%
rename from src/main/java/com/baidu/hugegraph/iterator/IterableIterator.java
rename to src/main/java/com/baidu/hugegraph/iterator/CIter.java
index eb2a966377..35eda45272 100644
--- a/src/main/java/com/baidu/hugegraph/iterator/IterableIterator.java
+++ b/src/main/java/com/baidu/hugegraph/iterator/CIter.java
@@ -21,32 +21,5 @@
import java.util.Iterator;
-public class IterableIterator implements Iterator {
-
- private final Iterable iterable;
- private final Iterator iterator;
-
- public IterableIterator(Iterable iterable) {
- this.iterable = iterable;
- this.iterator = iterable.iterator();
- }
-
- @Override
- public boolean hasNext() {
- return this.iterator.hasNext();
- }
-
- @Override
- public T next() {
- return this.iterator.next();
- }
-
- @Override
- public void remove() {
- this.iterator.remove();
- }
-
- public Iterable iterable() {
- return iterable;
- }
+public interface CIter extends Iterator, AutoCloseable, Metadatable {
}
diff --git a/src/main/java/com/baidu/hugegraph/iterator/ExtendableIterator.java b/src/main/java/com/baidu/hugegraph/iterator/ExtendableIterator.java
index 7d036111ae..d9985edc53 100644
--- a/src/main/java/com/baidu/hugegraph/iterator/ExtendableIterator.java
+++ b/src/main/java/com/baidu/hugegraph/iterator/ExtendableIterator.java
@@ -19,10 +19,8 @@
package com.baidu.hugegraph.iterator;
-import java.util.ArrayList;
import java.util.Deque;
import java.util.Iterator;
-import java.util.List;
import java.util.concurrent.ConcurrentLinkedDeque;
import com.baidu.hugegraph.util.E;
@@ -30,13 +28,11 @@
public class ExtendableIterator extends WrappedIterator {
private final Deque> itors;
- private final List> removedItors;
private Iterator currentIterator;
public ExtendableIterator() {
this.itors = new ConcurrentLinkedDeque<>();
- this.removedItors = new ArrayList<>();
this.currentIterator = null;
}
@@ -62,11 +58,6 @@ public ExtendableIterator extend(Iterator iter) {
@Override
public void close() throws Exception {
- for (Iterator iter : this.removedItors) {
- if (iter instanceof AutoCloseable) {
- ((AutoCloseable) iter).close();
- }
- }
for (Iterator iter : this.itors) {
if (iter instanceof AutoCloseable) {
((AutoCloseable) iter).close();
@@ -75,7 +66,7 @@ public void close() throws Exception {
}
@Override
- protected Iterator> originIterator() {
+ protected Iterator originIterator() {
return this.currentIterator;
}
@@ -98,7 +89,7 @@ protected boolean fetch() {
// The last one
return false;
}
- this.removedItors.add(this.itors.removeFirst());
+ close(this.itors.removeFirst());
}
assert first != null && first.hasNext();
diff --git a/src/main/java/com/baidu/hugegraph/iterator/FlatMapperFilterIterator.java b/src/main/java/com/baidu/hugegraph/iterator/FlatMapperFilterIterator.java
index 6046dd25a0..a222319b13 100644
--- a/src/main/java/com/baidu/hugegraph/iterator/FlatMapperFilterIterator.java
+++ b/src/main/java/com/baidu/hugegraph/iterator/FlatMapperFilterIterator.java
@@ -36,17 +36,17 @@ public FlatMapperFilterIterator(Iterator origin,
}
@Override
- protected final boolean fetchMapped() {
- E.checkNotNull(this.results, "mapper results");
- while (this.results.hasNext()) {
- R result = this.results.next();
+ protected final boolean fetchFromBatch() {
+ E.checkNotNull(this.batchIterator, "mapper results");
+ while (this.batchIterator.hasNext()) {
+ R result = this.batchIterator.next();
if (result != null && this.filterCallback.apply(result)) {
assert this.current == none();
this.current = result;
return true;
}
}
- this.results = null;
+ this.resetBatchIterator();
return false;
}
}
diff --git a/src/main/java/com/baidu/hugegraph/iterator/FlatMapperIterator.java b/src/main/java/com/baidu/hugegraph/iterator/FlatMapperIterator.java
index 9d50d79c5b..6b4cd9855b 100644
--- a/src/main/java/com/baidu/hugegraph/iterator/FlatMapperIterator.java
+++ b/src/main/java/com/baidu/hugegraph/iterator/FlatMapperIterator.java
@@ -29,48 +29,63 @@ public class FlatMapperIterator extends WrappedIterator {
private final Iterator originIterator;
private final Function> mapperCallback;
- protected Iterator results;
+ protected Iterator batchIterator;
public FlatMapperIterator(Iterator origin,
Function> mapper) {
this.originIterator = origin;
this.mapperCallback = mapper;
- this.results = null;
+ this.batchIterator = null;
}
@Override
- protected Iterator> originIterator() {
+ public void close() throws Exception {
+ this.resetBatchIterator();
+ super.close();
+ }
+
+ @Override
+ protected Iterator originIterator() {
return this.originIterator;
}
@Override
protected final boolean fetch() {
- if (this.results != null && this.fetchMapped()) {
+ if (this.batchIterator != null && this.fetchFromBatch()) {
return true;
}
while (this.originIterator.hasNext()) {
T next = this.originIterator.next();
- assert this.results == null;
- this.results = this.mapperCallback.apply(next);
- if (this.results != null && this.fetchMapped()) {
+ assert this.batchIterator == null;
+ // Do fetch
+ this.batchIterator = this.mapperCallback.apply(next);
+ if (this.batchIterator != null && this.fetchFromBatch()) {
return true;
}
}
return false;
}
- protected boolean fetchMapped() {
- E.checkNotNull(this.results, "mapper results");
- while (this.results.hasNext()) {
- R result = this.results.next();
+ protected boolean fetchFromBatch() {
+ E.checkNotNull(this.batchIterator, "mapper results");
+ while (this.batchIterator.hasNext()) {
+ R result = this.batchIterator.next();
if (result != null) {
assert this.current == none();
this.current = result;
return true;
}
}
- this.results = null;
+ this.resetBatchIterator();
return false;
}
+
+ protected final void resetBatchIterator() {
+ if (this.batchIterator == null) {
+ return;
+ }
+ close(this.batchIterator);
+ this.batchIterator = null;
+ }
}
diff --git a/src/main/java/com/baidu/hugegraph/iterator/ListIterator.java b/src/main/java/com/baidu/hugegraph/iterator/ListIterator.java
new file mode 100644
index 0000000000..f21a436461
--- /dev/null
+++ b/src/main/java/com/baidu/hugegraph/iterator/ListIterator.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You 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.baidu.hugegraph.iterator;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import com.baidu.hugegraph.util.InsertionOrderUtil;
+
+public class ListIterator extends WrappedIterator {
+
+ private final Iterator originIterator;
+ private final Iterator resultsIterator;
+ private final Collection results;
+
+ public ListIterator(long capacity, Iterator origin) {
+ List results = InsertionOrderUtil.newList();
+ while (origin.hasNext()) {
+ if (capacity >= 0L && results.size() >= capacity) {
+ throw new IllegalArgumentException(
+ "The iterator exceeded capacity " + capacity);
+ }
+ results.add(origin.next());
+ }
+ this.originIterator = origin;
+ this.results = Collections.unmodifiableList(results);
+ this.resultsIterator = this.results.iterator();
+ }
+
+ public ListIterator(Collection origin) {
+ this.originIterator = origin.iterator();
+ this.results = origin instanceof List ?
+ Collections.unmodifiableList((List) origin) :
+ Collections.unmodifiableCollection(origin);
+ this.resultsIterator = this.results.iterator();
+ }
+
+ @Override
+ public void remove() {
+ this.resultsIterator.remove();
+ }
+
+ public Collection list() {
+ return this.results;
+ }
+
+ @Override
+ protected boolean fetch() {
+ assert this.current == none();
+ if (!this.resultsIterator.hasNext()) {
+ return false;
+ }
+ this.current = this.resultsIterator.next();
+ return true;
+ }
+
+ @Override
+ protected Iterator originIterator() {
+ return this.originIterator;
+ }
+}
diff --git a/src/main/java/com/baidu/hugegraph/iterator/MapperIterator.java b/src/main/java/com/baidu/hugegraph/iterator/MapperIterator.java
index f9930f5128..c02d17c27b 100644
--- a/src/main/java/com/baidu/hugegraph/iterator/MapperIterator.java
+++ b/src/main/java/com/baidu/hugegraph/iterator/MapperIterator.java
@@ -33,7 +33,7 @@ public MapperIterator(Iterator origin, Function mapper) {
}
@Override
- protected Iterator> originIterator() {
+ protected Iterator originIterator() {
return this.originIterator;
}
diff --git a/src/main/java/com/baidu/hugegraph/iterator/WrappedIterator.java b/src/main/java/com/baidu/hugegraph/iterator/WrappedIterator.java
index 30cf0725e2..c6e9ae7bc5 100644
--- a/src/main/java/com/baidu/hugegraph/iterator/WrappedIterator.java
+++ b/src/main/java/com/baidu/hugegraph/iterator/WrappedIterator.java
@@ -22,8 +22,7 @@
import java.util.Iterator;
import java.util.NoSuchElementException;
-public abstract class WrappedIterator
- implements Iterator, AutoCloseable, Metadatable {
+public abstract class WrappedIterator implements CIter {
private static final Object NONE = new Object();
@@ -86,6 +85,16 @@ protected static final R none() {
return (R) NONE;
}
+ public static void close(Iterator> iterator) {
+ if (iterator instanceof AutoCloseable) {
+ try {
+ ((AutoCloseable) iterator).close();
+ } catch (Exception e) {
+ throw new IllegalStateException("Failed to close iterator");
+ }
+ }
+ }
+
protected abstract Iterator> originIterator();
protected abstract boolean fetch();
diff --git a/src/main/java/com/baidu/hugegraph/version/CommonVersion.java b/src/main/java/com/baidu/hugegraph/version/CommonVersion.java
index 5bfcbcb53c..5c4ed4b68a 100644
--- a/src/main/java/com/baidu/hugegraph/version/CommonVersion.java
+++ b/src/main/java/com/baidu/hugegraph/version/CommonVersion.java
@@ -27,5 +27,5 @@ public class CommonVersion {
// The second parameter of Version.of() is for all-in-one JAR
public static final Version VERSION = Version.of(CommonVersion.class,
- "1.7.1");
+ "1.7.2");
}
diff --git a/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java b/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java
index 4d292d6267..dc90b35bf2 100644
--- a/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java
+++ b/src/test/java/com/baidu/hugegraph/unit/UnitTestSuite.java
@@ -30,10 +30,12 @@
import com.baidu.hugegraph.unit.config.OptionSpaceTest;
import com.baidu.hugegraph.unit.date.SafeDateFormatTest;
import com.baidu.hugegraph.unit.event.EventHubTest;
+import com.baidu.hugegraph.unit.iterator.BatchMapperIteratorTest;
import com.baidu.hugegraph.unit.iterator.ExtendableIteratorTest;
import com.baidu.hugegraph.unit.iterator.FilterIteratorTest;
import com.baidu.hugegraph.unit.iterator.FlatMapperFilterIteratorTest;
import com.baidu.hugegraph.unit.iterator.FlatMapperIteratorTest;
+import com.baidu.hugegraph.unit.iterator.ListIteratorTest;
import com.baidu.hugegraph.unit.iterator.MapperIteratorTest;
import com.baidu.hugegraph.unit.license.ExtraParamTest;
import com.baidu.hugegraph.unit.license.LicenseCreateParamTest;
@@ -74,6 +76,8 @@
MapperIteratorTest.class,
FlatMapperIteratorTest.class,
FlatMapperFilterIteratorTest.class,
+ ListIteratorTest.class,
+ BatchMapperIteratorTest.class,
BytesTest.class,
CollectionUtilTest.class,
diff --git a/src/test/java/com/baidu/hugegraph/unit/iterator/BatchMapperIteratorTest.java b/src/test/java/com/baidu/hugegraph/unit/iterator/BatchMapperIteratorTest.java
new file mode 100644
index 0000000000..e08ff69216
--- /dev/null
+++ b/src/test/java/com/baidu/hugegraph/unit/iterator/BatchMapperIteratorTest.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You 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.baidu.hugegraph.unit.iterator;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.function.Function;
+
+import org.junit.Test;
+
+import com.baidu.hugegraph.iterator.BatchMapperIterator;
+import com.baidu.hugegraph.testutil.Assert;
+import com.baidu.hugegraph.unit.BaseUnitTest;
+import com.baidu.hugegraph.unit.iterator.ExtendableIteratorTest.CloseableItor;
+import com.google.common.collect.ImmutableList;
+
+@SuppressWarnings("resource")
+public class BatchMapperIteratorTest extends BaseUnitTest {
+
+ private static final Iterator EMPTY = Collections.emptyIterator();
+
+ private static final List DATA1 = ImmutableList.of(1);
+ private static final List DATA2 = ImmutableList.of(2, 3);
+ private static final List DATA3 = ImmutableList.of(4, 5, 6);
+
+ private static final Function, Iterator> MAPPER =
+ batch -> batch.iterator();
+
+ @Test
+ public void testBatchMapper() {
+ Iterator results;
+
+ results = new BatchMapperIterator<>(1, DATA1.iterator(), MAPPER);
+ Assert.assertEquals(ImmutableList.of(1), ImmutableList.copyOf(results));
+
+ results = new BatchMapperIterator<>(1, DATA2.iterator(), MAPPER);
+ Assert.assertEquals(ImmutableList.of(2, 3),
+ ImmutableList.copyOf(results));
+
+ results = new BatchMapperIterator<>(1, DATA3.iterator(), MAPPER);
+ Assert.assertEquals(ImmutableList.of(4, 5, 6),
+ ImmutableList.copyOf(results));
+ }
+
+ @Test
+ public void testBatch() {
+ Iterator results;
+
+ results = new BatchMapperIterator<>(2, DATA2.iterator(), MAPPER);
+ Assert.assertEquals(ImmutableList.of(2, 3),
+ ImmutableList.copyOf(results));
+
+ results = new BatchMapperIterator<>(2, DATA3.iterator(), MAPPER);
+ Assert.assertEquals(ImmutableList.of(4, 5, 6),
+ ImmutableList.copyOf(results));
+
+ results = new BatchMapperIterator<>(3, DATA3.iterator(), MAPPER);
+ Assert.assertEquals(ImmutableList.of(4, 5, 6),
+ ImmutableList.copyOf(results));
+
+ results = new BatchMapperIterator<>(4, DATA3.iterator(), MAPPER);
+ Assert.assertEquals(ImmutableList.of(4, 5, 6),
+ ImmutableList.copyOf(results));
+ }
+
+ @Test
+ public void testInvalidBatch() {
+ Assert.assertThrows(IllegalArgumentException.class, () -> {
+ new BatchMapperIterator<>(0, DATA1.iterator(), MAPPER);
+ });
+
+ Assert.assertThrows(IllegalArgumentException.class, () -> {
+ new BatchMapperIterator<>(-1, DATA1.iterator(), MAPPER);
+ });
+ }
+
+ @Test
+ public void testHasNext() {
+ Iterator results;
+
+ results = new BatchMapperIterator<>(1, EMPTY, MAPPER);
+ Assert.assertFalse(results.hasNext());
+
+ results = new BatchMapperIterator<>(1, DATA1.iterator(), MAPPER);
+ Assert.assertTrue(results.hasNext());
+ }
+
+ @Test
+ public void testHasNextAndNextWithMultiTimes() {
+ Iterator results;
+
+ results = new BatchMapperIterator<>(1, DATA3.iterator(), MAPPER);
+
+ for (int i = 0; i < 5; i++) {
+ Assert.assertTrue(results.hasNext());
+ }
+
+ for (int i = 0; i < 3; i++) {
+ results.next();
+ }
+
+ Assert.assertFalse(results.hasNext());
+ Assert.assertFalse(results.hasNext());
+
+ Assert.assertThrows(NoSuchElementException.class, () -> {
+ results.next();
+ });
+ Assert.assertThrows(NoSuchElementException.class, () -> {
+ results.next();
+ });
+ }
+
+ @Test
+ public void testNext() {
+ Iterator results;
+
+ results = new BatchMapperIterator<>(1, DATA1.iterator(), MAPPER);
+ // Call next() without hasNext()
+ Assert.assertEquals(1, results.next());
+
+ results = new BatchMapperIterator<>(1, DATA3.iterator(), MAPPER);
+ Assert.assertEquals(4, results.next());
+ Assert.assertEquals(5, results.next());
+ Assert.assertEquals(6, results.next());
+
+ results = new BatchMapperIterator<>(2, DATA3.iterator(), MAPPER);
+ Assert.assertEquals(4, results.next());
+ Assert.assertEquals(5, results.next());
+ Assert.assertEquals(6, results.next());
+ }
+
+ @Test
+ public void testNextWithMultiTimes() {
+ Iterator results;
+
+ results = new BatchMapperIterator<>(1, DATA2.iterator(), MAPPER);
+
+ for (int i = 0; i < 2; i++) {
+ results.next();
+ }
+ Assert.assertThrows(NoSuchElementException.class, () -> {
+ results.next();
+ });
+ }
+
+ @Test
+ public void testMapperWithBatch() {
+ Iterator results;
+
+ results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> {
+ Assert.assertEquals(1, batch.size());
+ return batch.iterator();
+ });
+ Assert.assertEquals(4, results.next());
+ Assert.assertEquals(5, results.next());
+ Assert.assertEquals(6, results.next());
+ Assert.assertFalse(results.hasNext());
+
+ results = new BatchMapperIterator<>(2, DATA3.iterator(), batch -> {
+ if (batch.size() == 1) {
+ Assert.assertEquals(6, batch.get(0));
+ } else {
+ Assert.assertEquals(2, batch.size());
+ }
+ return batch.iterator();
+ });
+ Assert.assertEquals(4, results.next());
+ Assert.assertEquals(5, results.next());
+ Assert.assertEquals(6, results.next());
+ Assert.assertFalse(results.hasNext());
+
+ results = new BatchMapperIterator<>(3, DATA3.iterator(), batch -> {
+ Assert.assertEquals(3, batch.size());
+ return batch.iterator();
+ });
+ Assert.assertEquals(4, results.next());
+ Assert.assertEquals(5, results.next());
+ Assert.assertEquals(6, results.next());
+ Assert.assertFalse(results.hasNext());
+
+ results = new BatchMapperIterator<>(4, DATA3.iterator(), batch -> {
+ Assert.assertEquals(3, batch.size());
+ return batch.iterator();
+ });
+ Assert.assertEquals(4, results.next());
+ Assert.assertEquals(5, results.next());
+ Assert.assertEquals(6, results.next());
+ Assert.assertFalse(results.hasNext());
+ }
+
+ @Test
+ public void testMapperThenReturn2X() {
+ Iterator results;
+
+ results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> {
+ List list = new ArrayList<>();
+ for (int i : batch) {
+ list.add(2 * i);
+ }
+ return list.iterator();
+ });
+
+ Assert.assertEquals(8, results.next());
+ Assert.assertEquals(10, results.next());
+ Assert.assertEquals(12, results.next());
+ Assert.assertFalse(results.hasNext());
+ }
+
+ @Test
+ public void testMapperReturnNullThenHasNext() {
+ Iterator results;
+
+ results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> {
+ return null;
+ });
+ Assert.assertFalse(results.hasNext());
+ Assert.assertFalse(results.hasNext());
+ }
+
+ @Test
+ public void testMapperReturnNullThenNext() {
+ Iterator results;
+
+ results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> {
+ return null;
+ });
+ Assert.assertThrows(NoSuchElementException.class, () -> {
+ results.next();
+ });
+ Assert.assertThrows(NoSuchElementException.class, () -> {
+ results.next();
+ });
+ }
+
+ @Test
+ public void testClose() throws Exception {
+ CloseableItor vals = new CloseableItor<>(DATA1.iterator());
+
+ Iterator results = new BatchMapperIterator<>(1, vals, MAPPER);
+
+ Assert.assertFalse(vals.closed());
+ ((BatchMapperIterator, ?>) results).close();
+ Assert.assertTrue(vals.closed());
+ }
+}
diff --git a/src/test/java/com/baidu/hugegraph/unit/iterator/ExtendableIteratorTest.java b/src/test/java/com/baidu/hugegraph/unit/iterator/ExtendableIteratorTest.java
index 1a9a635b5f..4c7ba31b82 100644
--- a/src/test/java/com/baidu/hugegraph/unit/iterator/ExtendableIteratorTest.java
+++ b/src/test/java/com/baidu/hugegraph/unit/iterator/ExtendableIteratorTest.java
@@ -175,7 +175,30 @@ public void testClose() throws Exception {
}
@Test
- public void testCloseAfterNext() throws Exception {
+ public void testCloseAfterNext1() throws Exception {
+ CloseableItor c1 = new CloseableItor<>(DATA1.iterator());
+ CloseableItor c2 = new CloseableItor<>(DATA2.iterator());
+ CloseableItor c3 = new CloseableItor<>(DATA3.iterator());
+
+ ExtendableIterator results = new ExtendableIterator<>();
+ results.extend(c1).extend(c2).extend(c3);
+
+ results.next();
+ results.hasNext();
+
+ Assert.assertTrue(c1.closed()); // close after iterated
+ Assert.assertFalse(c2.closed());
+ Assert.assertFalse(c3.closed());
+
+ results.close();
+
+ Assert.assertTrue(c1.closed());
+ Assert.assertTrue(c2.closed());
+ Assert.assertTrue(c3.closed());
+ }
+
+ @Test
+ public void testCloseAfterNext3() throws Exception {
CloseableItor c1 = new CloseableItor<>(DATA1.iterator());
CloseableItor c2 = new CloseableItor<>(DATA2.iterator());
CloseableItor c3 = new CloseableItor<>(DATA3.iterator());
@@ -191,8 +214,8 @@ public void testCloseAfterNext() throws Exception {
results.next();
}
- Assert.assertFalse(c1.closed());
- Assert.assertFalse(c2.closed());
+ Assert.assertTrue(c1.closed());
+ Assert.assertTrue(c2.closed());
Assert.assertFalse(c3.closed());
results.close();
diff --git a/src/test/java/com/baidu/hugegraph/unit/iterator/ListIteratorTest.java b/src/test/java/com/baidu/hugegraph/unit/iterator/ListIteratorTest.java
new file mode 100644
index 0000000000..8ddd995ba0
--- /dev/null
+++ b/src/test/java/com/baidu/hugegraph/unit/iterator/ListIteratorTest.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2017 HugeGraph Authors
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You 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.baidu.hugegraph.unit.iterator;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.junit.Test;
+
+import com.baidu.hugegraph.iterator.ListIterator;
+import com.baidu.hugegraph.testutil.Assert;
+import com.baidu.hugegraph.unit.BaseUnitTest;
+import com.baidu.hugegraph.unit.iterator.ExtendableIteratorTest.CloseableItor;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterators;
+
+@SuppressWarnings("resource")
+public class ListIteratorTest extends BaseUnitTest {
+
+ private static final Iterator EMPTY = Collections.emptyIterator();
+
+ private static final List DATA1 = ImmutableList.of(1);
+ private static final List DATA2 = ImmutableList.of(2, 3);
+ private static final List DATA3 = ImmutableList.of(4, 5, 6);
+
+ @Test
+ public void testCapacity() {
+ Iterator results;
+
+ results = new ListIterator<>(0, EMPTY);
+ Assert.assertFalse(results.hasNext());
+ Assert.assertEquals(0, Iterators.size(results));
+
+ results = new ListIterator<>(2, DATA1.iterator());
+ Assert.assertTrue(results.hasNext());
+ Assert.assertEquals(1, Iterators.size(results));
+
+ results = new ListIterator<>(2, DATA2.iterator());
+ Assert.assertTrue(results.hasNext());
+ Assert.assertEquals(2, Iterators.size(results));
+
+ Assert.assertThrows(IllegalArgumentException.class, () -> {
+ new ListIterator<>(0, DATA1.iterator());
+ });
+
+ Assert.assertThrows(IllegalArgumentException.class, () -> {
+ new ListIterator<>(2, DATA3.iterator());
+ });
+ }
+
+ @Test
+ public void testList() {
+ ListIterator results;
+
+ results = new ListIterator<>(-1, EMPTY);
+ Assert.assertEquals(ImmutableList.of(), results.list());
+
+ results = new ListIterator<>(-1, DATA1.iterator());
+ Assert.assertEquals(ImmutableList.of(1), results.list());
+
+ results = new ListIterator<>(-1, DATA2.iterator());
+ Assert.assertEquals(ImmutableList.of(2, 3), results.list());
+
+ results = new ListIterator<>(-1, DATA3.iterator());
+ Assert.assertEquals(ImmutableList.of(4, 5, 6), results.list());
+ }
+
+ @Test
+ public void testHasNext() {
+ Iterator origin = DATA1.iterator();
+ Assert.assertTrue(origin.hasNext());
+
+ Iterator results = new ListIterator<>(-1, origin);
+ Assert.assertTrue(results.hasNext());
+ Assert.assertTrue(results.hasNext());
+ Assert.assertFalse(origin.hasNext());
+ }
+
+ @Test
+ public void testNext() {
+ Iterator results = new ListIterator<>(-1, DATA1.iterator());
+ Assert.assertEquals(1, (int) results.next());
+ Assert.assertThrows(NoSuchElementException.class, () -> {
+ results.next();
+ });
+ }
+
+ @Test
+ public void testNextAfterList() {
+ Iterator results = new ListIterator<>(-1, DATA1.iterator());
+ Assert.assertEquals(ImmutableList.of(1),
+ ((ListIterator>) results).list());
+ Assert.assertEquals(1, (int) results.next());
+ Assert.assertThrows(NoSuchElementException.class, () -> {
+ results.next();
+ });
+ }
+
+ @Test
+ public void testNextWithMultiTimes() {
+ Iterator results = new ListIterator<>(-1, DATA2.iterator());
+ Assert.assertEquals(2, (int) results.next());
+ Assert.assertEquals(3, (int) results.next());
+ Assert.assertThrows(NoSuchElementException.class, () -> {
+ results.next();
+ });
+ }
+
+ @Test
+ public void testHasNextAndNext() {
+ Iterator results = new ListIterator<>(-1, DATA1.iterator());
+ Assert.assertTrue(results.hasNext());
+ Assert.assertTrue(results.hasNext());
+ Assert.assertEquals(1, (int) results.next());
+ Assert.assertFalse(results.hasNext());
+ Assert.assertFalse(results.hasNext());
+ Assert.assertThrows(NoSuchElementException.class, () -> {
+ results.next();
+ });
+ }
+
+ @Test
+ public void testRemove() {
+ List list = new ArrayList<>(DATA3);
+ ListIterator results = new ListIterator<>(-1, list.iterator());
+
+ Assert.assertEquals(ImmutableList.of(4, 5, 6), list);
+ Assert.assertEquals(ImmutableList.of(4, 5, 6), results.list());
+
+ Assert.assertThrows(UnsupportedOperationException.class, () -> {
+ results.remove();
+ });
+ results.next();
+ Assert.assertThrows(UnsupportedOperationException.class, () -> {
+ results.remove();
+ });
+
+ Assert.assertEquals(ImmutableList.of(4, 5, 6), list);
+ Assert.assertEquals(ImmutableList.of(4, 5, 6), results.list());
+ }
+
+ @Test
+ public void testRemoveWithoutResult() {
+ Iterator results = new ListIterator<>(-1, EMPTY);
+ Assert.assertThrows(UnsupportedOperationException.class, () -> {
+ results.remove();
+ });
+
+ List list0 = new ArrayList<>();
+ Iterator results2 = new ListIterator<>(-1, list0.iterator());
+ Assert.assertThrows(UnsupportedOperationException.class, () -> {
+ results2.remove();
+ });
+ }
+
+ @Test
+ public void testClose() throws Exception {
+ CloseableItor c1 = new CloseableItor<>(DATA1.iterator());
+
+ ListIterator results = new ListIterator<>(-1, c1);
+
+ Assert.assertFalse(c1.closed());
+
+ results.close();
+
+ Assert.assertTrue(c1.closed());
+ }
+
+ @Test
+ public void testListWithConstructFromList() {
+ ListIterator results;
+
+ results = new ListIterator<>(ImmutableList.of());
+ Assert.assertEquals(ImmutableList.of(), results.list());
+
+ results = new ListIterator<>(DATA1);
+ Assert.assertEquals(ImmutableList.of(1), results.list());
+
+ results = new ListIterator<>(DATA2);
+ Assert.assertEquals(ImmutableList.of(2, 3), results.list());
+
+ results = new ListIterator<>(DATA3);
+ Assert.assertEquals(ImmutableList.of(4, 5, 6), results.list());
+ }
+
+ @Test
+ public void testHasNextAndNextWithConstructFromList() {
+ ListIterator results0 = new ListIterator<>(ImmutableList.of());
+ Assert.assertFalse(results0.hasNext());
+ Assert.assertThrows(NoSuchElementException.class, () -> {
+ results0.next();
+ });
+
+ ListIterator results1 = new ListIterator<>(DATA1);
+ Assert.assertTrue(results1.hasNext());
+ Assert.assertEquals(1, results1.next());
+ Assert.assertFalse(results1.hasNext());
+ Assert.assertThrows(NoSuchElementException.class, () -> {
+ results1.next();
+ });
+
+ ListIterator results3 = new ListIterator<>(DATA3);
+ Assert.assertTrue(results3.hasNext());
+ Assert.assertEquals(4, results3.next());
+ Assert.assertTrue(results3.hasNext());
+ Assert.assertEquals(5, results3.next());
+ Assert.assertTrue(results3.hasNext());
+ Assert.assertEquals(6, results3.next());
+ Assert.assertFalse(results3.hasNext());
+ Assert.assertThrows(NoSuchElementException.class, () -> {
+ results3.next();
+ });
+ }
+
+ @Test
+ public void testNextWithConstructFromList() {
+ ListIterator results0 = new ListIterator<>(ImmutableList.of());
+ Assert.assertThrows(NoSuchElementException.class, () -> {
+ results0.next();
+ });
+
+ ListIterator results3 = new ListIterator<>(DATA3);
+ Assert.assertEquals(4, results3.next());
+ Assert.assertEquals(5, results3.next());
+ Assert.assertEquals(6, results3.next());
+ Assert.assertThrows(NoSuchElementException.class, () -> {
+ results3.next();
+ });
+ }
+
+ @Test
+ public void testNextAfterListWithConstructFromList() {
+ ListIterator results3 = new ListIterator<>(DATA3);
+ Assert.assertEquals(ImmutableList.of(4, 5, 6), results3.list());
+ Assert.assertEquals(4, results3.next());
+ Assert.assertEquals(5, results3.next());
+ Assert.assertEquals(6, results3.next());
+ Assert.assertThrows(NoSuchElementException.class, () -> {
+ results3.next();
+ });
+ }
+}