This is an automated email from the ASF dual-hosted git repository. jt2594838 pushed a commit to branch remove_swtich_type in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit bf032def159e537be39faa80ccbb842ba3bdc1fc Author: Tian Jiang <[email protected]> AuthorDate: Mon Aug 24 16:46:04 2026 +0800 multiple refactors --- .../process/window/partition/frame/RangeFrame.java | 294 +++++---------------- .../org/apache/iotdb/calc/utils/TypeServices.java | 230 ++++++++++++++++ .../aggregation/VarianceAccumulatorTest.java | 3 +- .../apache/iotdb/calc/utils/TypeServicesTest.java | 112 ++++++++ 4 files changed, 412 insertions(+), 227 deletions(-) diff --git a/iotdb-core/calc-commons/src/main/java/org/apache/iotdb/calc/execution/operator/process/window/partition/frame/RangeFrame.java b/iotdb-core/calc-commons/src/main/java/org/apache/iotdb/calc/execution/operator/process/window/partition/frame/RangeFrame.java index cf59324bdd9..6e53ce6549d 100644 --- a/iotdb-core/calc-commons/src/main/java/org/apache/iotdb/calc/execution/operator/process/window/partition/frame/RangeFrame.java +++ b/iotdb-core/calc-commons/src/main/java/org/apache/iotdb/calc/execution/operator/process/window/partition/frame/RangeFrame.java @@ -24,10 +24,11 @@ import org.apache.iotdb.calc.execution.operator.process.window.utils.ColumnList; import org.apache.iotdb.calc.execution.operator.process.window.utils.Range; import org.apache.iotdb.calc.execution.operator.process.window.utils.RowComparator; import org.apache.iotdb.calc.i18n.CalcMessages; +import org.apache.iotdb.calc.utils.TypeServices; import org.apache.iotdb.commons.exception.SemanticException; import org.apache.tsfile.enums.TSDataType; -import org.apache.tsfile.write.UnSupportedDataTypeException; +import org.apache.tsfile.read.common.type.Type; import java.util.List; @@ -44,6 +45,7 @@ public class RangeFrame implements Frame { private List<ColumnList> allSortedColumns; private ColumnList column; private TSDataType dataType; + private TypeServices.RangeFrameComparator rangeFrameComparator; private int partitionSize; private RowComparator peerGroupComparator; @@ -69,6 +71,8 @@ public class RangeFrame implements Frame { this.allSortedColumns = sortedColumns; this.column = sortedColumns.get(0); this.dataType = column.getDataType(); + this.rangeFrameComparator = + TypeServices.RANGE_FRAME_COMPARATOR_SERVICE.call(Type.fromTsDataType(dataType)); this.peerGroupComparator = comparator; this.recentRange = new Range(0, 0); } @@ -285,34 +289,14 @@ public class RangeFrame implements Frame { private boolean compareInAscFrameStartFollowing(int currentIndex, int recentIndex, int channel) { checkArgument(!partition.isNull(channel, currentIndex)); - switch (column.getDataType()) { - case INT32: - case DATE: - int currentInt = column.getInt(currentIndex); - int followInt = column.getInt(recentIndex); - int deltaInt = partition.getInt(channel, currentIndex); - return followInt >= currentInt + deltaInt; - case INT64: - case TIMESTAMP: - long currentLong = column.getLong(currentIndex); - long followLong = column.getLong(recentIndex); - long deltaLong = partition.getLong(channel, currentIndex); - return followLong >= currentLong + deltaLong; - case FLOAT: - float currentFloat = column.getFloat(currentIndex); - float followFloat = column.getFloat(recentIndex); - float deltaFloat = partition.getFloat(channel, currentIndex); - return followFloat >= currentFloat + deltaFloat; - case DOUBLE: - double currentDouble = column.getDouble(currentIndex); - double followDouble = column.getDouble(recentIndex); - double deltaDouble = partition.getDouble(channel, currentIndex); - return followDouble >= currentDouble + deltaDouble; - default: - // Unreachable - throw new UnSupportedDataTypeException( - CalcMessages.UNSUPPORTED_DATA_TYPE + column.getDataType()); - } + return rangeFrameComparator.compare( + column, + partition, + currentIndex, + recentIndex, + channel, + TypeServices.RangeFrameOffsetOperation.ADD, + TypeServices.RangeFrameComparison.GREATER_THAN_OR_EQUAL); } // Find first row which satisfy: @@ -331,34 +315,14 @@ public class RangeFrame implements Frame { private boolean compareInAscFrameEndFollowing(int currentIndex, int recentIndex, int channel) { checkArgument(!partition.isNull(channel, currentIndex)); - switch (column.getDataType()) { - case INT32: - case DATE: - int currentInt = column.getInt(currentIndex); - int followInt = column.getInt(recentIndex); - int deltaInt = partition.getInt(channel, currentIndex); - return followInt > currentInt + deltaInt; - case INT64: - case TIMESTAMP: - long currentLong = column.getLong(currentIndex); - long followLong = column.getLong(recentIndex); - long deltaLong = partition.getLong(channel, currentIndex); - return followLong > currentLong + deltaLong; - case FLOAT: - float currentFloat = column.getFloat(currentIndex); - float followFloat = column.getFloat(recentIndex); - float deltaFloat = partition.getFloat(channel, currentIndex); - return followFloat > currentFloat + deltaFloat; - case DOUBLE: - double currentDouble = column.getDouble(currentIndex); - double followDouble = column.getDouble(recentIndex); - double deltaDouble = partition.getDouble(channel, currentIndex); - return followDouble > currentDouble + deltaDouble; - default: - // Unreachable - throw new UnSupportedDataTypeException( - CalcMessages.UNSUPPORTED_DATA_TYPE + column.getDataType()); - } + return rangeFrameComparator.compare( + column, + partition, + currentIndex, + recentIndex, + channel, + TypeServices.RangeFrameOffsetOperation.ADD, + TypeServices.RangeFrameComparison.GREATER_THAN); } // Find first row which satisfy: @@ -377,34 +341,14 @@ public class RangeFrame implements Frame { private boolean compareInAscFrameStartPreceding(int currentIndex, int recentIndex, int channel) { checkArgument(!partition.isNull(channel, currentIndex)); - switch (column.getDataType()) { - case INT32: - case DATE: - int currentInt = column.getInt(currentIndex); - int precedeInt = column.getInt(recentIndex); - int deltaInt = partition.getInt(channel, currentIndex); - return precedeInt >= currentInt - deltaInt; - case INT64: - case TIMESTAMP: - long currentLong = column.getLong(currentIndex); - long precedeLong = column.getLong(recentIndex); - long deltaLong = partition.getLong(channel, currentIndex); - return precedeLong >= currentLong - deltaLong; - case FLOAT: - float currentFloat = column.getFloat(currentIndex); - float precedeFollow = column.getFloat(recentIndex); - float deltaFloat = partition.getFloat(channel, currentIndex); - return precedeFollow >= currentFloat - deltaFloat; - case DOUBLE: - double currentDouble = column.getDouble(currentIndex); - double precedeDouble = column.getDouble(recentIndex); - double deltaDouble = partition.getDouble(channel, currentIndex); - return precedeDouble >= currentDouble - deltaDouble; - default: - // Unreachable - throw new UnSupportedDataTypeException( - CalcMessages.UNSUPPORTED_DATA_TYPE + column.getDataType()); - } + return rangeFrameComparator.compare( + column, + partition, + currentIndex, + recentIndex, + channel, + TypeServices.RangeFrameOffsetOperation.SUBTRACT, + TypeServices.RangeFrameComparison.GREATER_THAN_OR_EQUAL); } // Find first row which satisfy: @@ -423,34 +367,14 @@ public class RangeFrame implements Frame { private boolean compareInAscFrameEndPreceding(int currentIndex, int recentIndex, int channel) { checkArgument(!partition.isNull(channel, currentIndex)); - switch (column.getDataType()) { - case INT32: - case DATE: - int currentInt = column.getInt(currentIndex); - int precedeInt = column.getInt(recentIndex); - int deltaInt = partition.getInt(channel, currentIndex); - return precedeInt > currentInt - deltaInt; - case INT64: - case TIMESTAMP: - long currentLong = column.getLong(currentIndex); - long precedeLong = column.getLong(recentIndex); - long deltaLong = partition.getLong(channel, currentIndex); - return precedeLong > currentLong - deltaLong; - case FLOAT: - float currentFloat = column.getFloat(currentIndex); - float precedeFollow = column.getFloat(recentIndex); - float deltaFloat = partition.getFloat(channel, currentIndex); - return precedeFollow > currentFloat - deltaFloat; - case DOUBLE: - double currentDouble = column.getDouble(currentIndex); - double precedeDouble = column.getDouble(recentIndex); - double deltaDouble = partition.getDouble(channel, currentIndex); - return precedeDouble > currentDouble - deltaDouble; - default: - // Unreachable - throw new UnSupportedDataTypeException( - CalcMessages.UNSUPPORTED_DATA_TYPE + column.getDataType()); - } + return rangeFrameComparator.compare( + column, + partition, + currentIndex, + recentIndex, + channel, + TypeServices.RangeFrameOffsetOperation.SUBTRACT, + TypeServices.RangeFrameComparison.GREATER_THAN); } // Find first row which satisfy: @@ -469,34 +393,14 @@ public class RangeFrame implements Frame { private boolean compareInDescFrameStartFollowing(int currentIndex, int recentIndex, int channel) { checkArgument(!partition.isNull(channel, currentIndex)); - switch (column.getDataType()) { - case INT32: - case DATE: - int currentInt = column.getInt(currentIndex); - int followInt = column.getInt(recentIndex); - int deltaInt = partition.getInt(channel, currentIndex); - return followInt <= currentInt - deltaInt; - case INT64: - case TIMESTAMP: - long currentLong = column.getLong(currentIndex); - long followLong = column.getLong(recentIndex); - long deltaLong = partition.getLong(channel, currentIndex); - return followLong <= currentLong - deltaLong; - case FLOAT: - float currentFloat = column.getFloat(currentIndex); - float followFloat = column.getFloat(recentIndex); - float deltaFloat = partition.getFloat(channel, currentIndex); - return followFloat <= currentFloat - deltaFloat; - case DOUBLE: - double currentDouble = column.getDouble(currentIndex); - double followDouble = column.getDouble(recentIndex); - double deltaDouble = partition.getDouble(channel, currentIndex); - return followDouble <= currentDouble - deltaDouble; - default: - // Unreachable - throw new UnSupportedDataTypeException( - CalcMessages.UNSUPPORTED_DATA_TYPE + column.getDataType()); - } + return rangeFrameComparator.compare( + column, + partition, + currentIndex, + recentIndex, + channel, + TypeServices.RangeFrameOffsetOperation.SUBTRACT, + TypeServices.RangeFrameComparison.LESS_THAN_OR_EQUAL); } // Find first row which satisfy: @@ -515,34 +419,14 @@ public class RangeFrame implements Frame { private boolean compareInDescFrameEndFollowing(int currentIndex, int recentIndex, int channel) { checkArgument(!partition.isNull(channel, currentIndex)); - switch (column.getDataType()) { - case INT32: - case DATE: - int currentInt = column.getInt(currentIndex); - int followInt = column.getInt(recentIndex); - int deltaInt = partition.getInt(channel, currentIndex); - return followInt < currentInt - deltaInt; - case INT64: - case TIMESTAMP: - long currentLong = column.getLong(currentIndex); - long followLong = column.getLong(recentIndex); - long deltaLong = partition.getLong(channel, currentIndex); - return followLong < currentLong - deltaLong; - case FLOAT: - float currentFloat = column.getFloat(currentIndex); - float followFloat = column.getFloat(recentIndex); - float deltaFloat = partition.getFloat(channel, currentIndex); - return followFloat < currentFloat - deltaFloat; - case DOUBLE: - double currentDouble = column.getDouble(currentIndex); - double followDouble = column.getDouble(recentIndex); - double deltaDouble = partition.getDouble(channel, currentIndex); - return followDouble < currentDouble - deltaDouble; - default: - // Unreachable - throw new UnSupportedDataTypeException( - CalcMessages.UNSUPPORTED_DATA_TYPE + column.getDataType()); - } + return rangeFrameComparator.compare( + column, + partition, + currentIndex, + recentIndex, + channel, + TypeServices.RangeFrameOffsetOperation.SUBTRACT, + TypeServices.RangeFrameComparison.LESS_THAN); } // Find first row which satisfy: @@ -561,34 +445,14 @@ public class RangeFrame implements Frame { private boolean compareInDescFrameStartPreceding(int currentIndex, int recentIndex, int channel) { checkArgument(!partition.isNull(channel, currentIndex)); - switch (column.getDataType()) { - case INT32: - case DATE: - int currentInt = column.getInt(currentIndex); - int precedeInt = column.getInt(recentIndex); - int deltaInt = partition.getInt(channel, currentIndex); - return precedeInt <= currentInt + deltaInt; - case INT64: - case TIMESTAMP: - long currentLong = column.getLong(currentIndex); - long precedeLong = column.getLong(recentIndex); - long deltaLong = partition.getLong(channel, currentIndex); - return precedeLong <= currentLong + deltaLong; - case FLOAT: - float currentFloat = column.getFloat(currentIndex); - float precedeFollow = column.getFloat(recentIndex); - float deltaFloat = partition.getFloat(channel, currentIndex); - return precedeFollow <= currentFloat + deltaFloat; - case DOUBLE: - double currentDouble = column.getDouble(currentIndex); - double precedeDouble = column.getDouble(recentIndex); - double deltaDouble = partition.getDouble(channel, currentIndex); - return precedeDouble <= currentDouble + deltaDouble; - default: - // Unreachable - throw new UnSupportedDataTypeException( - CalcMessages.UNSUPPORTED_DATA_TYPE + column.getDataType()); - } + return rangeFrameComparator.compare( + column, + partition, + currentIndex, + recentIndex, + channel, + TypeServices.RangeFrameOffsetOperation.ADD, + TypeServices.RangeFrameComparison.LESS_THAN_OR_EQUAL); } // Find first row which satisfy: @@ -607,33 +471,13 @@ public class RangeFrame implements Frame { private boolean compareInDescFrameEndPreceding(int currentIndex, int recentIndex, int channel) { checkArgument(!partition.isNull(channel, currentIndex)); - switch (column.getDataType()) { - case INT32: - case DATE: - int currentInt = column.getInt(currentIndex); - int precedeInt = column.getInt(recentIndex); - int deltaInt = partition.getInt(channel, currentIndex); - return precedeInt < currentInt + deltaInt; - case INT64: - case TIMESTAMP: - long currentLong = column.getLong(currentIndex); - long precedeLong = column.getLong(recentIndex); - long deltaLong = partition.getLong(channel, currentIndex); - return precedeLong < currentLong + deltaLong; - case FLOAT: - float currentFloat = column.getFloat(currentIndex); - float precedeFollow = column.getFloat(recentIndex); - float deltaFloat = partition.getFloat(channel, currentIndex); - return precedeFollow < currentFloat + deltaFloat; - case DOUBLE: - double currentDouble = column.getDouble(currentIndex); - double precedeDouble = column.getDouble(recentIndex); - double deltaDouble = partition.getDouble(channel, currentIndex); - return precedeDouble < currentDouble + deltaDouble; - default: - // Unreachable - throw new UnSupportedDataTypeException( - CalcMessages.UNSUPPORTED_DATA_TYPE + column.getDataType()); - } + return rangeFrameComparator.compare( + column, + partition, + currentIndex, + recentIndex, + channel, + TypeServices.RangeFrameOffsetOperation.ADD, + TypeServices.RangeFrameComparison.LESS_THAN); } } diff --git a/iotdb-core/calc-commons/src/main/java/org/apache/iotdb/calc/utils/TypeServices.java b/iotdb-core/calc-commons/src/main/java/org/apache/iotdb/calc/utils/TypeServices.java index a68dae23632..23ab14974df 100644 --- a/iotdb-core/calc-commons/src/main/java/org/apache/iotdb/calc/utils/TypeServices.java +++ b/iotdb-core/calc-commons/src/main/java/org/apache/iotdb/calc/utils/TypeServices.java @@ -20,6 +20,7 @@ package org.apache.iotdb.calc.utils; import org.apache.iotdb.calc.execution.operator.process.window.partition.Partition; +import org.apache.iotdb.calc.execution.operator.process.window.utils.ColumnList; import org.apache.iotdb.calc.execution.operator.source.relational.aggregation.grouped.GroupedMaxMinByBaseAccumulator; import org.apache.iotdb.calc.execution.operator.source.relational.aggregation.grouped.array.BinaryBigArray; import org.apache.iotdb.calc.execution.operator.source.relational.aggregation.grouped.array.BooleanBigArray; @@ -153,6 +154,74 @@ public class TypeServices { }; }; + // RANGE frame offsets must retain each primitive type's native overflow and precision rules. + public static final TypeService<RangeFrameComparator> RANGE_FRAME_COMPARATOR_SERVICE = + type -> + switch (type.getTypeEnum()) { + case INT32, DATE -> + (column, + partition, + currentIndex, + recentIndex, + channel, + offsetOperation, + comparison) -> { + int current = column.getInt(currentIndex); + int offset = partition.getInt(channel, currentIndex); + int boundary = offsetOperation.apply(current, offset); + return comparison.compare(column.getInt(recentIndex), boundary); + }; + case INT64, TIMESTAMP -> + (column, + partition, + currentIndex, + recentIndex, + channel, + offsetOperation, + comparison) -> { + long current = column.getLong(currentIndex); + long offset = partition.getLong(channel, currentIndex); + long boundary = offsetOperation.apply(current, offset); + return comparison.compare(column.getLong(recentIndex), boundary); + }; + case FLOAT -> + (column, + partition, + currentIndex, + recentIndex, + channel, + offsetOperation, + comparison) -> { + float current = column.getFloat(currentIndex); + float offset = partition.getFloat(channel, currentIndex); + float boundary = offsetOperation.apply(current, offset); + return comparison.compare(column.getFloat(recentIndex), boundary); + }; + case DOUBLE -> + (column, + partition, + currentIndex, + recentIndex, + channel, + offsetOperation, + comparison) -> { + double current = column.getDouble(currentIndex); + double offset = partition.getDouble(channel, currentIndex); + double boundary = offsetOperation.apply(current, offset); + return comparison.compare(column.getDouble(recentIndex), boundary); + }; + case BOOLEAN, TEXT, BLOB, STRING, OBJECT, ROW, UNKNOWN, VECTOR -> + (column, + partition, + currentIndex, + recentIndex, + channel, + offsetOperation, + comparison) -> { + throw new UnSupportedDataTypeException(CalcMessages.UNSUPPORTED_DATA_TYPE + type); + }; + }; + public static final TypeService<Function<DefaultEncodingProvider, TSEncoding>> DEFAULT_ENCODING_BY_TYPE_SERVICE = type -> @@ -290,6 +359,7 @@ public class TypeServices { MEMORY_USAGE_OF_ONE_SERIALIZABLE_ROW_FIELD_SERVICE.check(); PRIMITIVE_TYPE_VALUE_EXTRACTOR_SERVICE.check(); NUMERIC_COLUMN_TO_DOUBLE_CONVERTER_SERVICE.check(); + RANGE_FRAME_COMPARATOR_SERVICE.check(); DEFAULT_ENCODING_BY_TYPE_SERVICE.check(); DEFAULT_VALUE_WRITER_SERVICE.check(); INTERMEDIATE_VALUE_WRITER_SERVICE.check(); @@ -324,6 +394,166 @@ public class TypeServices { ColumnToDoubleConverter create(Supplier<? extends RuntimeException> exceptionSupplier); } + @FunctionalInterface + public interface RangeFrameComparator { + boolean compare( + ColumnList column, + Partition partition, + int currentIndex, + int recentIndex, + int channel, + RangeFrameOffsetOperation offsetOperation, + RangeFrameComparison comparison); + } + + public enum RangeFrameOffsetOperation { + ADD { + @Override + int apply(int value, int offset) { + return value + offset; + } + + @Override + long apply(long value, long offset) { + return value + offset; + } + + @Override + float apply(float value, float offset) { + return value + offset; + } + + @Override + double apply(double value, double offset) { + return value + offset; + } + }, + SUBTRACT { + @Override + int apply(int value, int offset) { + return value - offset; + } + + @Override + long apply(long value, long offset) { + return value - offset; + } + + @Override + float apply(float value, float offset) { + return value - offset; + } + + @Override + double apply(double value, double offset) { + return value - offset; + } + }; + + abstract int apply(int value, int offset); + + abstract long apply(long value, long offset); + + abstract float apply(float value, float offset); + + abstract double apply(double value, double offset); + } + + public enum RangeFrameComparison { + GREATER_THAN_OR_EQUAL { + @Override + boolean compare(int left, int right) { + return left >= right; + } + + @Override + boolean compare(long left, long right) { + return left >= right; + } + + @Override + boolean compare(float left, float right) { + return left >= right; + } + + @Override + boolean compare(double left, double right) { + return left >= right; + } + }, + GREATER_THAN { + @Override + boolean compare(int left, int right) { + return left > right; + } + + @Override + boolean compare(long left, long right) { + return left > right; + } + + @Override + boolean compare(float left, float right) { + return left > right; + } + + @Override + boolean compare(double left, double right) { + return left > right; + } + }, + LESS_THAN_OR_EQUAL { + @Override + boolean compare(int left, int right) { + return left <= right; + } + + @Override + boolean compare(long left, long right) { + return left <= right; + } + + @Override + boolean compare(float left, float right) { + return left <= right; + } + + @Override + boolean compare(double left, double right) { + return left <= right; + } + }, + LESS_THAN { + @Override + boolean compare(int left, int right) { + return left < right; + } + + @Override + boolean compare(long left, long right) { + return left < right; + } + + @Override + boolean compare(float left, float right) { + return left < right; + } + + @Override + boolean compare(double left, double right) { + return left < right; + } + }; + + abstract boolean compare(int left, int right); + + abstract boolean compare(long left, long right); + + abstract boolean compare(float left, float right); + + abstract boolean compare(double left, double right); + } + @FunctionalInterface public interface DefaultValueWriter { void write(Partition partition, int channel, int index, ColumnBuilder builder); diff --git a/iotdb-core/calc-commons/src/test/java/org/apache/iotdb/calc/execution/operator/source/relational/aggregation/VarianceAccumulatorTest.java b/iotdb-core/calc-commons/src/test/java/org/apache/iotdb/calc/execution/operator/source/relational/aggregation/VarianceAccumulatorTest.java index 872eeaa2a33..a11bad4f5e1 100644 --- a/iotdb-core/calc-commons/src/test/java/org/apache/iotdb/calc/execution/operator/source/relational/aggregation/VarianceAccumulatorTest.java +++ b/iotdb-core/calc-commons/src/test/java/org/apache/iotdb/calc/execution/operator/source/relational/aggregation/VarianceAccumulatorTest.java @@ -22,10 +22,9 @@ import org.apache.iotdb.calc.execution.aggregation.VarianceAccumulator; import org.apache.iotdb.calc.execution.operator.source.relational.aggregation.grouped.GroupedVarianceAccumulator; import org.apache.tsfile.block.column.Column; -import org.apache.tsfile.block.column.ColumnBuilder; import org.apache.tsfile.enums.TSDataType; -import org.apache.tsfile.read.common.block.column.DoubleColumnBuilder; import org.apache.tsfile.read.common.block.column.DoubleColumn; +import org.apache.tsfile.read.common.block.column.DoubleColumnBuilder; import org.apache.tsfile.read.common.block.column.FloatColumn; import org.apache.tsfile.read.common.block.column.IntColumn; import org.apache.tsfile.read.common.block.column.LongColumn; diff --git a/iotdb-core/calc-commons/src/test/java/org/apache/iotdb/calc/utils/TypeServicesTest.java b/iotdb-core/calc-commons/src/test/java/org/apache/iotdb/calc/utils/TypeServicesTest.java index 983d969387b..f11222c26fe 100644 --- a/iotdb-core/calc-commons/src/test/java/org/apache/iotdb/calc/utils/TypeServicesTest.java +++ b/iotdb-core/calc-commons/src/test/java/org/apache/iotdb/calc/utils/TypeServicesTest.java @@ -18,20 +18,28 @@ package org.apache.iotdb.calc.utils; +import org.apache.iotdb.calc.execution.operator.process.window.partition.Partition; +import org.apache.iotdb.calc.execution.operator.process.window.utils.ColumnList; + import org.apache.tsfile.block.column.Column; import org.apache.tsfile.enums.TSDataType; +import org.apache.tsfile.read.common.block.TsBlock; import org.apache.tsfile.read.common.block.column.DoubleColumn; import org.apache.tsfile.read.common.block.column.FloatColumn; import org.apache.tsfile.read.common.block.column.IntColumn; import org.apache.tsfile.read.common.block.column.LongColumn; +import org.apache.tsfile.read.common.block.column.TimeColumn; import org.apache.tsfile.read.common.type.Type; import org.junit.Assert; import org.junit.Test; +import java.util.Collections; import java.util.Optional; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; public class TypeServicesTest { @@ -86,6 +94,51 @@ public class TypeServicesTest { .apply(0)); } + // Covers every supported RANGE-frame type and guards native integer overflow and long precision. + @Test + public void testRangeFrameComparatorPreservesNativeArithmetic() { + assertRangeFrameComparator( + TSDataType.INT32, + new IntColumn(3, Optional.empty(), new int[] {10, 12, 8}), + new IntColumn(3, Optional.empty(), new int[] {2, 0, 0})); + assertRangeFrameComparator( + TSDataType.DATE, + new IntColumn(3, Optional.empty(), new int[] {10, 12, 8}, TSDataType.DATE), + new IntColumn(3, Optional.empty(), new int[] {2, 0, 0})); + assertRangeFrameComparator( + TSDataType.INT64, + new LongColumn(3, Optional.empty(), new long[] {10, 12, 8}), + new LongColumn(3, Optional.empty(), new long[] {2, 0, 0})); + assertRangeFrameComparator( + TSDataType.TIMESTAMP, + new LongColumn(3, Optional.empty(), new long[] {10, 12, 8}), + new LongColumn(3, Optional.empty(), new long[] {2, 0, 0})); + assertRangeFrameComparator( + TSDataType.FLOAT, + new FloatColumn(3, Optional.empty(), new float[] {10, 12, 8}), + new FloatColumn(3, Optional.empty(), new float[] {2, 0, 0})); + assertRangeFrameComparator( + TSDataType.DOUBLE, + new DoubleColumn(3, Optional.empty(), new double[] {10, 12, 8}), + new DoubleColumn(3, Optional.empty(), new double[] {2, 0, 0})); + + assertTrue( + compareRangeFrameValues( + TSDataType.INT32, + new IntColumn(2, Optional.empty(), new int[] {Integer.MAX_VALUE, Integer.MIN_VALUE}), + new IntColumn(2, Optional.empty(), new int[] {1, 0}), + TypeServices.RangeFrameOffsetOperation.ADD, + TypeServices.RangeFrameComparison.GREATER_THAN_OR_EQUAL)); + assertFalse( + compareRangeFrameValues( + TSDataType.INT64, + new LongColumn( + 2, Optional.empty(), new long[] {9_007_199_254_740_992L, 9_007_199_254_740_992L}), + new LongColumn(2, Optional.empty(), new long[] {1, 0}), + TypeServices.RangeFrameOffsetOperation.ADD, + TypeServices.RangeFrameComparison.GREATER_THAN_OR_EQUAL)); + } + private static double convert(final TSDataType dataType, final Column column) { return TypeServices.NUMERIC_COLUMN_TO_DOUBLE_CONVERTER_SERVICE .call(Type.fromTsDataType(dataType)) @@ -95,4 +148,63 @@ public class TypeServicesTest { "supported data type should not use the exception factory")) .convert(column, 0); } + + private static void assertRangeFrameComparator( + final TSDataType dataType, final Column valueColumn, final Column offsetColumn) { + assertTrue( + compareRangeFrameValues( + dataType, + valueColumn, + offsetColumn, + TypeServices.RangeFrameOffsetOperation.ADD, + TypeServices.RangeFrameComparison.GREATER_THAN_OR_EQUAL)); + assertFalse( + compareRangeFrameValues( + dataType, + valueColumn, + offsetColumn, + TypeServices.RangeFrameOffsetOperation.ADD, + TypeServices.RangeFrameComparison.GREATER_THAN)); + assertTrue( + compareRangeFrameValues( + dataType, + valueColumn, + offsetColumn, + TypeServices.RangeFrameOffsetOperation.SUBTRACT, + TypeServices.RangeFrameComparison.LESS_THAN_OR_EQUAL)); + assertFalse( + compareRangeFrameValues( + dataType, + valueColumn, + offsetColumn, + TypeServices.RangeFrameOffsetOperation.SUBTRACT, + TypeServices.RangeFrameComparison.LESS_THAN)); + } + + private static boolean compareRangeFrameValues( + final TSDataType dataType, + final Column valueColumn, + final Column offsetColumn, + final TypeServices.RangeFrameOffsetOperation offsetOperation, + final TypeServices.RangeFrameComparison comparison) { + final long[] times = new long[valueColumn.getPositionCount()]; + final TsBlock block = + new TsBlock( + new TimeColumn(valueColumn.getPositionCount(), times), valueColumn, offsetColumn); + final Partition partition = + new Partition(Collections.singletonList(block), 0, valueColumn.getPositionCount()); + final ColumnList columnList = new ColumnList(Collections.singletonList(valueColumn)); + return TypeServices.RANGE_FRAME_COMPARATOR_SERVICE + .call(Type.fromTsDataType(dataType)) + .compare( + columnList, + partition, + 0, + offsetOperation == TypeServices.RangeFrameOffsetOperation.ADD + ? 1 + : valueColumn.getPositionCount() - 1, + 1, + offsetOperation, + comparison); + } }
