Copilot commented on code in PR #7333:
URL: https://github.com/apache/ignite-3/pull/7333#discussion_r2653036311
##########
modules/system-view/src/main/java/org/apache/ignite/internal/systemview/SystemViewManagerImpl.java:
##########
@@ -256,30 +267,223 @@ private static Map<String, ScannableView<?>>
toScannableViews(String localNodeNa
private static class ScannableView<T> {
private final Publisher<InternalTuple> publisher;
- private ScannableView(String localNodeName, SystemView<T> view) {
- BinaryTupleSchema schema = tupleSchemaForView(view);
+ private ScannableView(ViewRowFactory rowFactory, SystemView<T> view) {
+ this.publisher = new TransformingPublisher<>(view.dataProvider(),
object -> rowFactory.create(view, object));
+ }
- this.publisher = new TransformingPublisher<>(view.dataProvider(),
object -> {
- BinaryTupleBuilder builder = new
BinaryTupleBuilder(schema.elementCount());
+ Publisher<InternalTuple> scan() {
+ return publisher;
+ }
+ }
- int offset = 0;
- if (view instanceof NodeSystemView) {
- builder.appendString(localNodeName);
- offset++;
- }
+ private abstract static class ViewRowFactory {
+ abstract <ViewSourceT> InternalTuple create(SystemView<ViewSourceT>
view, ViewSourceT source);
+ }
- for (int i = 0; i < view.columns().size(); i++) {
- SystemViewColumn<T, ?> column = view.columns().get(i);
+ private static class NodeViewRowFactory extends ViewRowFactory {
+ private final String nodeName;
- schema.appendValue(builder, i + offset,
column.value().apply(object));
- }
+ private NodeViewRowFactory(String nodeName) {
+ this.nodeName = nodeName;
+ }
- return new BinaryTuple(schema.elementCount(), builder.build());
- });
+ @Override
+ <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> view,
ViewSourceT source) {
+ return new NodeViewRow<>(nodeName, view, source);
}
+ }
- Publisher<InternalTuple> scan() {
- return publisher;
+ private static class ClusterViewRowFactory extends ViewRowFactory {
+ private static final ViewRowFactory INSTANCE = new
ClusterViewRowFactory();
+
+ @Override
+ <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> view,
ViewSourceT source) {
+ return new ClusterViewRow<>(view, source);
}
}
+
+ private static class NodeViewRow<T> extends AbstractViewRow {
+ private final String nodeName;
+ private final SystemView<T> view;
+ private final T source;
+
+ private NodeViewRow(String nodeName, SystemView<T> view, T source) {
+ this.nodeName = nodeName;
+ this.view = view;
+ this.source = source;
+ }
+
+ @Override
+ public int elementCount() {
+ return view.columns().size() + 1;
+ }
+
+ @Override
+ public ByteBuffer byteBuffer() {
+ throw new UnsupportedOperationException("byteBuffer");
+ }
+
+ @Override
+ <ReturnT> ReturnT value(int columnIndex) {
+ return columnIndex == 0
+ ? (ReturnT) nodeName
+ : (ReturnT) view.columns().get(columnIndex -
1).value().apply(source);
+ }
+ }
+
+ private static class ClusterViewRow<T> extends AbstractViewRow {
+ private final SystemView<T> view;
+ private final T source;
+
+ private ClusterViewRow(SystemView<T> view, T source) {
+ this.view = view;
+ this.source = source;
+ }
+
+ @Override
+ public int elementCount() {
+ return view.columns().size();
+ }
+
+ @Override
+ public ByteBuffer byteBuffer() {
+ throw new UnsupportedOperationException("byteBuffer");
+ }
+
+ @Override
+ <ReturnT> ReturnT value(int columnIndex) {
+ return (ReturnT)
view.columns().get(columnIndex).value().apply(source);
+ }
+ }
+
+ private abstract static class AbstractViewRow implements InternalTuple {
+ abstract <T> T value(int columnIndex);
+
+ @Override
+ public boolean hasNullValue(int columnIndex) {
+ return value(columnIndex) == null;
+ }
+
+ @Override
+ public boolean booleanValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Boolean booleanValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public byte byteValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Byte byteValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public short shortValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Short shortValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public int intValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Integer intValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public long longValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Long longValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public float floatValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Float floatValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public double doubleValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Double doubleValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public BigDecimal decimalValue(int columnIndex, int scale) {
+ BigDecimal value = value(columnIndex);
+
+ return value.setScale(scale, RoundingMode.UNNECESSARY);
+ }
+
+ @Override
+ public String stringValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public byte[] bytesValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public UUID uuidValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public LocalDate dateValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public LocalTime timeValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public LocalDateTime dateTimeValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Instant timestampValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Period periodValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Duration durationValue(int columnIndex) {
+ return value(columnIndex);
+ }
+ }
Review Comment:
Trailing whitespace detected after the closing brace. Please remove it to
maintain code cleanliness.
```suggestion
}
```
##########
modules/system-view/src/main/java/org/apache/ignite/internal/systemview/SystemViewManagerImpl.java:
##########
@@ -256,30 +267,223 @@ private static Map<String, ScannableView<?>>
toScannableViews(String localNodeNa
private static class ScannableView<T> {
private final Publisher<InternalTuple> publisher;
- private ScannableView(String localNodeName, SystemView<T> view) {
- BinaryTupleSchema schema = tupleSchemaForView(view);
+ private ScannableView(ViewRowFactory rowFactory, SystemView<T> view) {
+ this.publisher = new TransformingPublisher<>(view.dataProvider(),
object -> rowFactory.create(view, object));
+ }
- this.publisher = new TransformingPublisher<>(view.dataProvider(),
object -> {
- BinaryTupleBuilder builder = new
BinaryTupleBuilder(schema.elementCount());
+ Publisher<InternalTuple> scan() {
+ return publisher;
+ }
+ }
- int offset = 0;
- if (view instanceof NodeSystemView) {
- builder.appendString(localNodeName);
- offset++;
- }
+ private abstract static class ViewRowFactory {
+ abstract <ViewSourceT> InternalTuple create(SystemView<ViewSourceT>
view, ViewSourceT source);
+ }
- for (int i = 0; i < view.columns().size(); i++) {
- SystemViewColumn<T, ?> column = view.columns().get(i);
+ private static class NodeViewRowFactory extends ViewRowFactory {
+ private final String nodeName;
- schema.appendValue(builder, i + offset,
column.value().apply(object));
- }
+ private NodeViewRowFactory(String nodeName) {
+ this.nodeName = nodeName;
+ }
- return new BinaryTuple(schema.elementCount(), builder.build());
- });
+ @Override
+ <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> view,
ViewSourceT source) {
+ return new NodeViewRow<>(nodeName, view, source);
}
+ }
- Publisher<InternalTuple> scan() {
- return publisher;
+ private static class ClusterViewRowFactory extends ViewRowFactory {
+ private static final ViewRowFactory INSTANCE = new
ClusterViewRowFactory();
+
+ @Override
+ <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> view,
ViewSourceT source) {
+ return new ClusterViewRow<>(view, source);
}
}
+
+ private static class NodeViewRow<T> extends AbstractViewRow {
+ private final String nodeName;
+ private final SystemView<T> view;
+ private final T source;
+
+ private NodeViewRow(String nodeName, SystemView<T> view, T source) {
+ this.nodeName = nodeName;
+ this.view = view;
+ this.source = source;
+ }
+
+ @Override
+ public int elementCount() {
+ return view.columns().size() + 1;
+ }
+
+ @Override
+ public ByteBuffer byteBuffer() {
+ throw new UnsupportedOperationException("byteBuffer");
+ }
+
+ @Override
+ <ReturnT> ReturnT value(int columnIndex) {
+ return columnIndex == 0
+ ? (ReturnT) nodeName
+ : (ReturnT) view.columns().get(columnIndex -
1).value().apply(source);
+ }
+ }
+
+ private static class ClusterViewRow<T> extends AbstractViewRow {
+ private final SystemView<T> view;
+ private final T source;
+
+ private ClusterViewRow(SystemView<T> view, T source) {
+ this.view = view;
+ this.source = source;
+ }
+
+ @Override
+ public int elementCount() {
+ return view.columns().size();
+ }
+
+ @Override
+ public ByteBuffer byteBuffer() {
+ throw new UnsupportedOperationException("byteBuffer");
+ }
+
+ @Override
+ <ReturnT> ReturnT value(int columnIndex) {
+ return (ReturnT)
view.columns().get(columnIndex).value().apply(source);
+ }
+ }
+
+ private abstract static class AbstractViewRow implements InternalTuple {
+ abstract <T> T value(int columnIndex);
+
+ @Override
+ public boolean hasNullValue(int columnIndex) {
+ return value(columnIndex) == null;
+ }
+
+ @Override
+ public boolean booleanValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Boolean booleanValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public byte byteValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Byte byteValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public short shortValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Short shortValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public int intValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Integer intValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public long longValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Long longValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public float floatValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Float floatValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public double doubleValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Double doubleValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public BigDecimal decimalValue(int columnIndex, int scale) {
+ BigDecimal value = value(columnIndex);
+
Review Comment:
The decimalValue method will throw a NullPointerException if the value at
columnIndex is null. Consider adding a null check before calling setScale, or
documenting that null values should be checked using hasNullValue before
calling this method.
```suggestion
if (value == null) {
return null;
}
```
##########
modules/system-view/src/main/java/org/apache/ignite/internal/systemview/SystemViewManagerImpl.java:
##########
@@ -256,30 +267,223 @@ private static Map<String, ScannableView<?>>
toScannableViews(String localNodeNa
private static class ScannableView<T> {
private final Publisher<InternalTuple> publisher;
- private ScannableView(String localNodeName, SystemView<T> view) {
- BinaryTupleSchema schema = tupleSchemaForView(view);
+ private ScannableView(ViewRowFactory rowFactory, SystemView<T> view) {
+ this.publisher = new TransformingPublisher<>(view.dataProvider(),
object -> rowFactory.create(view, object));
+ }
- this.publisher = new TransformingPublisher<>(view.dataProvider(),
object -> {
- BinaryTupleBuilder builder = new
BinaryTupleBuilder(schema.elementCount());
+ Publisher<InternalTuple> scan() {
+ return publisher;
+ }
+ }
- int offset = 0;
- if (view instanceof NodeSystemView) {
- builder.appendString(localNodeName);
- offset++;
- }
+ private abstract static class ViewRowFactory {
+ abstract <ViewSourceT> InternalTuple create(SystemView<ViewSourceT>
view, ViewSourceT source);
+ }
- for (int i = 0; i < view.columns().size(); i++) {
- SystemViewColumn<T, ?> column = view.columns().get(i);
+ private static class NodeViewRowFactory extends ViewRowFactory {
+ private final String nodeName;
- schema.appendValue(builder, i + offset,
column.value().apply(object));
- }
+ private NodeViewRowFactory(String nodeName) {
+ this.nodeName = nodeName;
+ }
- return new BinaryTuple(schema.elementCount(), builder.build());
- });
+ @Override
+ <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> view,
ViewSourceT source) {
+ return new NodeViewRow<>(nodeName, view, source);
}
+ }
- Publisher<InternalTuple> scan() {
- return publisher;
+ private static class ClusterViewRowFactory extends ViewRowFactory {
+ private static final ViewRowFactory INSTANCE = new
ClusterViewRowFactory();
+
+ @Override
+ <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> view,
ViewSourceT source) {
+ return new ClusterViewRow<>(view, source);
}
}
Review Comment:
The ViewRowFactory abstract class and its implementations
(NodeViewRowFactory, ClusterViewRowFactory) lack JavaDoc documentation.
Consider adding class-level and method-level documentation to explain their
purpose and the factory pattern being used for creating view rows.
##########
modules/system-view/src/main/java/org/apache/ignite/internal/systemview/SystemViewManagerImpl.java:
##########
@@ -256,30 +267,223 @@ private static Map<String, ScannableView<?>>
toScannableViews(String localNodeNa
private static class ScannableView<T> {
private final Publisher<InternalTuple> publisher;
- private ScannableView(String localNodeName, SystemView<T> view) {
- BinaryTupleSchema schema = tupleSchemaForView(view);
+ private ScannableView(ViewRowFactory rowFactory, SystemView<T> view) {
+ this.publisher = new TransformingPublisher<>(view.dataProvider(),
object -> rowFactory.create(view, object));
+ }
- this.publisher = new TransformingPublisher<>(view.dataProvider(),
object -> {
- BinaryTupleBuilder builder = new
BinaryTupleBuilder(schema.elementCount());
+ Publisher<InternalTuple> scan() {
+ return publisher;
+ }
+ }
- int offset = 0;
- if (view instanceof NodeSystemView) {
- builder.appendString(localNodeName);
- offset++;
- }
+ private abstract static class ViewRowFactory {
+ abstract <ViewSourceT> InternalTuple create(SystemView<ViewSourceT>
view, ViewSourceT source);
+ }
- for (int i = 0; i < view.columns().size(); i++) {
- SystemViewColumn<T, ?> column = view.columns().get(i);
+ private static class NodeViewRowFactory extends ViewRowFactory {
+ private final String nodeName;
- schema.appendValue(builder, i + offset,
column.value().apply(object));
- }
+ private NodeViewRowFactory(String nodeName) {
+ this.nodeName = nodeName;
+ }
- return new BinaryTuple(schema.elementCount(), builder.build());
- });
+ @Override
+ <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> view,
ViewSourceT source) {
+ return new NodeViewRow<>(nodeName, view, source);
}
+ }
- Publisher<InternalTuple> scan() {
- return publisher;
+ private static class ClusterViewRowFactory extends ViewRowFactory {
+ private static final ViewRowFactory INSTANCE = new
ClusterViewRowFactory();
+
+ @Override
+ <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> view,
ViewSourceT source) {
+ return new ClusterViewRow<>(view, source);
}
}
+
+ private static class NodeViewRow<T> extends AbstractViewRow {
+ private final String nodeName;
+ private final SystemView<T> view;
+ private final T source;
+
+ private NodeViewRow(String nodeName, SystemView<T> view, T source) {
+ this.nodeName = nodeName;
+ this.view = view;
+ this.source = source;
+ }
+
+ @Override
+ public int elementCount() {
+ return view.columns().size() + 1;
+ }
+
+ @Override
+ public ByteBuffer byteBuffer() {
+ throw new UnsupportedOperationException("byteBuffer");
+ }
+
+ @Override
+ <ReturnT> ReturnT value(int columnIndex) {
+ return columnIndex == 0
+ ? (ReturnT) nodeName
+ : (ReturnT) view.columns().get(columnIndex -
1).value().apply(source);
+ }
+ }
+
+ private static class ClusterViewRow<T> extends AbstractViewRow {
+ private final SystemView<T> view;
+ private final T source;
+
+ private ClusterViewRow(SystemView<T> view, T source) {
+ this.view = view;
+ this.source = source;
+ }
+
+ @Override
+ public int elementCount() {
+ return view.columns().size();
+ }
+
+ @Override
+ public ByteBuffer byteBuffer() {
+ throw new UnsupportedOperationException("byteBuffer");
+ }
+
+ @Override
+ <ReturnT> ReturnT value(int columnIndex) {
+ return (ReturnT)
view.columns().get(columnIndex).value().apply(source);
+ }
+ }
+
+ private abstract static class AbstractViewRow implements InternalTuple {
+ abstract <T> T value(int columnIndex);
+
+ @Override
+ public boolean hasNullValue(int columnIndex) {
+ return value(columnIndex) == null;
+ }
+
+ @Override
+ public boolean booleanValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Boolean booleanValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public byte byteValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Byte byteValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public short shortValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Short shortValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public int intValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Integer intValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public long longValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Long longValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public float floatValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Float floatValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public double doubleValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Double doubleValueBoxed(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public BigDecimal decimalValue(int columnIndex, int scale) {
+ BigDecimal value = value(columnIndex);
+
+ return value.setScale(scale, RoundingMode.UNNECESSARY);
+ }
+
+ @Override
+ public String stringValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public byte[] bytesValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public UUID uuidValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public LocalDate dateValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public LocalTime timeValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public LocalDateTime dateTimeValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Instant timestampValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Period periodValue(int columnIndex) {
+ return value(columnIndex);
+ }
+
+ @Override
+ public Duration durationValue(int columnIndex) {
+ return value(columnIndex);
+ }
Review Comment:
The NodeViewRow, ClusterViewRow, and AbstractViewRow classes lack JavaDoc
documentation. Consider adding class-level documentation explaining that these
classes implement late materialization for system view rows and how they differ
from the previous BinaryTuple-based approach.
##########
modules/core/src/main/java/org/apache/ignite/internal/util/FlatteningIterator.java:
##########
@@ -0,0 +1,86 @@
+/*
+ * 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.ignite.internal.util;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * An iterator which implements FLAT MAP operation on the input.
+ */
+public class FlatteningIterator<T> implements Iterator<T>, AutoCloseable {
+ private final Iterator<? extends Iterable<T>> source;
+
+ private @Nullable Iterator<T> current;
+
+ /** Constructs the object. */
+ public FlatteningIterator(Iterator<? extends Iterable<T>> source) {
+ this.source = source;
+ }
+
+ @Override
+ public boolean hasNext() {
+ do {
+ if (current != null) {
+ if (current.hasNext()) {
+ return true;
+ }
+
+ // current is completely drained, reset.
+ current = null;
+ }
+
+ if (!source.hasNext()) {
+ return false;
+ }
+
+ current = source.next().iterator();
+ } while (true);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public T next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ assert current != null;
+
+ return current.next();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void remove() {
+ if (current == null) {
+ throw new IllegalStateException();
+ }
+
+ current.remove();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void close() throws Exception {
+ if (source instanceof AutoCloseable) {
+ ((AutoCloseable) source).close();
+ }
+ }
+}
Review Comment:
The new FlatteningIterator class lacks test coverage. Consider adding unit
tests to verify the iterator behavior, including edge cases such as empty
iterables, null handling in hasNext/next, and proper AutoCloseable behavior.
##########
modules/runner/src/integrationTest/java/org/apache/ignite/internal/benchmark/SystemViewsBenchmark.java:
##########
@@ -0,0 +1,158 @@
+/*
+ * 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.ignite.internal.benchmark;
+
+import java.io.IOException;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+import org.apache.ignite.sql.IgniteSql;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+/**
+ * Benchmark that runs sql queries over system views to measure its
performance.
+ */
+@State(Scope.Benchmark)
+@Fork(1)
+@Threads(1)
+@Warmup(iterations = 10, time = 2)
+@Measurement(iterations = 20, time = 2)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@SuppressWarnings({"WeakerAccess", "unused"})
+public class SystemViewsBenchmark extends AbstractMultiNodeBenchmark {
+ private IgniteSql sql;
+
+ @Param("3")
+ private int clusterSize;
+
+ /** Fills the table with data. */
+ @Setup
+ public void setUp() throws IOException {
+ sql = publicIgnite.sql();
+ }
+
+ /** Benchmark to measure performance of queries over TABLE-COLUMNS system
view. */
+ @Benchmark
+ @OutputTimeUnit(TimeUnit.MICROSECONDS)
+ public void getPrimaryKeys(FiveHundredTablesState state, Blackhole bh) {
+ try (var rs = sql.execute(null, "SELECT column_name \n"
+ + "FROM SYSTEM.table_columns \n"
+ + "WHERE table_name = ? \n"
+ + "AND pk_column_ordinal IS NOT NULL;", state.tableName())) {
+ while (rs.hasNext()) {
+ bh.consume(rs.next());
+ }
+ }
+ }
+
+ /** Benchmark to measure performance of queries over TABLE-COLUMNS system
view. */
+ @Benchmark
+ @OutputTimeUnit(TimeUnit.MICROSECONDS)
+ public void getColumnsType(FiveHundredTablesState state, Blackhole bh) {
+ try (var rs = sql.execute(null, "SELECT column_name,column_type\n"
+ + "FROM SYSTEM.table_columns \n"
Review Comment:
Trailing whitespace detected at the end of the line. Please remove it to
maintain code cleanliness.
```suggestion
+ "FROM SYSTEM.table_columns\n"
```
##########
modules/core/src/main/java/org/apache/ignite/internal/util/FlatteningIterator.java:
##########
@@ -0,0 +1,86 @@
+/*
+ * 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.ignite.internal.util;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * An iterator which implements FLAT MAP operation on the input.
Review Comment:
Trailing whitespace detected at the end of the JavaDoc comment. Please
remove it to maintain code cleanliness.
```suggestion
* An iterator which implements FLAT MAP operation on the input.
```
##########
modules/runner/src/integrationTest/java/org/apache/ignite/internal/benchmark/SystemViewsBenchmark.java:
##########
@@ -0,0 +1,158 @@
+/*
+ * 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.ignite.internal.benchmark;
+
+import java.io.IOException;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+import org.apache.ignite.sql.IgniteSql;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+/**
+ * Benchmark that runs sql queries over system views to measure its
performance.
+ */
+@State(Scope.Benchmark)
+@Fork(1)
+@Threads(1)
+@Warmup(iterations = 10, time = 2)
+@Measurement(iterations = 20, time = 2)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@SuppressWarnings({"WeakerAccess", "unused"})
+public class SystemViewsBenchmark extends AbstractMultiNodeBenchmark {
+ private IgniteSql sql;
+
+ @Param("3")
+ private int clusterSize;
+
+ /** Fills the table with data. */
+ @Setup
+ public void setUp() throws IOException {
+ sql = publicIgnite.sql();
+ }
+
+ /** Benchmark to measure performance of queries over TABLE-COLUMNS system
view. */
+ @Benchmark
+ @OutputTimeUnit(TimeUnit.MICROSECONDS)
+ public void getPrimaryKeys(FiveHundredTablesState state, Blackhole bh) {
+ try (var rs = sql.execute(null, "SELECT column_name \n"
+ + "FROM SYSTEM.table_columns \n"
+ + "WHERE table_name = ? \n"
+ + "AND pk_column_ordinal IS NOT NULL;", state.tableName())) {
+ while (rs.hasNext()) {
+ bh.consume(rs.next());
+ }
+ }
+ }
+
+ /** Benchmark to measure performance of queries over TABLE-COLUMNS system
view. */
+ @Benchmark
+ @OutputTimeUnit(TimeUnit.MICROSECONDS)
+ public void getColumnsType(FiveHundredTablesState state, Blackhole bh) {
+ try (var rs = sql.execute(null, "SELECT column_name,column_type\n"
+ + "FROM SYSTEM.table_columns \n"
+ + "WHERE table_name = ?;", state.tableName())) {
+ while (rs.hasNext()) {
+ bh.consume(rs.next());
+ }
+ }
+ }
+
+ /** State that creates 500 tables with 10 columns each and 2 columns
primary key. */
+ @State(Scope.Benchmark)
+ public static class FiveHundredTablesState {
+ private static final int TABLES_COUNT = 500;
+
+ /** Creates necessary tables. */
+ @Setup
+ public void setUp() throws IOException {
+ IgniteSql sql = publicIgnite.sql();
+
+ int columnsCount = 10;
+
+ StringBuilder scriptBuilder = new StringBuilder(
+ "CREATE ZONE my_zone (PARTITIONS 1, REPLICAS 1) STORAGE
PROFILES ['default'];"
+ ).append("ALTER ZONE my_zone SET DEFAULT;");
+
+ for (int t = 0; t < TABLES_COUNT; t++) {
+ scriptBuilder.append("CREATE TABLE
my_table_").append(t).append("(");
+
+ for (int c = 0; c < columnsCount; c++) {
+ if (c > 0) {
+ scriptBuilder.append(", ");
+ }
+
+ scriptBuilder.append("c_").append(c).append(" INT");
+ }
+
+ scriptBuilder.append(", PRIMARY KEY (c_1, c_2));");
+ }
+
+ sql.executeScript(scriptBuilder.toString());
+ }
+
+ @SuppressWarnings("MethodMayBeStatic")
+ String tableName() {
+ return "MY_TABLE_" +
ThreadLocalRandom.current().nextInt(TABLES_COUNT);
+ }
+ }
+
+ /**
+ * Benchmark's entry point.
+ */
+ public static void main(String[] args) throws RunnerException {
+ Options opt = new OptionsBuilder()
+ .include(".*" + SystemViewsBenchmark.class.getSimpleName() +
".*")
+ .build();
+
+ new Runner(opt).run();
+ }
+
+ @Override
+ protected void createDistributionZoneOnStartup() {
+ // NO-OP
+ }
+
+ @Override
+ protected void createTablesOnStartup() {
+ // NO-OP
+ }
+
+ @Override
+ protected int nodes() {
+ return clusterSize;
+ }
+}
+
+
Review Comment:
Extra blank lines at the end of the file. Please remove them to maintain
consistent formatting.
```suggestion
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]