blob: 40a39a21789810ea90b9f80f018596042c51c87f [file] [log] [blame]
/*
* 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 org.apache.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.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import org.junit.Test;
import org.apache.hugegraph.iterator.BatchMapperIterator;
import org.apache.hugegraph.testutil.Assert;
import org.apache.hugegraph.unit.BaseUnitTest;
import org.apache.hugegraph.unit.iterator.ExtendableIteratorTest.CloseableItor;
import com.google.common.collect.ImmutableList;
@SuppressWarnings("resource")
public class BatchMapperIteratorTest extends BaseUnitTest {
private static final Iterator<Integer> EMPTY = Collections.emptyIterator();
private static final List<Integer> DATA1 = ImmutableList.of(1);
private static final List<Integer> DATA2 = ImmutableList.of(2, 3);
private static final List<Integer> DATA3 = ImmutableList.of(4, 5, 6);
private static final Function<List<Integer>, Iterator<Integer>> MAPPER =
batch -> batch.iterator();
@Test
public void testBatchMapper() {
Iterator<Integer> 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<Integer> 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<Integer> 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<Integer> 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<Integer> 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<Integer> 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<Integer> 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<Integer> results;
results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> {
List<Integer> 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<Integer> results;
results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> {
return null;
});
Assert.assertFalse(results.hasNext());
Assert.assertFalse(results.hasNext());
AtomicInteger count1 = new AtomicInteger(0);
results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> {
if (count1.incrementAndGet() == 1) {
return null;
}
return batch.iterator();
});
Assert.assertTrue(results.hasNext());
Assert.assertEquals(5, results.next());
Assert.assertEquals(6, results.next());
Assert.assertFalse(results.hasNext());
AtomicInteger count2 = new AtomicInteger(0);
results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> {
if (count2.incrementAndGet() == 2) {
return null;
}
return batch.iterator();
});
Assert.assertTrue(results.hasNext());
Assert.assertEquals(4, results.next());
Assert.assertEquals(6, results.next());
Assert.assertFalse(results.hasNext());
AtomicInteger count3 = new AtomicInteger(0);
results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> {
if (count3.incrementAndGet() == 3) {
return null;
}
return batch.iterator();
});
Assert.assertTrue(results.hasNext());
Assert.assertEquals(4, results.next());
Assert.assertEquals(5, results.next());
Assert.assertFalse(results.hasNext());
}
@Test
public void testMapperReturnNullThenNext() {
Iterator<Integer> 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 testMapperReturnEmptyThenHasNext() {
Iterator<Integer> results;
results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> {
return Collections.emptyIterator();
});
Assert.assertFalse(results.hasNext());
Assert.assertFalse(results.hasNext());
AtomicInteger count1 = new AtomicInteger(0);
results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> {
if (count1.incrementAndGet() == 1) {
return Collections.emptyIterator();
}
return batch.iterator();
});
Assert.assertTrue(results.hasNext());
Assert.assertEquals(5, results.next());
Assert.assertEquals(6, results.next());
Assert.assertFalse(results.hasNext());
AtomicInteger count2 = new AtomicInteger(0);
results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> {
if (count2.incrementAndGet() == 2) {
return Collections.emptyIterator();
}
return batch.iterator();
});
Assert.assertTrue(results.hasNext());
Assert.assertEquals(4, results.next());
Assert.assertEquals(6, results.next());
Assert.assertFalse(results.hasNext());
AtomicInteger count3 = new AtomicInteger(0);
results = new BatchMapperIterator<>(1, DATA3.iterator(), batch -> {
if (count3.incrementAndGet() == 3) {
return Collections.emptyIterator();
}
return batch.iterator();
});
Assert.assertTrue(results.hasNext());
Assert.assertEquals(4, results.next());
Assert.assertEquals(5, results.next());
Assert.assertFalse(results.hasNext());
}
@Test
public void testClose() throws Exception {
CloseableItor<Integer> vals = new CloseableItor<>(DATA1.iterator());
Iterator<Integer> results = new BatchMapperIterator<>(1, vals, MAPPER);
Assert.assertFalse(vals.closed());
((BatchMapperIterator<?, ?>) results).close();
Assert.assertTrue(vals.closed());
}
}