diff --git a/src/main/java/spliterators/part1/exercise/RectangleSpliterator.java b/src/main/java/spliterators/part1/exercise/RectangleSpliterator.java index 678f4f5..ad94dc3 100755 --- a/src/main/java/spliterators/part1/exercise/RectangleSpliterator.java +++ b/src/main/java/spliterators/part1/exercise/RectangleSpliterator.java @@ -9,38 +9,60 @@ public class RectangleSpliterator extends Spliterators.AbstractIntSpliterator { private final int innerLength; private final int[][] array; - private final int startOuterInclusive; - private final int endOuterExclusive; - private final int startInnerInclusive; + private int startInclusive; + private int endExclusive; public RectangleSpliterator(int[][] array) { - this(array, 0, array.length, 0); + this(array, 0, array.length * array[0].length); } - private RectangleSpliterator(int[][] array, int startOuterInclusive, int endOuterExclusive, int startInnerInclusive) { + private RectangleSpliterator(int[][] array, int startInclusive, int endExclusive) { super(Long.MAX_VALUE, Spliterator.IMMUTABLE | Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.NONNULL); innerLength = array.length == 0 ? 0 : array[0].length; this.array = array; - this.startOuterInclusive = startOuterInclusive; - this.endOuterExclusive = endOuterExclusive; - this.startInnerInclusive = startInnerInclusive; + this.startInclusive = startInclusive; + this.endExclusive = endExclusive; } @Override public OfInt trySplit() { - // TODO - throw new UnsupportedOperationException(); + int length = (int) estimateSize(); + + if (length < 5) { + return null; + } + + int mid = startInclusive + length / 2; + + RectangleSpliterator rectangleSpliterator = new RectangleSpliterator(array, startInclusive, mid); + + startInclusive = mid; + return rectangleSpliterator; } @Override public long estimateSize() { - return ((long) endOuterExclusive - startOuterInclusive)*innerLength - startInnerInclusive; + return (long) (endExclusive - startInclusive); } @Override public boolean tryAdvance(IntConsumer action) { - // TODO - throw new UnsupportedOperationException(); + int i = startInclusive / innerLength; + int j = startInclusive - i*innerLength; + + action.accept(array[i][j]); + + return true; + } + + @Override + public void forEachRemaining(IntConsumer action) { + for (int i = startInclusive; i < endExclusive; i++) { + int ii = i / innerLength; + int jj = i - ii*innerLength; + + action.accept(array[ii][jj]); + } } } diff --git a/src/main/java/spliterators/part1/exercise/RectangleSpliteratorExercise.java b/src/main/java/spliterators/part1/exercise/RectangleSpliteratorExercise.java index 1316732..01bb82a 100755 --- a/src/main/java/spliterators/part1/exercise/RectangleSpliteratorExercise.java +++ b/src/main/java/spliterators/part1/exercise/RectangleSpliteratorExercise.java @@ -10,8 +10,8 @@ @Fork(1) @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.MILLISECONDS) -@Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) -@Measurement(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) +@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS) @State(Scope.Thread) public class RectangleSpliteratorExercise { @@ -36,7 +36,6 @@ public void setup() { } } - @Benchmark public long baiseline_seq() { return Arrays.stream(array) diff --git a/src/test/java/spliterators/part1/exercise/RectangleSpliteratorTest.java b/src/test/java/spliterators/part1/exercise/RectangleSpliteratorTest.java new file mode 100644 index 0000000..505b849 --- /dev/null +++ b/src/test/java/spliterators/part1/exercise/RectangleSpliteratorTest.java @@ -0,0 +1,73 @@ +package spliterators.part1.exercise; + +import org.junit.Before; +import org.junit.Test; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Setup; + +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.StreamSupport; + +import static org.junit.Assert.*; + +/** + * Created by student on 7/14/17. + */ + +public class RectangleSpliteratorTest { + + public int outerLength; + + public int innerLength; + + public int[][] array; + + @Before + public void setup() { + outerLength = ThreadLocalRandom.current().nextInt(1000); + innerLength = ThreadLocalRandom.current().nextInt(1000); + + + array = new int[outerLength][]; + + for (int i = 0; i < array.length; i++) { + int[] inner = new int[innerLength]; + array[i] = inner; + for (int j = 0; j < inner.length; j++) { + inner[j] = ThreadLocalRandom.current().nextInt(); + } + } + } + + @Test + public void sum() { + long l = rectangle_par(); + long l1 = rectangle_seq(); + + long res = 0; + for (int i = 0; i < array.length; i++) { + for (int j = 0; j < array[i].length; j++) { + res += array[i][j]; + } + } + + assertEquals(res,l); + assertEquals(res,l1); + } + + public long rectangle_seq() { + final boolean parallel = false; + return StreamSupport.intStream(new RectangleSpliterator(array), parallel) + .asLongStream() + .sum(); + } + + public long rectangle_par() { + final boolean parallel = true; + return StreamSupport.intStream(new RectangleSpliterator(array), parallel) + .asLongStream() + .sum(); + } + +} \ No newline at end of file