From 761b0ea6b13f2f5a2f1cd6ea6ef1322d0e9c3bdd Mon Sep 17 00:00:00 2001 From: Thomas Segismont Date: Wed, 31 Jan 2024 15:54:38 +0100 Subject: [PATCH] Remove RowAccumulator related code The alternative to ArrayList has never been used in Vert.x 4. We can get rid of it in Vert.x 5. Signed-off-by: Thomas Segismont --- vertx-sql-client/pom.xml | 52 -------- .../io/vertx/sqlclient/impl/RowSetImpl.java | 70 ++++------- .../accumulator/ArrayListRowAccumulator.java | 44 ------- .../accumulator/ChunkedRowAccumulator.java | 116 ------------------ .../impl/accumulator/RowAccumulator.java | 24 ---- .../RowAccumulatorReadBenchmark.java | 63 ---------- .../benchmarks/RowAccumulatorType.java | 36 ------ .../RowAccumulatorWriteBenchmark.java | 58 --------- .../io/vertx/sqlclient/benchmarks/Utils.java | 41 ------- .../impl/accumulator/RowAccumulatorTest.java | 80 ------------ 10 files changed, 21 insertions(+), 563 deletions(-) delete mode 100644 vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/accumulator/ArrayListRowAccumulator.java delete mode 100644 vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/accumulator/ChunkedRowAccumulator.java delete mode 100644 vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/accumulator/RowAccumulator.java delete mode 100644 vertx-sql-client/src/test/java/io/vertx/sqlclient/benchmarks/RowAccumulatorReadBenchmark.java delete mode 100644 vertx-sql-client/src/test/java/io/vertx/sqlclient/benchmarks/RowAccumulatorType.java delete mode 100644 vertx-sql-client/src/test/java/io/vertx/sqlclient/benchmarks/RowAccumulatorWriteBenchmark.java delete mode 100644 vertx-sql-client/src/test/java/io/vertx/sqlclient/benchmarks/Utils.java delete mode 100644 vertx-sql-client/src/test/java/io/vertx/sqlclient/impl/accumulator/RowAccumulatorTest.java diff --git a/vertx-sql-client/pom.xml b/vertx-sql-client/pom.xml index 97442e70f..d7133e2f7 100644 --- a/vertx-sql-client/pom.xml +++ b/vertx-sql-client/pom.xml @@ -62,58 +62,6 @@ test-jar test - - org.openjdk.jmh - jmh-core - ${jmh.version} - test - - - org.openjdk.jmh - jmh-generator-annprocess - ${jmh.version} - test - - - - benchmarks - - - - maven-assembly-plugin - - - assemble-benchmarks - package - - single - - - - - org.openjdk.jmh.Main - - - - src/test/assembly/benchmarks.xml - - - - - - - - - - org.openjdk.jmh - jmh-generator-annprocess - ${jmh.version} - test - - - - - diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/RowSetImpl.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/RowSetImpl.java index a0abb82a7..69e07438e 100644 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/RowSetImpl.java +++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/RowSetImpl.java @@ -19,10 +19,11 @@ import io.vertx.sqlclient.Row; import io.vertx.sqlclient.RowIterator; import io.vertx.sqlclient.RowSet; -import io.vertx.sqlclient.impl.accumulator.ArrayListRowAccumulator; -import io.vertx.sqlclient.impl.accumulator.RowAccumulator; -import java.util.NoSuchElementException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; import java.util.function.Function; import java.util.stream.Collector; @@ -38,9 +39,7 @@ class RowSetImpl extends SqlResultBase> implements RowSet { static Collector, RowSet> collector(Function mapper) { return Collector.of( RowSetImpl::new, - (set, row) -> { - set.add(mapper.apply(row)); - }, + (set, row) -> set.add(mapper.apply(row)), (set1, set2) -> null, // Shall not be invoked as this is sequential (set) -> set ); @@ -52,8 +51,7 @@ static Function, RowSetImpl> factory() { return rs -> (RowSetImpl) rs; } - private R firstRow; - private RowAccumulator rowAccumulator; + private List rowAccumulator = Collections.emptyList(); @Override public RowSet value() { @@ -61,56 +59,30 @@ public RowSet value() { } private void add(R row) { - if (rowAccumulator != null) { - rowAccumulator.accept(row); - } else if (firstRow != null) { - rowAccumulator = new ArrayListRowAccumulator<>(); - rowAccumulator.accept(firstRow); - rowAccumulator.accept(row); - firstRow = null; - } else { - firstRow = row; + if (rowAccumulator.isEmpty()) { + rowAccumulator = new ArrayList<>(); } + rowAccumulator.add(row); } @Override public RowIterator iterator() { - return rowAccumulator != null ? rowAccumulator.iterator() : SingletonRowIterator.createFor(firstRow); + Iterator iter = rowAccumulator.iterator(); + return new RowIterator() { + @Override + public boolean hasNext() { + return iter.hasNext(); + } + + @Override + public R next() { + return iter.next(); + } + }; } @Override public RowSetImpl next() { return (RowSetImpl) super.next(); } - - private static final class SingletonRowIterator implements RowIterator { - - static final SingletonRowIterator EMPTY_INSTANCE = new SingletonRowIterator<>(null); - - ROW row; - - SingletonRowIterator(ROW row) { - this.row = row; - } - - @SuppressWarnings("unchecked") - static SingletonRowIterator createFor(X row) { - return row != null ? new SingletonRowIterator<>(row) : (SingletonRowIterator) EMPTY_INSTANCE; - } - - @Override - public boolean hasNext() { - return row != null; - } - - @Override - public ROW next() { - if (row != null) { - ROW res = row; - row = null; - return res; - } - throw new NoSuchElementException(); - } - } } diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/accumulator/ArrayListRowAccumulator.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/accumulator/ArrayListRowAccumulator.java deleted file mode 100644 index 365676383..000000000 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/accumulator/ArrayListRowAccumulator.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2011-2022 Contributors to the Eclipse Foundation - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 - * which is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 - */ - -package io.vertx.sqlclient.impl.accumulator; - -import io.vertx.sqlclient.RowIterator; - -import java.util.ArrayList; -import java.util.Iterator; - -public class ArrayListRowAccumulator extends ArrayList implements RowAccumulator { - - @Override - public void accept(T t) { - add(t); - } - - @Override - public RowIterator iterator() { - return rowIterator(super.iterator()); - } - - private static RowIterator rowIterator(Iterator iter) { - return new RowIterator() { - @Override - public boolean hasNext() { - return iter.hasNext(); - } - - @Override - public U next() { - return iter.next(); - } - }; - } -} diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/accumulator/ChunkedRowAccumulator.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/accumulator/ChunkedRowAccumulator.java deleted file mode 100644 index 4a7fa4ffd..000000000 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/accumulator/ChunkedRowAccumulator.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2011-2022 Contributors to the Eclipse Foundation - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 - * which is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 - */ - -package io.vertx.sqlclient.impl.accumulator; - -import io.vertx.sqlclient.RowIterator; - -import java.util.NoSuchElementException; -import java.util.function.IntUnaryOperator; - -public class ChunkedRowAccumulator implements RowAccumulator { - - // How many items can be stored in the first chunk - private static final int FIRST_CHUNK_CAPACITY = 10; - - private final IntUnaryOperator extensionPolicy; - - // Each chunk is an array with - // - at most N value objects - // - a last element pointing to the next chunk (if any) - - // Reference useful when iterating - private final Object[] firstChunk; - // Reference useful when adding - private Object[] lastChunk; - // Number of elements in the last chunk - private int count; - - /** - * @param extensionPolicy determines the capacity of a new chunk using the capacity of the previous one - */ - public ChunkedRowAccumulator(IntUnaryOperator extensionPolicy) { - this.extensionPolicy = extensionPolicy; - firstChunk = lastChunk = newChunk(FIRST_CHUNK_CAPACITY); - count = 0; - } - - private Object[] newChunk(int capacity) { - return new Object[capacity + 1]; - } - - @Override - public void accept(T item) { - int chunkCapacity = chunkCapacity(lastChunk); - if (count == chunkCapacity) { - Object[] chunk = newChunk(extensionPolicy.applyAsInt(chunkCapacity)); - chunk[0] = item; - lastChunk[chunkCapacity] = chunk; - lastChunk = chunk; - count = 1; - } else { - lastChunk[count] = item; - count++; - } - } - - private static int chunkCapacity(Object[] chunk) { - return chunk.length - 1; - } - - @Override - public RowIterator iterator() { - return rowIterator(firstChunk, lastChunk, count); - } - - private static RowIterator rowIterator(Object[] firstChunk, Object[] lastChunk, int count) { - return new RowIterator() { - - Object[] curr = firstChunk; - int idx = 0; - - @Override - public boolean hasNext() { - if (curr != lastChunk) { - int chunkCapacity = chunkCapacity(curr); - return idx < chunkCapacity || curr[chunkCapacity] != null; - } else { - return idx < count; - } - } - - @Override - public U next() { - if (curr != lastChunk) { - int chunkCapacity = chunkCapacity(curr); - if (idx == chunkCapacity) { - Object[] next = (Object[]) curr[chunkCapacity]; - if (next == null) { - throw new NoSuchElementException(); - } - curr = next; - idx = 0; - } - } else if (idx == count) { - throw new NoSuchElementException(); - } - U item = value(); - idx++; - return item; - } - - @SuppressWarnings("unchecked") - private U value() { - return (U) curr[idx]; - } - }; - } -} diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/accumulator/RowAccumulator.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/accumulator/RowAccumulator.java deleted file mode 100644 index fca669d3b..000000000 --- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/accumulator/RowAccumulator.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2011-2022 Contributors to the Eclipse Foundation - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 - * which is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 - */ - -package io.vertx.sqlclient.impl.accumulator; - -import io.vertx.sqlclient.RowIterator; - -import java.util.function.Consumer; - -/** - * A data structure similar to a {@link java.util.Collection} but which is append-only. - */ -public interface RowAccumulator extends Consumer, Iterable { - @Override - RowIterator iterator(); -} diff --git a/vertx-sql-client/src/test/java/io/vertx/sqlclient/benchmarks/RowAccumulatorReadBenchmark.java b/vertx-sql-client/src/test/java/io/vertx/sqlclient/benchmarks/RowAccumulatorReadBenchmark.java deleted file mode 100644 index 2b7bc4eec..000000000 --- a/vertx-sql-client/src/test/java/io/vertx/sqlclient/benchmarks/RowAccumulatorReadBenchmark.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2011-2022 Contributors to the Eclipse Foundation - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 - * which is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 - */ - -package io.vertx.sqlclient.benchmarks; - -import io.vertx.sqlclient.impl.accumulator.RowAccumulator; -import org.openjdk.jmh.annotations.*; - -import java.io.IOException; -import java.util.concurrent.TimeUnit; - -import static io.vertx.sqlclient.benchmarks.Utils.generateStrings; - -@Threads(1) -@State(Scope.Thread) -@BenchmarkMode(Mode.Throughput) -@OutputTimeUnit(TimeUnit.MILLISECONDS) -@Warmup(iterations = 20, time = 1, timeUnit = TimeUnit.SECONDS) -@Measurement(iterations = 10, time = 2, timeUnit = TimeUnit.SECONDS) -@Fork(value = 3, jvmArgs = {"-Xms8g", "-Xmx8g", "-Xmn7g"}) -public class RowAccumulatorReadBenchmark { - - @Param({"ARRAY_LIST", "CHUNKED_FIXED_SIZE", "CHUNKED_GROWING_SIZE"}) - public RowAccumulatorType rowAccumulatorType; - - @Param({"5", "20", "65", "605", "1820", "5465", "16400"}) - int size; - - @Param({"false", "true"}) - boolean shuffle; - - @Param({"false", "true"}) - boolean gc; - - String[] arr; - RowAccumulator rowAccumulator; - - @Setup - public void setup() throws IOException, InterruptedException { - arr = generateStrings(size, shuffle, gc); - rowAccumulator = rowAccumulatorType.newInstance(); - for (String s : arr) { - rowAccumulator.accept(s); - } - } - - @Benchmark - public int iterate() { - int dummy = 0; - for (String s : rowAccumulator) { - dummy += s.length(); - } - return dummy; - } -} diff --git a/vertx-sql-client/src/test/java/io/vertx/sqlclient/benchmarks/RowAccumulatorType.java b/vertx-sql-client/src/test/java/io/vertx/sqlclient/benchmarks/RowAccumulatorType.java deleted file mode 100644 index 630835fdf..000000000 --- a/vertx-sql-client/src/test/java/io/vertx/sqlclient/benchmarks/RowAccumulatorType.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2011-2022 Contributors to the Eclipse Foundation - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 - * which is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 - */ - -package io.vertx.sqlclient.benchmarks; - -import io.vertx.sqlclient.impl.accumulator.ArrayListRowAccumulator; -import io.vertx.sqlclient.impl.accumulator.ChunkedRowAccumulator; -import io.vertx.sqlclient.impl.accumulator.RowAccumulator; - -import java.util.function.IntUnaryOperator; - -public enum RowAccumulatorType { - - ARRAY_LIST, CHUNKED_FIXED_SIZE, CHUNKED_GROWING_SIZE; - - RowAccumulator newInstance() { - switch (this) { - case ARRAY_LIST: - return new ArrayListRowAccumulator<>(); - case CHUNKED_FIXED_SIZE: - return new ChunkedRowAccumulator<>(IntUnaryOperator.identity()); - case CHUNKED_GROWING_SIZE: - return new ChunkedRowAccumulator<>(size -> size + (size >> 1)); - default: - throw new AssertionError(); - } - } -} diff --git a/vertx-sql-client/src/test/java/io/vertx/sqlclient/benchmarks/RowAccumulatorWriteBenchmark.java b/vertx-sql-client/src/test/java/io/vertx/sqlclient/benchmarks/RowAccumulatorWriteBenchmark.java deleted file mode 100644 index 2c4ec9a9e..000000000 --- a/vertx-sql-client/src/test/java/io/vertx/sqlclient/benchmarks/RowAccumulatorWriteBenchmark.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2011-2022 Contributors to the Eclipse Foundation - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 - * which is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 - */ - -package io.vertx.sqlclient.benchmarks; - -import io.vertx.sqlclient.impl.accumulator.RowAccumulator; -import org.openjdk.jmh.annotations.*; - -import java.io.IOException; -import java.util.concurrent.TimeUnit; - -import static io.vertx.sqlclient.benchmarks.Utils.generateStrings; - -@Threads(1) -@State(Scope.Thread) -@BenchmarkMode(Mode.Throughput) -@OutputTimeUnit(TimeUnit.MILLISECONDS) -@Warmup(iterations = 20, time = 1, timeUnit = TimeUnit.SECONDS) -@Measurement(iterations = 10, time = 2, timeUnit = TimeUnit.SECONDS) -@Fork(value = 3, jvmArgs = {"-Xms8g", "-Xmx8g", "-Xmn7g"}) -public class RowAccumulatorWriteBenchmark { - - @Param({"ARRAY_LIST", "CHUNKED_FIXED_SIZE", "CHUNKED_GROWING_SIZE"}) - public RowAccumulatorType rowAccumulatorType; - - @Param({"5", "20", "65", "605", "1820", "5465", "16400"}) - int size; - - @Param({"false", "true"}) - boolean shuffle; - - @Param({"false", "true"}) - boolean gc; - - String[] arr; - - @Setup - public void setup() throws IOException, InterruptedException { - arr = generateStrings(size, shuffle, gc); - } - - @Benchmark - public RowAccumulator accumulate() { - RowAccumulator rowAccumulator = rowAccumulatorType.newInstance(); - for (String s : arr) { - rowAccumulator.accept(s); - } - return rowAccumulator; - } -} diff --git a/vertx-sql-client/src/test/java/io/vertx/sqlclient/benchmarks/Utils.java b/vertx-sql-client/src/test/java/io/vertx/sqlclient/benchmarks/Utils.java deleted file mode 100644 index 924ead289..000000000 --- a/vertx-sql-client/src/test/java/io/vertx/sqlclient/benchmarks/Utils.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2011-2022 Contributors to the Eclipse Foundation - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 - * which is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 - */ - -package io.vertx.sqlclient.benchmarks; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Random; -import java.util.concurrent.TimeUnit; - -public class Utils { - - public static String[] generateStrings(int size, boolean shuffle, boolean gc) throws InterruptedException { - String[] strings = new String[size]; - for (int c = 0; c < size; c++) { - strings[c] = "Value" + c; - } - if (shuffle) { - Collections.shuffle(Arrays.asList(strings), new Random(0xBAD_BEE)); - } - if (gc) { - for (int c = 0; c < 5; c++) { - System.gc(); - TimeUnit.SECONDS.sleep(1); - } - } - return strings; - } - - private Utils() { - // Utility - } -} diff --git a/vertx-sql-client/src/test/java/io/vertx/sqlclient/impl/accumulator/RowAccumulatorTest.java b/vertx-sql-client/src/test/java/io/vertx/sqlclient/impl/accumulator/RowAccumulatorTest.java deleted file mode 100644 index 910ba09a6..000000000 --- a/vertx-sql-client/src/test/java/io/vertx/sqlclient/impl/accumulator/RowAccumulatorTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2011-2022 Contributors to the Eclipse Foundation - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 - * which is available at https://www.apache.org/licenses/LICENSE-2.0. - * - * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 - */ - -package io.vertx.sqlclient.impl.accumulator; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -import java.util.*; -import java.util.function.IntUnaryOperator; -import java.util.stream.IntStream; - -import static java.util.stream.Collectors.toList; -import static org.junit.Assert.assertEquals; - -@RunWith(Parameterized.class) -public class RowAccumulatorTest { - - @Parameters(name = "Accumulate {index} item(s)") - public static List testData() { - return new AbstractList() { - @Override - public Object[] get(int index) { - switch (index) { - case 0: - return new Object[]{Collections.emptyList()}; - case 1: - return new Object[]{Collections.singletonList(UUID.randomUUID().toString())}; - default: - return new Object[]{IntStream.range(0, index).mapToObj(i -> UUID.randomUUID().toString()).collect(toList())}; - } - } - - @Override - public int size() { - return 1000; - } - }; - } - - private final List data; - - public RowAccumulatorTest(List data) { - this.data = data; - } - - @Test - public void testArrayListAccumulator() { - doTest(new ArrayListRowAccumulator<>()); - } - - private void doTest(RowAccumulator rowAccumulator) { - data.forEach(rowAccumulator); - List actual = new ArrayList<>(data.size()); - for (String value : rowAccumulator) { - actual.add(value); - } - assertEquals(data, actual); - } - - @Test - public void testChunkedAccumulatorFixedChunkSize() { - doTest(new ChunkedRowAccumulator<>(IntUnaryOperator.identity())); - } - - @Test - public void testChunkedAccumulatorGrowingChunkSize() { - doTest(new ChunkedRowAccumulator<>(size -> size + (size >> 1))); - } -}