diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Column.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Column.enso index 77170f50cc84..9b0267ec3a73 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Column.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Column.enso @@ -2366,7 +2366,7 @@ type Column to_js_object self = name = self.java_column.getName storage = self.java_column.getStorage - storage_proxy = Array_Proxy.new storage.size i-> storage.getItemBoxed i + storage_proxy = Array_Proxy.new storage.getSize i-> storage.getItemBoxed i storage_json = Vector.from_polyglot_array storage_proxy JS_Object.from_pairs [["name", name], ["data", storage_json]] diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Cast_Helpers.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Cast_Helpers.enso index 011ffbfc27b1..3b26eb2244aa 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Cast_Helpers.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Cast_Helpers.enso @@ -7,8 +7,6 @@ import project.Internal.Storage import project.Value_Type.Value_Type from project.Errors import Conversion_Failure -polyglot java import org.enso.table.data.column.storage.type.StorageType - ## PRIVATE Checks if one type can be cast into another and returns a dataflow error explaining the situation if not. diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Column_Ops.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Column_Ops.enso index 8fdb5d2ccb0d..ceda534d7c40 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Column_Ops.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Column_Ops.enso @@ -12,7 +12,7 @@ map_over_storage : Column -> (Any -> Text) -> (Integer -> Any) -> Boolean -> Pro map_over_storage input_column function builder skip_nothing=True on_problems:Problem_Behavior=..Report_Warning = problem_builder = Problem_Builder.new input_storage = input_column.java_column.getStorage - num_input_rows = input_storage.size + num_input_rows = input_storage.getSize output_storage_builder = builder num_input_rows 0.up_to num_input_rows . each i-> input_value = input_storage.getItemBoxed i @@ -33,12 +33,12 @@ map_2_over_storage : Column -> Column -> (Any -> Any -> Text) -> (Integer -> Any map_2_over_storage input_column_0 input_column_1 function builder skip_nothing=True = input_storage_0 = input_column_0.java_column.getStorage input_storage_1 = input_column_1.java_column.getStorage - case input_storage_0.size != input_storage_1.size of + case input_storage_0.getSize != input_storage_1.getSize of True -> - msg = "Column lengths differ: " + input_storage_0.size.to_text + " != " + input_storage_1.size.to_text + msg = "Column lengths differ: " + input_storage_0.getSize.to_text + " != " + input_storage_1.getSize.to_text Error.throw (Illegal_Argument.Error msg) False -> - num_input_rows = input_storage_0.size + num_input_rows = input_storage_0.getSize output_storage_builder = builder num_input_rows ok = 0.up_to num_input_rows . each_propagate i-> input_value_0 = input_storage_0.getItemBoxed i diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Fan_Out.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Fan_Out.enso index 31a08235ba55..f68a451fc483 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Fan_Out.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Fan_Out.enso @@ -140,7 +140,7 @@ fan_out_to_rows_and_columns table input_column_id function column_names at_least fan_out_to_rows_and_columns_fixed : Any -> (Any -> Vector (Vector Any)) -> Boolean -> Vector Text -> (Integer -> Any) -> Problem_Builder -> Vector fan_out_to_rows_and_columns_fixed input_storage function at_least_one_row:Boolean column_names:Vector column_builder problem_builder = num_output_columns = column_names.length - num_input_rows = input_storage.size + num_input_rows = input_storage.getSize # Accumulates the outputs of the function. output_column_builders = Vector.new num_output_columns _-> column_builder num_input_rows @@ -176,7 +176,7 @@ fan_out_to_rows_and_columns_dynamic input_storage function at_least_one_row colu output_column_builders = Builder.new # Guess that most of the time, we'll get at least one value for each input. - num_input_rows = input_storage.size + num_input_rows = input_storage.getSize # Column Builder add function add_column n current_length = diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Java_Exports.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Java_Exports.enso index 1efa888f7021..08a4a07505db 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Java_Exports.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Internal/Java_Exports.enso @@ -38,7 +38,7 @@ make_long_builder initial_size bits java_problem_aggregator=(Missing_Argument.en make_string_builder : Integer -> Value_Type -> Builder make_string_builder initial_size value_type=Value_Type.Char = storage_type = Storage.from_value_type_strict value_type - Builder.getForType storage_type initial_size Nothing + Builder.getForText storage_type initial_size ## PRIVATE make_inferred_builder : Integer -> ProblemAggregator -> Builder diff --git a/std-bits/google-api/src/main/java/org/enso/google/GoogleAnalyticsReader.java b/std-bits/google-api/src/main/java/org/enso/google/GoogleAnalyticsReader.java index 51bc6a38fb34..0c9d16a4eb21 100644 --- a/std-bits/google-api/src/main/java/org/enso/google/GoogleAnalyticsReader.java +++ b/std-bits/google-api/src/main/java/org/enso/google/GoogleAnalyticsReader.java @@ -277,7 +277,7 @@ public static Table runReport( var builders = new Builder[dimensions.size() + metrics.size()]; for (int i = 0; i < dimensions.size() + metrics.size(); i++) { - builders[i] = Builder.getForType(TextType.VARIABLE_LENGTH, rowCount, null); + builders[i] = Builder.getForText(TextType.VARIABLE_LENGTH, rowCount); } // Load the data diff --git a/std-bits/snowflake/src/main/java/org/enso/snowflake/SnowflakeIntegerColumnMaterializer.java b/std-bits/snowflake/src/main/java/org/enso/snowflake/SnowflakeIntegerColumnMaterializer.java index 5626d970919d..3979e5837543 100644 --- a/std-bits/snowflake/src/main/java/org/enso/snowflake/SnowflakeIntegerColumnMaterializer.java +++ b/std-bits/snowflake/src/main/java/org/enso/snowflake/SnowflakeIntegerColumnMaterializer.java @@ -101,7 +101,7 @@ public Storage seal() { resize(currentSize); return switch (mode) { case LONG -> new LongStorage(ints, currentSize, intsMissing, IntegerType.INT_64); - case BIG_INTEGER -> new BigIntegerStorage(bigInts, currentSize); + case BIG_INTEGER -> new BigIntegerStorage(bigInts); }; } diff --git a/std-bits/table/src/main/java/org/enso/table/aggregations/Concatenate.java b/std-bits/table/src/main/java/org/enso/table/aggregations/Concatenate.java index 4bf3e917946e..21fbcdcd8951 100644 --- a/std-bits/table/src/main/java/org/enso/table/aggregations/Concatenate.java +++ b/std-bits/table/src/main/java/org/enso/table/aggregations/Concatenate.java @@ -39,7 +39,7 @@ public Object aggregate(List indexes, ProblemAggregator problemAggregat if (value == null || value instanceof String) { String textValue = toQuotedString(value, quote, separator); - if (!separator.equals("") && quote.equals("") && textValue.contains(separator)) { + if (!separator.isEmpty() && quote.isEmpty() && textValue.contains(separator)) { innerAggregator.reportColumnAggregatedProblem( new UnquotedDelimiter(this.getName(), row, "Unquoted delimiter.")); } diff --git a/std-bits/table/src/main/java/org/enso/table/aggregations/Mean.java b/std-bits/table/src/main/java/org/enso/table/aggregations/Mean.java index 0ba19e73f052..161b4eaa8c49 100644 --- a/std-bits/table/src/main/java/org/enso/table/aggregations/Mean.java +++ b/std-bits/table/src/main/java/org/enso/table/aggregations/Mean.java @@ -4,9 +4,9 @@ import java.math.MathContext; import java.util.List; import org.enso.base.polyglot.NumericConverter; +import org.enso.table.data.column.storage.ColumnDoubleStorage; +import org.enso.table.data.column.storage.ColumnLongStorage; import org.enso.table.data.column.storage.Storage; -import org.enso.table.data.column.storage.numeric.AbstractLongStorage; -import org.enso.table.data.column.storage.numeric.DoubleStorage; import org.enso.table.data.column.storage.type.AnyObjectType; import org.enso.table.data.column.storage.type.BigDecimalType; import org.enso.table.data.column.storage.type.BigIntegerType; @@ -82,7 +82,7 @@ private final class FloatMeanAccumulator extends MeanAccumulator { void accumulate( List indexes, Storage storage, ProblemAggregator problemAggregator) { Context context = Context.getCurrent(); - if (storage instanceof DoubleStorage doubleStorage) { + if (storage instanceof ColumnDoubleStorage doubleStorage) { for (int i : indexes) { if (!doubleStorage.isNothing(i)) { total += doubleStorage.getItemAsDouble(i); @@ -90,10 +90,10 @@ void accumulate( } context.safepoint(); } - } else if (storage instanceof AbstractLongStorage longStorage) { + } else if (storage instanceof ColumnLongStorage longStorage) { for (int i : indexes) { if (!longStorage.isNothing(i)) { - total += longStorage.getItem(i); + total += longStorage.getItemAsLong(i); count++; } context.safepoint(); diff --git a/std-bits/table/src/main/java/org/enso/table/aggregations/Sum.java b/std-bits/table/src/main/java/org/enso/table/aggregations/Sum.java index 637bcefc1c02..3d92d8a93c99 100644 --- a/std-bits/table/src/main/java/org/enso/table/aggregations/Sum.java +++ b/std-bits/table/src/main/java/org/enso/table/aggregations/Sum.java @@ -6,10 +6,10 @@ import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.builder.InferredIntegerBuilder; import org.enso.table.data.column.operation.map.MapOperationProblemAggregator; +import org.enso.table.data.column.storage.ColumnDoubleStorage; +import org.enso.table.data.column.storage.ColumnLongStorage; import org.enso.table.data.column.storage.Storage; -import org.enso.table.data.column.storage.numeric.AbstractLongStorage; import org.enso.table.data.column.storage.numeric.BigIntegerStorage; -import org.enso.table.data.column.storage.numeric.DoubleStorage; import org.enso.table.data.column.storage.type.BigIntegerType; import org.enso.table.data.column.storage.type.FloatType; import org.enso.table.data.column.storage.type.IntegerType; @@ -34,8 +34,7 @@ public Sum(String name, Column column) { public Builder makeBuilder(int size, ProblemAggregator problemAggregator) { return switch (inputType) { case IntegerType integerType -> new InferredIntegerBuilder(size, problemAggregator); - case BigIntegerType bigIntegerType -> Builder.getForType( - bigIntegerType, size, problemAggregator); + case BigIntegerType bigIntegerType -> Builder.getForBigInteger(size, problemAggregator); case FloatType floatType -> Builder.getForDouble(floatType, size, problemAggregator); case NullType nullType -> Builder.getForType(nullType, size, problemAggregator); default -> throw new IllegalStateException( @@ -90,16 +89,16 @@ void add(Object value) { @Override void accumulate(List indexes, Storage storage) { Context context = Context.getCurrent(); - if (storage instanceof AbstractLongStorage longStorage) { + if (storage instanceof ColumnLongStorage longStorage) { for (int row : indexes) { if (!longStorage.isNothing(row)) { - addLong(longStorage.getItem(row)); + addLong(longStorage.getItemAsLong(row)); } context.safepoint(); } } else if (storage instanceof BigIntegerStorage bigIntegerStorage) { for (int row : indexes) { - BigInteger value = bigIntegerStorage.getItem(row); + BigInteger value = bigIntegerStorage.getItemBoxed(row); if (value != null) { addBigInteger(value); } @@ -169,10 +168,10 @@ void add(Object value) { @Override void accumulate(List indexes, Storage storage) { Context context = Context.getCurrent(); - if (storage instanceof DoubleStorage doubleStorage) { + if (storage instanceof ColumnDoubleStorage doubleStorage) { for (int row : indexes) { if (!doubleStorage.isNothing(row)) { - addDouble(doubleStorage.getItem(row)); + addDouble(doubleStorage.getItemAsDouble(row)); } context.safepoint(); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/BigDecimalBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/BigDecimalBuilder.java index 6c71d83250ce..eb40d5bda443 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/BigDecimalBuilder.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/BigDecimalBuilder.java @@ -29,6 +29,6 @@ public boolean accepts(Object o) { @Override protected Storage doSeal() { - return new BigDecimalStorage(data, currentSize); + return new BigDecimalStorage(data); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/BigIntegerBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/BigIntegerBuilder.java index b1ee3c30041e..a4f57458cab6 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/BigIntegerBuilder.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/BigIntegerBuilder.java @@ -2,8 +2,8 @@ import java.math.BigInteger; import org.enso.base.polyglot.NumericConverter; +import org.enso.table.data.column.storage.ColumnLongStorage; import org.enso.table.data.column.storage.Storage; -import org.enso.table.data.column.storage.numeric.AbstractLongStorage; import org.enso.table.data.column.storage.numeric.BigIntegerStorage; import org.enso.table.data.column.storage.type.BigDecimalType; import org.enso.table.data.column.storage.type.BigIntegerType; @@ -45,7 +45,7 @@ public Builder retypeTo(StorageType type) { return res; } case BigDecimalType _ -> { - var res = Builder.getForType(type, data.length, problemAggregator); + var res = Builder.getForBigDecimal(data.length); for (int i = 0; i < currentSize; i++) { if (data[i] == null) { res.appendNulls(1); @@ -61,7 +61,7 @@ public Builder retypeTo(StorageType type) { @Override protected Storage doSeal() { - return new BigIntegerStorage(data, currentSize); + return new BigIntegerStorage(data); } @Override @@ -98,14 +98,14 @@ static Builder retypeFromLongBuilder(LongBuilder longBuilder) { @Override public void appendBulkStorage(Storage storage) { if (storage.getType() instanceof IntegerType) { - if (storage instanceof AbstractLongStorage longStorage) { - int n = longStorage.size(); - for (int i = 0; i < n; i++) { + if (storage instanceof ColumnLongStorage longStorage) { + long n = longStorage.getSize(); + for (long i = 0; i < n; i++) { if (storage.isNothing(i)) { - data[currentSize++] = null; + appendNulls(1); } else { - long item = longStorage.getItem(i); - data[currentSize++] = BigInteger.valueOf(item); + long item = longStorage.getItemAsLong(i); + append(BigInteger.valueOf(item)); } } } else { diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/BoolBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/BoolBuilder.java index 3fb34656cf95..700fcd5b1cef 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/BoolBuilder.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/BoolBuilder.java @@ -2,6 +2,7 @@ import java.util.BitSet; import org.enso.table.data.column.storage.BoolStorage; +import org.enso.table.data.column.storage.ColumnBooleanStorage; import org.enso.table.data.column.storage.Storage; import org.enso.table.data.column.storage.type.BooleanType; import org.enso.table.data.column.storage.type.NullType; @@ -64,9 +65,19 @@ public void appendNulls(int count) { public void appendBulkStorage(Storage storage) { if (storage.getType().equals(getType())) { if (storage instanceof BoolStorage boolStorage) { - BitSets.copy(boolStorage.getValues(), vals, size, boolStorage.size()); - BitSets.copy(boolStorage.getIsNothingMap(), isNothing, size, boolStorage.size()); - size += boolStorage.size(); + // We know this is valid for a BoolStorage. + int toCopy = (int) boolStorage.getSize(); + BitSets.copy(boolStorage.getValues(), vals, size, toCopy); + BitSets.copy(boolStorage.getIsNothingMap(), isNothing, size, toCopy); + size += toCopy; + } else if (storage instanceof ColumnBooleanStorage columnBooleanStorage) { + for (long i = 0; i < columnBooleanStorage.getSize(); i++) { + if (columnBooleanStorage.isNothing(i)) { + appendNulls(1); + } else { + appendBoolean(columnBooleanStorage.getItemAsBoolean(i)); + } + } } else { throw new IllegalStateException( "Unexpected storage implementation for type BOOLEAN: " @@ -74,7 +85,7 @@ public void appendBulkStorage(Storage storage) { + ". This is a bug in the Table library."); } } else if (storage.getType() instanceof NullType) { - appendNulls(storage.size()); + appendNulls(Math.toIntExact(storage.getSize())); } else { throw new StorageTypeMismatchException(getType(), storage.getType()); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/Builder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/Builder.java index ec7197f46803..58fe71f9c37f 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/Builder.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/Builder.java @@ -32,7 +32,8 @@ public interface Builder { * */ int MAX_SIZE = Integer.MAX_VALUE; - private static int checkSize(long size) { + /** Checks that the size is within the maximum allowed. */ + static int checkSize(long size) { if (size > MAX_SIZE) { throw new IllegalArgumentException("Columns cannot exceed " + MAX_SIZE + " rows."); } @@ -56,7 +57,7 @@ static Builder getForType(StorageType type, long size, ProblemAggregator problem case TimeOfDayType _ -> getForTime(size); case FloatType floatType -> getForDouble(floatType, size, problemAggregator); case IntegerType integerType -> getForLong(integerType, size, problemAggregator); - case TextType textType -> getForText(size, textType); + case TextType textType -> getForText(textType, size); case BigDecimalType _ -> getForBigDecimal(size); case BigIntegerType _ -> getForBigInteger(size, problemAggregator); case NullType x -> new NullBuilder(); @@ -150,7 +151,7 @@ static BuilderForType getForDateTime(long size) { return new DateTimeBuilder(checkedSize, false); } - static BuilderForType getForText(long size, TextType textType) { + static BuilderForType getForText(TextType textType, long size) { int checkedSize = checkSize(size); return new StringBuilder(checkedSize, textType); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/DateBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/DateBuilder.java index 84ffbfe87a6e..aa15f93c3835 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/DateBuilder.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/DateBuilder.java @@ -35,7 +35,7 @@ public boolean accepts(Object o) { @Override protected Storage doSeal() { - return new DateStorage(data, currentSize); + return new DateStorage(data); } @Override diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/DateTimeBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/DateTimeBuilder.java index 08430706715a..d11460dbeb0e 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/DateTimeBuilder.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/DateTimeBuilder.java @@ -5,7 +5,6 @@ import java.time.ZonedDateTime; import java.util.BitSet; import org.enso.table.data.column.storage.Storage; -import org.enso.table.data.column.storage.datetime.DateStorage; import org.enso.table.data.column.storage.datetime.DateTimeStorage; import org.enso.table.data.column.storage.type.DateTimeType; import org.enso.table.data.column.storage.type.DateType; @@ -49,25 +48,17 @@ public void append(Object o) { @Override public void appendBulkStorage(Storage storage) { if (storage.getType() instanceof DateType) { - if (storage instanceof DateStorage dateStorage) { - Context context = Context.getCurrent(); - for (int i = 0; i < dateStorage.size(); ++i) { - LocalDate date = dateStorage.getItemBoxed(i); - if (date == null) { - data[currentSize++] = null; - } else { - data[currentSize++] = convertDate(date); - } - - context.safepoint(); + Context context = Context.getCurrent(); + for (long i = 0; i < storage.getSize(); ++i) { + var date = storage.getItemBoxed(i); + if (date == null) { + appendNulls(1); + } else if (date instanceof LocalDate localDate) { + append(convertDate(localDate)); + } else { + throw new IllegalStateException("Unexpected type in DateStorage: " + date.getClass()); } - } else { - throw new IllegalStateException( - "Unexpected storage implementation for type " - + storage.getType() - + ": " - + storage - + ". This is a bug in the Table library."); + context.safepoint(); } } else { super.appendBulkStorage(storage); @@ -81,7 +72,7 @@ public boolean accepts(Object o) { @Override protected Storage doSeal() { - return new DateTimeStorage(data, currentSize); + return new DateTimeStorage(data); } @Override diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/DoubleBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/DoubleBuilder.java index 817c097ba98b..db2d250d8462 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/DoubleBuilder.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/DoubleBuilder.java @@ -5,8 +5,9 @@ import java.util.Objects; import org.enso.base.polyglot.NumericConverter; import org.enso.table.data.column.storage.BoolStorage; +import org.enso.table.data.column.storage.ColumnDoubleStorage; +import org.enso.table.data.column.storage.ColumnLongStorage; import org.enso.table.data.column.storage.Storage; -import org.enso.table.data.column.storage.numeric.AbstractLongStorage; import org.enso.table.data.column.storage.numeric.BigIntegerStorage; import org.enso.table.data.column.storage.numeric.DoubleStorage; import org.enso.table.data.column.storage.type.BigIntegerType; @@ -86,11 +87,20 @@ public void append(Object o) { public void appendBulkStorage(Storage storage) { if (Objects.equals(storage.getType(), FloatType.FLOAT_64)) { if (storage instanceof DoubleStorage doubleStorage) { - int n = doubleStorage.size(); + int n = (int) doubleStorage.getSize(); ensureFreeSpaceFor(n); System.arraycopy(doubleStorage.getRawData(), 0, data, currentSize, n); BitSets.copy(doubleStorage.getIsNothingMap(), isNothing, currentSize, n); currentSize += n; + } else if (storage instanceof ColumnDoubleStorage doubleStorage) { + long n = doubleStorage.getSize(); + for (long i = 0; i < n; i++) { + if (storage.isNothing(i)) { + appendNulls(1); + } else { + appendDouble(doubleStorage.getItemAsDouble(i)); + } + } } else { throw new IllegalStateException( "Unexpected storage implementation for type DOUBLE: " @@ -98,12 +108,15 @@ public void appendBulkStorage(Storage storage) { + ". This is a bug in the Table library."); } } else if (storage.getType() instanceof IntegerType) { - if (storage instanceof AbstractLongStorage longStorage) { - int n = longStorage.size(); - BitSets.copy(longStorage.getIsNothingMap(), isNothing, currentSize, n); - for (int i = 0; i < n; i++) { - long item = longStorage.getItem(i); - data[currentSize++] = convertLongToDouble(item); + if (storage instanceof ColumnLongStorage longStorage) { + long n = longStorage.getSize(); + for (long i = 0; i < n; i++) { + if (storage.isNothing(i)) { + appendNulls(1); + } else { + long item = longStorage.getItemAsLong(i); + appendDouble(convertLongToDouble(item)); + } } } else { throw new IllegalStateException( @@ -113,13 +126,13 @@ public void appendBulkStorage(Storage storage) { } } else if (storage.getType() instanceof BigIntegerType) { if (storage instanceof BigIntegerStorage bigIntegerStorage) { - int n = bigIntegerStorage.size(); - for (int i = 0; i < n; i++) { - BigInteger item = bigIntegerStorage.getItem(i); + long n = bigIntegerStorage.getSize(); + for (long i = 0; i < n; i++) { + BigInteger item = bigIntegerStorage.getItemBoxed(i); if (item == null) { - isNothing.set(currentSize++); + appendNulls(1); } else { - data[currentSize++] = convertBigIntegerToDouble(item); + appendDouble(convertBigIntegerToDouble(item)); } } } else { @@ -130,12 +143,12 @@ public void appendBulkStorage(Storage storage) { } } else if (storage.getType() instanceof BooleanType) { if (storage instanceof BoolStorage boolStorage) { - int n = boolStorage.size(); - for (int i = 0; i < n; i++) { + long n = boolStorage.getSize(); + for (long i = 0; i < n; i++) { if (boolStorage.isNothing(i)) { - isNothing.set(currentSize++); + appendNulls(1); } else { - data[currentSize++] = boolStorage.getItem(i) ? 1.0 : 0.0; + appendDouble(boolStorage.getItemAsBoolean(i) ? 1.0 : 0.0); } } } else { @@ -145,7 +158,7 @@ public void appendBulkStorage(Storage storage) { + ". This is a bug in the Table library."); } } else if (storage.getType() instanceof NullType) { - appendNulls(storage.size()); + appendNulls(Math.toIntExact(storage.getSize())); } else { throw new StorageTypeMismatchException(getType(), storage.getType()); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/InferredBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/InferredBuilder.java index 77f33241704b..85d82f7333d1 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/InferredBuilder.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/InferredBuilder.java @@ -85,9 +85,9 @@ public void appendNulls(int count) { @Override public void appendBulkStorage(Storage storage) { if (storage.getType() instanceof NullType) { - appendNulls(storage.size()); + appendNulls(Math.toIntExact(storage.getSize())); } else { - for (int i = 0; i < storage.size(); i++) { + for (long i = 0; i < storage.getSize(); i++) { append(storage.getItemBoxed(i)); } } @@ -104,23 +104,23 @@ private void initBuilderFor(Object o) { } else if (NumericConverter.isFloatLike(o)) { newBuilder = new InferredDoubleBuilder(initialCapacity, problemAggregator); } else if (o instanceof String) { - newBuilder = Builder.getForType(TextType.VARIABLE_LENGTH, initialCapacity, problemAggregator); + newBuilder = Builder.getForText(TextType.VARIABLE_LENGTH, initialCapacity); } else if (o instanceof BigInteger) { - newBuilder = Builder.getForType(BigIntegerType.INSTANCE, initialCapacity, problemAggregator); + newBuilder = Builder.getForBigInteger(initialCapacity, problemAggregator); } else if (o instanceof BigDecimal) { - newBuilder = Builder.getForType(BigDecimalType.INSTANCE, initialCapacity, problemAggregator); + newBuilder = Builder.getForBigDecimal(initialCapacity); } else if (o instanceof LocalDate) { newBuilder = allowDateToDateTimeConversion ? new DateBuilder(initialCapacity, true) - : Builder.getForType(DateType.INSTANCE, initialCapacity, problemAggregator); + : Builder.getForDate(initialCapacity); } else if (o instanceof ZonedDateTime) { newBuilder = allowDateToDateTimeConversion ? new DateTimeBuilder(initialCapacity, true) - : Builder.getForType(DateTimeType.INSTANCE, initialCapacity, problemAggregator); + : Builder.getForDateTime(initialCapacity); } else if (o instanceof LocalTime) { - newBuilder = Builder.getForType(TimeOfDayType.INSTANCE, initialCapacity, problemAggregator); + newBuilder = Builder.getForTime(initialCapacity); } else { newBuilder = Builder.getForType(AnyObjectType.INSTANCE, initialCapacity, problemAggregator); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/InferredDoubleBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/InferredDoubleBuilder.java index 2370fffa782a..776c60e7d8bd 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/InferredDoubleBuilder.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/InferredDoubleBuilder.java @@ -145,7 +145,7 @@ public boolean canRetypeTo(StorageType type) { @Override public Builder retypeTo(StorageType type) { if (type instanceof BigDecimalType) { - Builder res = Builder.getForType(BigDecimalType.INSTANCE, data.length, null); + Builder res = Builder.getForBigDecimal(data.length); for (int i = 0; i < currentSize; i++) { if (isNothing.get(i)) { res.appendNulls(1); diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/InferredIntegerBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/InferredIntegerBuilder.java index cc07dbb47ab6..68fb2715bb62 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/InferredIntegerBuilder.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/InferredIntegerBuilder.java @@ -67,9 +67,9 @@ public void appendNulls(int count) { @Override public void appendBulkStorage(Storage storage) { if (storage.getType() instanceof NullType) { - appendNulls(storage.size()); + appendNulls(Math.toIntExact(storage.getSize())); } else { - for (int i = 0; i < storage.size(); i++) { + for (long i = 0; i < storage.getSize(); i++) { append(storage.getItemBoxed(i)); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/LongBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/LongBuilder.java index 9fd46fe44a8f..72dbddbd1f8f 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/LongBuilder.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/LongBuilder.java @@ -2,9 +2,9 @@ import java.util.Objects; import org.enso.base.polyglot.NumericConverter; -import org.enso.table.data.column.storage.BoolStorage; +import org.enso.table.data.column.storage.ColumnBooleanStorage; +import org.enso.table.data.column.storage.ColumnLongStorage; import org.enso.table.data.column.storage.Storage; -import org.enso.table.data.column.storage.numeric.AbstractLongStorage; import org.enso.table.data.column.storage.numeric.LongStorage; import org.enso.table.data.column.storage.type.BigIntegerType; import org.enso.table.data.column.storage.type.BooleanType; @@ -90,20 +90,19 @@ public void appendBulkStorage(Storage storage) { if (Objects.equals(storage.getType(), getType()) && storage instanceof LongStorage longStorage) { // A fast path for the same type - no conversions/checks needed. - int n = longStorage.size(); + int n = (int) longStorage.getSize(); ensureFreeSpaceFor(n); System.arraycopy(longStorage.getRawData(), 0, data, currentSize, n); BitSets.copy(longStorage.getIsNothingMap(), isNothing, currentSize, n); currentSize += n; } else if (storage.getType() instanceof IntegerType otherType && getType().fits(otherType)) { - if (storage instanceof AbstractLongStorage longStorage) { - int n = longStorage.size(); - ensureFreeSpaceFor(n); - for (int i = 0; i < n; i++) { + if (storage instanceof ColumnLongStorage longStorage) { + long n = longStorage.getSize(); + for (long i = 0; i < n; i++) { if (longStorage.isNothing(i)) { - isNothing.set(currentSize++); + appendNulls(1); } else { - appendLong(longStorage.getItem(i)); + appendLong(longStorage.getItemAsLong(i)); } } } else { @@ -113,13 +112,13 @@ public void appendBulkStorage(Storage storage) { + ". This is a bug in the Table library."); } } else if (Objects.equals(storage.getType(), BooleanType.INSTANCE)) { - if (storage instanceof BoolStorage boolStorage) { - int n = boolStorage.size(); - for (int i = 0; i < n; i++) { + if (storage instanceof ColumnBooleanStorage boolStorage) { + long n = boolStorage.getSize(); + for (long i = 0; i < n; i++) { if (boolStorage.isNothing(i)) { - isNothing.set(currentSize++); + appendNulls(1); } else { - data[currentSize++] = boolStorage.getItem(i) ? 1L : 0L; + appendLong(boolStorage.getItemAsBoolean(i) ? 1L : 0L); } } } else { @@ -129,7 +128,7 @@ public void appendBulkStorage(Storage storage) { + ". This is a bug in the Table library."); } } else if (storage.getType() instanceof NullType) { - appendNulls(storage.size()); + appendNulls(Math.toIntExact(storage.getSize())); } else { throw new StorageTypeMismatchException(getType(), storage.getType()); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/MixedBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/MixedBuilder.java index 729b6a5a0a6d..ff58cf2e4a16 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/MixedBuilder.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/MixedBuilder.java @@ -25,7 +25,7 @@ static MixedBuilder fromBuilder(Builder source, int capacity) { @Override public Storage doSeal() { - return new MixedStorage(data, currentSize); + return new MixedStorage(data); } @Override diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/NullBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/NullBuilder.java index 409e435c6d0e..44cbea96ac67 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/NullBuilder.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/NullBuilder.java @@ -28,7 +28,7 @@ public void appendNulls(int count) { public void appendBulkStorage(Storage storage) { // For any storage that is not all-null, check if non-null values are present if (!(storage.getType() instanceof NullType)) { - for (int i = 0; i < storage.size(); i++) { + for (long i = 0; i < storage.getSize(); i++) { if (!storage.isNothing(i)) { throw new IllegalArgumentException( "NullBuilder can only append nulls, but got " + storage.getItemBoxed(i)); @@ -36,7 +36,7 @@ public void appendBulkStorage(Storage storage) { } } - length += storage.size(); + length += Math.toIntExact(storage.getSize()); } @Override diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/ObjectBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/ObjectBuilder.java index 785cd6cd660a..b1b2e245d606 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/ObjectBuilder.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/ObjectBuilder.java @@ -25,25 +25,29 @@ public void append(Object o) { @Override public void appendBulkStorage(Storage storage) { - if (currentSize + storage.size() > data.length) { - resize(currentSize + storage.size()); + long newSize = currentSize + storage.getSize(); + if (newSize > data.length) { + int newSizeInt = Builder.checkSize(newSize); + resize(newSizeInt); } if (storage instanceof SpecializedStorage specializedStorage) { - System.arraycopy(specializedStorage.getData(), 0, data, currentSize, storage.size()); - currentSize += storage.size(); + // We can safely cast here, as for SpecializedStorage the size is always an int. + int toCopy = (int) storage.getSize(); + System.arraycopy(specializedStorage.getData(), 0, data, currentSize, toCopy); + currentSize += toCopy; } else if (storage.getType() instanceof NullType) { - appendNulls(storage.size()); + appendNulls(Math.toIntExact(storage.getSize())); } else { - int n = storage.size(); - for (int i = 0; i < n; i++) { - data[currentSize++] = storage.getItemBoxed(i); + long n = storage.getSize(); + for (long i = 0; i < n; i++) { + append(storage.getItemBoxed(i)); } } } @Override public Storage doSeal() { - return new ObjectStorage(data, currentSize); + return new ObjectStorage(data); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/StringBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/StringBuilder.java index e6ea79e4d4bc..f2c8febb5931 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/StringBuilder.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/StringBuilder.java @@ -48,8 +48,9 @@ public void appendBulkStorage(Storage storage) { // storage.T == String @SuppressWarnings("unchecked") SpecializedStorage specializedStorage = (SpecializedStorage) storage; - System.arraycopy(specializedStorage.getData(), 0, data, currentSize, storage.size()); - currentSize += storage.size(); + int toCopy = (int) storage.getSize(); + System.arraycopy(specializedStorage.getData(), 0, data, currentSize, toCopy); + currentSize += toCopy; return; } } @@ -60,6 +61,6 @@ public void appendBulkStorage(Storage storage) { @Override protected Storage doSeal() { - return new StringStorage(data, currentSize, type); + return new StringStorage(data, type); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/TimeOfDayBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/TimeOfDayBuilder.java index 33050a614b97..2c3d66b1f89f 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/TimeOfDayBuilder.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/TimeOfDayBuilder.java @@ -29,6 +29,6 @@ public boolean accepts(Object o) { @Override protected Storage doSeal() { - return new TimeOfDayStorage(data, currentSize); + return new TimeOfDayStorage(data); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/TypedBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/TypedBuilder.java index 757b056bd17d..ed7c88d012eb 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/TypedBuilder.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/TypedBuilder.java @@ -50,8 +50,12 @@ public void appendBulkStorage(Storage storage) { // This cast is safe, because storage.getType() == this.getType() iff storage.T == this.T @SuppressWarnings("unchecked") SpecializedStorage specializedStorage = (SpecializedStorage) storage; - System.arraycopy(specializedStorage.getData(), 0, data, currentSize, storage.size()); - currentSize += storage.size(); + int toCopy = (int) storage.getSize(); + if (currentSize + toCopy > data.length) { + resize(currentSize + toCopy); + } + System.arraycopy(specializedStorage.getData(), 0, data, currentSize, toCopy); + currentSize += toCopy; } else { throw new IllegalStateException( "Unexpected storage implementation for type " @@ -61,7 +65,7 @@ public void appendBulkStorage(Storage storage) { + ". This is a bug in the Table library."); } } else if (storage.getType() instanceof NullType) { - appendNulls(storage.size()); + appendNulls(Math.toIntExact(storage.getSize())); } else { throw new StorageTypeMismatchException(getType(), storage.getType()); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/CountNothing.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/CountNothing.java index f1f4e064d5b7..e34f22da1984 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/CountNothing.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/CountNothing.java @@ -9,12 +9,12 @@ public class CountNothing { /** Counts the number of Nothing values in the given column. */ public static long apply(Column column) { - ColumnStorage storage = column.getStorage(); + var storage = column.getStorage(); return applyToStorage(storage); } /** Counts the number of Nothing values in the given storage. */ - public static long applyToStorage(ColumnStorage storage) { + public static long applyToStorage(ColumnStorage storage) { if (storage instanceof ColumnStorageWithNothingMap withNothingMap) { return withNothingMap.getIsNothingMap().cardinality(); } @@ -31,7 +31,7 @@ public static long applyToStorage(ColumnStorage storage) { } /** Returns true if any value in the storage is Nothing. */ - public static boolean anyNothing(ColumnStorage storage) { + public static boolean anyNothing(ColumnStorage storage) { if (storage instanceof ColumnStorageWithNothingMap withNothingMap) { return !withNothingMap.getIsNothingMap().isEmpty(); } @@ -47,7 +47,7 @@ public static boolean anyNothing(ColumnStorage storage) { } /** Returns true if all values in the storage are Nothing. */ - public static boolean allNothing(ColumnStorage storage) { + public static boolean allNothing(ColumnStorage storage) { if (storage instanceof ColumnStorageWithNothingMap withNothingMap) { return withNothingMap.getIsNothingMap().nextClearBit(0) >= storage.getSize(); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/CountUntrimmed.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/CountUntrimmed.java index 9e0f5923a015..341f8e94ffb2 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/CountUntrimmed.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/CountUntrimmed.java @@ -17,12 +17,12 @@ public class CountUntrimmed { /** Counts the number of cells in the columns with leading or trailing whitespace. */ public static Long apply(Column column, long sampleSize) throws InterruptedException { - ColumnStorage storage = column.getStorage(); + var storage = column.getStorage(); return applyToStorage(storage, sampleSize); } /** Counts the number of cells in the given storage with leading or trailing whitespace. */ - public static Long applyToStorage(ColumnStorage storage, long sampleSize) + public static Long applyToStorage(ColumnStorage storage, long sampleSize) throws InterruptedException { return (sampleSize == DEFAULT_SAMPLE_SIZE && storage instanceof StringStorage stringStorage) ? stringStorage.cachedUntrimmedCount() @@ -30,15 +30,15 @@ public static Long applyToStorage(ColumnStorage storage, long sampleSize) } /** Internal method performing the calculation on a storage. */ - public static long compute(ColumnStorage storage, long sampleSize, Context context) { + public static long compute(ColumnStorage storage, long sampleSize, Context context) { long size = storage.getSize(); long count = 0; if (sampleSize < size) { var rng = new Random(RANDOM_SEED); for (int i = 0; i < sampleSize; i++) { - long idx = rng.nextInt(Math.toIntExact(size)); - var val = storage.getItemAsObject(idx); + long idx = rng.nextLong(size); + var val = storage.getItemBoxed(idx); if (val instanceof String str && Text_Utils.has_leading_trailing_whitespace(str)) { count++; } @@ -50,7 +50,7 @@ public static long compute(ColumnStorage storage, long sampleSize, Context conte count = Math.min(size, (long) Math.ceil((double) count / sampleSize * size)); } else { for (long i = 0; i < storage.getSize(); i++) { - var val = storage.getItemAsObject(i); + var val = storage.getItemBoxed(i); if (val instanceof String str && Text_Utils.has_leading_trailing_whitespace(str)) { count++; } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/UnaryOperation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/UnaryOperation.java index 67d1949f19f4..5c8900c75f9d 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/UnaryOperation.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/UnaryOperation.java @@ -32,7 +32,7 @@ static Column apply( UnaryOperation operation, String newColumnName, MapOperationProblemAggregator problemAggregator) { - ColumnStorage storage = column.getStorage(); + ColumnStorage storage = column.getStorage(); // If the storage has an inferred storage (e.g. a Mixed column) and the first level can't do get // an inferred storage. @@ -76,7 +76,7 @@ static Column mapFunction( nothingUnchanged, storageBuilder, i -> { - Value result = function.apply(column.getStorage().getItemAsObject(i)); + Value result = function.apply(column.getStorage().getItemBoxed(i)); Object converted = Polyglot_Utils.convertPolyglotValue(result); storageBuilder.append(converted); }); @@ -87,13 +87,13 @@ static Column mapFunction( String getName(); /** Can the operation be applied to the given Storage? */ - boolean canApply(ColumnStorage storage); + boolean canApply(ColumnStorage storage); /** Applies the operation to the given Storage. */ - ColumnStorage apply(ColumnStorage storage, MapOperationProblemAggregator problemAggregator); + ColumnStorage apply(ColumnStorage storage, MapOperationProblemAggregator problemAggregator); private static void applyStorageInner( - ColumnStorage columnStorage, + ColumnStorage columnStorage, boolean nothingUnchanged, Builder builder, LongConsumer callback) { @@ -111,7 +111,7 @@ private static void applyStorageInner( /** Applies the operation to the given Storage. */ static void applyOverObjectStorage( - ColumnStorage objectStorage, + ColumnStorage objectStorage, boolean nothingUnchanged, Builder builder, Consumer function) { @@ -119,7 +119,7 @@ static void applyOverObjectStorage( objectStorage, nothingUnchanged, builder, - i -> function.accept(objectStorage.getItemAsObject(i))); + i -> function.accept(objectStorage.getItemBoxed(i))); } /** Applies the operation to the given Boolean Storage. */ @@ -132,7 +132,7 @@ static void applyOverBooleanStorage( booleanStorage, nothingUnchanged, builder, - i -> function.accept(booleanStorage.isNothing(i), booleanStorage.get(i))); + i -> function.accept(booleanStorage.isNothing(i), booleanStorage.getItemAsBoolean(i))); } @FunctionalInterface @@ -150,7 +150,7 @@ static void applyOverLongStorage( longStorage, nothingUnchanged, builder, - i -> function.accept(longStorage.isNothing(i), longStorage.get(i))); + i -> function.accept(longStorage.isNothing(i), longStorage.getItemAsLong(i))); } @FunctionalInterface @@ -168,7 +168,7 @@ static void applyOverDoubleStorage( doubleStorage, nothingUnchanged, builder, - i -> function.accept(doubleStorage.isNothing(i), doubleStorage.get(i))); + i -> function.accept(doubleStorage.isNothing(i), doubleStorage.getItemAsDouble(i))); } @FunctionalInterface diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/StorageConverter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/StorageConverter.java index c347d5ffe65e..bec7a1ad1de0 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/StorageConverter.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/StorageConverter.java @@ -41,7 +41,7 @@ static StorageConverter fromStorageType(StorageType storageType) { } static Storage innerLoop( - BuilderForType builder, ColumnStorage storage, LongFunction converter) { + BuilderForType builder, ColumnStorage storage, LongFunction converter) { Context context = Context.getCurrent(); long n = storage.getSize(); diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToBigDecimalConverter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToBigDecimalConverter.java index 535a871743de..3d566c932f4a 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToBigDecimalConverter.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToBigDecimalConverter.java @@ -3,15 +3,13 @@ import java.math.BigDecimal; import java.math.BigInteger; import org.enso.table.data.column.builder.Builder; -import org.enso.table.data.column.storage.BoolStorage; +import org.enso.table.data.column.storage.ColumnBooleanStorage; import org.enso.table.data.column.storage.ColumnDoubleStorage; import org.enso.table.data.column.storage.ColumnLongStorage; import org.enso.table.data.column.storage.ColumnStorage; import org.enso.table.data.column.storage.Storage; -import org.enso.table.data.column.storage.numeric.AbstractLongStorage; import org.enso.table.data.column.storage.numeric.BigDecimalStorage; import org.enso.table.data.column.storage.numeric.BigIntegerStorage; -import org.enso.table.data.column.storage.numeric.DoubleStorage; import org.enso.table.data.column.storage.type.AnyObjectType; import org.enso.table.data.column.storage.type.NullType; @@ -20,13 +18,13 @@ public class ToBigDecimalConverter implements StorageConverter { public Storage cast(Storage storage, CastProblemAggregator problemAggregator) { if (storage instanceof BigDecimalStorage bigDecimalStorage) { return bigDecimalStorage; - } else if (storage instanceof AbstractLongStorage longStorage) { + } else if (storage instanceof ColumnLongStorage longStorage) { return convertLongStorage(longStorage, problemAggregator); - } else if (storage instanceof DoubleStorage doubleStorage) { + } else if (storage instanceof ColumnDoubleStorage doubleStorage) { return convertDoubleStorage(doubleStorage, problemAggregator); } else if (storage instanceof BigIntegerStorage bigIntegerStorage) { return convertBigIntegerStorage(bigIntegerStorage, problemAggregator); - } else if (storage instanceof BoolStorage boolStorage) { + } else if (storage instanceof ColumnBooleanStorage boolStorage) { return convertBoolStorage(boolStorage, problemAggregator); } else if (storage.getType() instanceof AnyObjectType || storage.getType() instanceof NullType) { @@ -43,7 +41,7 @@ private Storage convertDoubleStorage( Builder.getForBigDecimal(doubleStorage.getSize()), doubleStorage, (i) -> { - double x = doubleStorage.get(i); + double x = doubleStorage.getItemAsDouble(i); return BigDecimal.valueOf(x); }); } @@ -54,40 +52,40 @@ private Storage convertLongStorage( Builder.getForBigDecimal(longStorage.getSize()), longStorage, (i) -> { - long x = longStorage.get(i); + long x = longStorage.getItemAsLong(i); return BigDecimal.valueOf(x); }); } private Storage convertBoolStorage( - BoolStorage boolStorage, CastProblemAggregator problemAggregator) { + ColumnBooleanStorage boolStorage, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( - Builder.getForBigDecimal(boolStorage.size()), + Builder.getForBigDecimal(boolStorage.getSize()), boolStorage, (i) -> { - boolean x = boolStorage.getItem(i); + boolean x = boolStorage.getItemAsBoolean(i); return booleanAsBigDecimal(x); }); } private Storage convertBigIntegerStorage( - BigIntegerStorage bigIntegerStorage, CastProblemAggregator problemAggregator) { + Storage bigIntegerStorage, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( - Builder.getForBigDecimal(bigIntegerStorage.size()), + Builder.getForBigDecimal(bigIntegerStorage.getSize()), bigIntegerStorage, (i) -> { - BigInteger x = bigIntegerStorage.getItem(i); + BigInteger x = bigIntegerStorage.getItemBoxed(i); return new BigDecimal(x); }); } private Storage castFromMixed( - ColumnStorage storage, CastProblemAggregator problemAggregator) { + ColumnStorage storage, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( Builder.getForBigDecimal(storage.getSize()), storage, (i) -> { - Object o = storage.getItemAsObject(i); + Object o = storage.getItemBoxed(i); return switch (o) { case Boolean b -> booleanAsBigDecimal(b); case Long l -> BigDecimal.valueOf(l); diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToBigIntegerConverter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToBigIntegerConverter.java index 995c3b6c1941..18367eb081f3 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToBigIntegerConverter.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToBigIntegerConverter.java @@ -3,15 +3,13 @@ import java.math.BigDecimal; import java.math.BigInteger; import org.enso.table.data.column.builder.Builder; -import org.enso.table.data.column.storage.BoolStorage; +import org.enso.table.data.column.storage.ColumnBooleanStorage; import org.enso.table.data.column.storage.ColumnDoubleStorage; import org.enso.table.data.column.storage.ColumnLongStorage; import org.enso.table.data.column.storage.ColumnStorage; import org.enso.table.data.column.storage.Storage; -import org.enso.table.data.column.storage.numeric.AbstractLongStorage; import org.enso.table.data.column.storage.numeric.BigDecimalStorage; import org.enso.table.data.column.storage.numeric.BigIntegerStorage; -import org.enso.table.data.column.storage.numeric.DoubleStorage; import org.enso.table.data.column.storage.type.AnyObjectType; import org.enso.table.data.column.storage.type.NullType; @@ -20,11 +18,11 @@ public class ToBigIntegerConverter implements StorageConverter { public Storage cast(Storage storage, CastProblemAggregator problemAggregator) { if (storage instanceof BigIntegerStorage bigIntegerStorage) { return bigIntegerStorage; - } else if (storage instanceof AbstractLongStorage longStorage) { + } else if (storage instanceof ColumnLongStorage longStorage) { return convertLongStorage(longStorage, problemAggregator); - } else if (storage instanceof DoubleStorage doubleStorage) { + } else if (storage instanceof ColumnDoubleStorage doubleStorage) { return convertDoubleStorage(doubleStorage, problemAggregator); - } else if (storage instanceof BoolStorage boolStorage) { + } else if (storage instanceof ColumnBooleanStorage boolStorage) { return convertBoolStorage(boolStorage, problemAggregator); } else if (storage instanceof BigDecimalStorage bigDecimalStorage) { return convertBigDecimalStorage(bigDecimalStorage, problemAggregator); @@ -43,7 +41,7 @@ private Storage convertDoubleStorage( Builder.getForBigInteger(doubleStorage.getSize(), problemAggregator), doubleStorage, (i) -> { - double x = doubleStorage.get(i); + double x = doubleStorage.getItemAsDouble(i); return BigDecimal.valueOf(x).toBigInteger(); }); } @@ -54,40 +52,40 @@ private Storage convertLongStorage( Builder.getForBigInteger(longStorage.getSize(), problemAggregator), longStorage, (i) -> { - long x = longStorage.get(i); + long x = longStorage.getItemAsLong(i); return BigInteger.valueOf(x); }); } private Storage convertBoolStorage( - BoolStorage boolStorage, CastProblemAggregator problemAggregator) { + ColumnBooleanStorage boolStorage, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( - Builder.getForBigInteger(boolStorage.size(), problemAggregator), + Builder.getForBigInteger(boolStorage.getSize(), problemAggregator), boolStorage, (i) -> { - boolean x = boolStorage.getItem((int) i); + boolean x = boolStorage.getItemAsBoolean((int) i); return booleanAsBigInteger(x); }); } private Storage convertBigDecimalStorage( - BigDecimalStorage bigDecimalStorage, CastProblemAggregator problemAggregator) { + Storage bigDecimalStorage, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( - Builder.getForBigInteger(bigDecimalStorage.size(), problemAggregator), + Builder.getForBigInteger(bigDecimalStorage.getSize(), problemAggregator), bigDecimalStorage, (i) -> { - BigDecimal x = bigDecimalStorage.getItemBoxed((int) i); + BigDecimal x = bigDecimalStorage.getItemBoxed(i); return x.toBigInteger(); }); } private Storage castFromMixed( - ColumnStorage storage, CastProblemAggregator problemAggregator) { + ColumnStorage storage, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( Builder.getForBigInteger(storage.getSize(), problemAggregator), storage, (i) -> { - Object o = storage.getItemAsObject(i); + Object o = storage.getItemBoxed(i); return switch (o) { case Boolean b -> booleanAsBigInteger(b); case Long l -> BigInteger.valueOf(l); diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToBooleanStorageConverter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToBooleanStorageConverter.java index 5d97599122c7..f4ccaaad5edc 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToBooleanStorageConverter.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToBooleanStorageConverter.java @@ -22,13 +22,13 @@ public Storage cast(Storage storage, CastProblemAggregator problemAg } private Storage castFromMixed( - ColumnStorage mixedStorage, CastProblemAggregator problemAggregator) { + ColumnStorage mixedStorage, CastProblemAggregator problemAggregator) { // As mixed storage is already boxed, use the standard inner loop. return StorageConverter.innerLoop( Builder.getForBoolean(mixedStorage.getSize()), mixedStorage, (i) -> { - Object o = mixedStorage.getItemAsObject(i); + Object o = mixedStorage.getItemBoxed(i); if (o instanceof Boolean b) { return b; } else { diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToDateStorageConverter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToDateStorageConverter.java index bfb0842794bb..ac8c45c6bd7b 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToDateStorageConverter.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToDateStorageConverter.java @@ -27,12 +27,12 @@ public Storage cast(Storage storage, CastProblemAggregator problem } private Storage castFromMixed( - ColumnStorage mixedStorage, CastProblemAggregator problemAggregator) { + ColumnStorage mixedStorage, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( Builder.getForDate(mixedStorage.getSize()), mixedStorage, (i) -> { - Object o = mixedStorage.getItemAsObject(i); + Object o = mixedStorage.getItemBoxed(i); return switch (o) { case LocalDate d -> d; case ZonedDateTime d -> d.toLocalDate(); @@ -45,12 +45,12 @@ private Storage castFromMixed( } private Storage convertDateTimeStorage( - DateTimeStorage dateTimeStorage, CastProblemAggregator problemAggregator) { + Storage dateTimeStorage, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( - Builder.getForDate(dateTimeStorage.size()), + Builder.getForDate(dateTimeStorage.getSize()), dateTimeStorage, (i) -> { - ZonedDateTime dateTime = dateTimeStorage.getItem(i); + ZonedDateTime dateTime = dateTimeStorage.getItemBoxed(i); return dateTime.toLocalDate(); }); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToDateTimeStorageConverter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToDateTimeStorageConverter.java index 8ef12a4ef18f..41c22c2f6d59 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToDateTimeStorageConverter.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToDateTimeStorageConverter.java @@ -28,12 +28,12 @@ public Storage cast(Storage storage, CastProblemAggregator pro } public Storage castFromMixed( - ColumnStorage mixedStorage, CastProblemAggregator problemAggregator) { + ColumnStorage mixedStorage, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( Builder.getForDateTime(mixedStorage.getSize()), mixedStorage, (i) -> { - Object o = mixedStorage.getItemAsObject(i); + Object o = mixedStorage.getItemBoxed(i); return switch (o) { case ZonedDateTime d -> d; case LocalDate d -> convertDate(d); @@ -46,12 +46,12 @@ public Storage castFromMixed( } private Storage convertDateStorage( - DateStorage dateStorage, CastProblemAggregator problemAggregator) { + Storage dateStorage, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( - Builder.getForDateTime(dateStorage.size()), + Builder.getForDateTime(dateStorage.getSize()), dateStorage, (i) -> { - LocalDate date = dateStorage.getItem(i); + LocalDate date = dateStorage.getItemBoxed(i); return convertDate(date); }); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToFloatStorageConverter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToFloatStorageConverter.java index 35dc351a1f80..fcafcefb71b6 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToFloatStorageConverter.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToFloatStorageConverter.java @@ -6,12 +6,10 @@ import org.enso.base.polyglot.NumericConverter; import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.builder.BuilderForDouble; -import org.enso.table.data.column.storage.BoolStorage; import org.enso.table.data.column.storage.ColumnBooleanStorage; import org.enso.table.data.column.storage.ColumnLongStorage; import org.enso.table.data.column.storage.ColumnStorage; import org.enso.table.data.column.storage.Storage; -import org.enso.table.data.column.storage.numeric.AbstractLongStorage; import org.enso.table.data.column.storage.numeric.BigDecimalStorage; import org.enso.table.data.column.storage.numeric.BigIntegerStorage; import org.enso.table.data.column.storage.numeric.DoubleStorage; @@ -33,9 +31,9 @@ public ToFloatStorageConverter(FloatType targetType) { public Storage cast(Storage storage, CastProblemAggregator problemAggregator) { if (storage instanceof DoubleStorage doubleStorage) { return doubleStorage; - } else if (storage instanceof AbstractLongStorage longStorage) { + } else if (storage instanceof ColumnLongStorage longStorage) { return convertLongStorage(longStorage, problemAggregator); - } else if (storage instanceof BoolStorage boolStorage) { + } else if (storage instanceof ColumnBooleanStorage boolStorage) { return convertBoolStorage(boolStorage, problemAggregator); } else if (storage instanceof BigIntegerStorage bigIntegerStorage) { return convertBigIntegerStorage(bigIntegerStorage, problemAggregator); @@ -53,7 +51,7 @@ public Storage cast(Storage storage, CastProblemAggregator problemAgg /** Specialised innerLoop so that we can avoid boxing. */ static Storage innerLoop( BuilderForDouble builder, - ColumnStorage storage, + ColumnStorage storage, ObjLongConsumer converter) { Context context = Context.getCurrent(); @@ -72,12 +70,12 @@ static Storage innerLoop( } private Storage castFromMixed( - ColumnStorage mixedStorage, CastProblemAggregator problemAggregator) { + ColumnStorage mixedStorage, CastProblemAggregator problemAggregator) { return innerLoop( Builder.getForDouble(FloatType.FLOAT_64, mixedStorage.getSize(), problemAggregator), mixedStorage, (builder, i) -> { - Object o = mixedStorage.getItemAsObject(i); + Object o = mixedStorage.getItemBoxed(i); if (NumericConverter.isCoercibleToLong(o)) { builder.appendLong(NumericConverter.coerceToLong(o)); @@ -103,7 +101,7 @@ private Storage convertLongStorage( Builder.getForDouble(FloatType.FLOAT_64, longStorage.getSize(), problemAggregator), longStorage, (builder, i) -> { - long value = longStorage.get(i); + long value = longStorage.getItemAsLong(i); builder.appendLong(value); }); } @@ -114,7 +112,7 @@ private Storage convertBoolStorage( Builder.getForDouble(FloatType.FLOAT_64, boolStorage.getSize(), problemAggregator), boolStorage, (builder, i) -> { - boolean value = boolStorage.get(i); + boolean value = boolStorage.getItemAsBoolean(i); builder.appendDouble(booleanAsDouble(value)); }); } @@ -126,16 +124,16 @@ private static double booleanAsDouble(boolean value) { private Storage convertBigIntegerStorage( Storage storage, CastProblemAggregator problemAggregator) { return innerLoop( - Builder.getForDouble(FloatType.FLOAT_64, storage.size(), problemAggregator), + Builder.getForDouble(FloatType.FLOAT_64, storage.getSize(), problemAggregator), storage, - (builder, i) -> builder.append(storage.getItemBoxed((int) i))); + (builder, i) -> builder.append(storage.getItemBoxed(i))); } private Storage convertBigDecimalStorage( Storage storage, CastProblemAggregator problemAggregator) { return innerLoop( - Builder.getForDouble(FloatType.FLOAT_64, storage.size(), problemAggregator), + Builder.getForDouble(FloatType.FLOAT_64, storage.getSize(), problemAggregator), storage, - (builder, i) -> builder.append(storage.getItemBoxed((int) i))); + (builder, i) -> builder.append(storage.getItemBoxed(i))); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToIntegerStorageConverter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToIntegerStorageConverter.java index c5e52b4aff3c..c87a756abf89 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToIntegerStorageConverter.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToIntegerStorageConverter.java @@ -6,7 +6,6 @@ import org.enso.base.polyglot.NumericConverter; import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.builder.BuilderForLong; -import org.enso.table.data.column.storage.BoolStorage; import org.enso.table.data.column.storage.ColumnBooleanStorage; import org.enso.table.data.column.storage.ColumnDoubleStorage; import org.enso.table.data.column.storage.ColumnStorage; @@ -14,7 +13,6 @@ import org.enso.table.data.column.storage.numeric.AbstractLongStorage; import org.enso.table.data.column.storage.numeric.BigDecimalStorage; import org.enso.table.data.column.storage.numeric.BigIntegerStorage; -import org.enso.table.data.column.storage.numeric.DoubleStorage; import org.enso.table.data.column.storage.type.AnyObjectType; import org.enso.table.data.column.storage.type.IntegerType; import org.enso.table.data.column.storage.type.NullType; @@ -35,9 +33,9 @@ public Storage cast(Storage storage, CastProblemAggregator problemAggre } else { return convertLongStorage(longStorage, problemAggregator); } - } else if (storage instanceof DoubleStorage doubleStorage) { + } else if (storage instanceof ColumnDoubleStorage doubleStorage) { return convertDoubleStorage(doubleStorage, problemAggregator); - } else if (storage instanceof BoolStorage boolStorage) { + } else if (storage instanceof ColumnBooleanStorage boolStorage) { return convertBoolStorage(boolStorage, problemAggregator); } else if (storage instanceof BigIntegerStorage bigIntegerStorage) { return convertBigIntegerStorage(bigIntegerStorage, problemAggregator); @@ -54,7 +52,7 @@ public Storage cast(Storage storage, CastProblemAggregator problemAggre /** Specialised innerLoop so that we can avoid boxing. */ static Storage innerLoop( - BuilderForLong builder, ColumnStorage storage, ObjLongConsumer converter) { + BuilderForLong builder, ColumnStorage storage, ObjLongConsumer converter) { Context context = Context.getCurrent(); long n = storage.getSize(); @@ -72,12 +70,12 @@ static Storage innerLoop( } private Storage castFromMixed( - ColumnStorage mixedStorage, CastProblemAggregator problemAggregator) { + ColumnStorage mixedStorage, CastProblemAggregator problemAggregator) { return innerLoop( Builder.getForLong(targetType, mixedStorage.getSize(), problemAggregator), mixedStorage, (builder, i) -> { - Object o = mixedStorage.getItemAsObject(i); + Object o = mixedStorage.getItemBoxed(i); if (o instanceof Boolean b) { builder.appendLong(booleanAsLong(b)); } else if (NumericConverter.isCoercibleToLong(o)) { @@ -120,7 +118,7 @@ private Storage convertBoolStorage( Builder.getForLong(targetType, boolStorage.getSize(), problemAggregator), boolStorage, (builder, i) -> { - boolean value = boolStorage.get(i); + boolean value = boolStorage.getItemAsBoolean(i); builder.appendLong(booleanAsLong(value)); }); } @@ -131,7 +129,7 @@ private Storage convertDoubleStorage( Builder.getForLong(targetType, doubleStorage.getSize(), problemAggregator), doubleStorage, (builder, i) -> { - double value = doubleStorage.get(i); + double value = doubleStorage.getItemAsDouble(i); if (targetType.fits(value)) { long converted = (long) value; builder.appendLong(converted); @@ -152,10 +150,10 @@ private Storage convertLongStorage( } return innerLoop( - Builder.getForLong(targetType, longStorage.size(), problemAggregator), + Builder.getForLong(targetType, longStorage.getSize(), problemAggregator), longStorage, (builder, i) -> { - long value = longStorage.getItem((int) i); + long value = longStorage.getItemAsLong(i); builder.appendLong(value); }); } @@ -163,10 +161,10 @@ private Storage convertLongStorage( private Storage convertBigIntegerStorage( Storage storage, CastProblemAggregator problemAggregator) { return innerLoop( - Builder.getForLong(targetType, storage.size(), problemAggregator), + Builder.getForLong(targetType, storage.getSize(), problemAggregator), storage, (builder, i) -> { - BigInteger value = storage.getItemBoxed((int) i); + BigInteger value = storage.getItemBoxed(i); if (targetType.fits(value)) { builder.appendLong(value.longValue()); } else { @@ -179,10 +177,10 @@ private Storage convertBigIntegerStorage( private Storage convertBigDecimalStorage( Storage storage, CastProblemAggregator problemAggregator) { return innerLoop( - Builder.getForLong(targetType, storage.size(), problemAggregator), + Builder.getForLong(targetType, storage.getSize(), problemAggregator), storage, (builder, i) -> { - BigDecimal value = storage.getItemBoxed((int) i); + BigDecimal value = storage.getItemBoxed(i); BigInteger bigInteger = value.toBigInteger(); if (targetType.fits(bigInteger)) { builder.appendLong(bigInteger.longValue()); diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToTextStorageConverter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToTextStorageConverter.java index c856155c0dc1..71a571bd99e6 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToTextStorageConverter.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToTextStorageConverter.java @@ -7,12 +7,15 @@ import java.util.function.Function; import org.enso.polyglot.common_utils.Core_Date_Utils; import org.enso.table.data.column.builder.Builder; -import org.enso.table.data.column.storage.*; +import org.enso.table.data.column.storage.ColumnBooleanStorage; +import org.enso.table.data.column.storage.ColumnDoubleStorage; +import org.enso.table.data.column.storage.ColumnLongStorage; +import org.enso.table.data.column.storage.ColumnStorage; +import org.enso.table.data.column.storage.Storage; +import org.enso.table.data.column.storage.StringStorage; import org.enso.table.data.column.storage.datetime.DateStorage; import org.enso.table.data.column.storage.datetime.DateTimeStorage; import org.enso.table.data.column.storage.datetime.TimeOfDayStorage; -import org.enso.table.data.column.storage.numeric.AbstractLongStorage; -import org.enso.table.data.column.storage.numeric.DoubleStorage; import org.enso.table.data.column.storage.type.AnyObjectType; import org.enso.table.data.column.storage.type.NullType; import org.enso.table.data.column.storage.type.TextType; @@ -33,11 +36,11 @@ public Storage cast(Storage storage, CastProblemAggregator problemAgg return adaptStringStorage(stringStorage, problemAggregator); } } - if (storage instanceof AbstractLongStorage longStorage) { + if (storage instanceof ColumnLongStorage longStorage) { return castLongStorage(longStorage, problemAggregator); - } else if (storage instanceof DoubleStorage doubleStorage) { + } else if (storage instanceof ColumnDoubleStorage doubleStorage) { return castDoubleStorage(doubleStorage, problemAggregator); - } else if (storage instanceof BoolStorage boolStorage) { + } else if (storage instanceof ColumnBooleanStorage boolStorage) { return castBoolStorage(boolStorage, problemAggregator); } else if (storage instanceof TimeOfDayStorage timeOfDayStorage) { return castTemporalStorage(timeOfDayStorage, this::convertTime, problemAggregator); @@ -55,12 +58,12 @@ public Storage cast(Storage storage, CastProblemAggregator problemAgg } private Storage castFromMixed( - ColumnStorage mixedStorage, CastProblemAggregator problemAggregator) { + ColumnStorage mixedStorage, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( - Builder.getForText(mixedStorage.getSize(), targetType), + Builder.getForText(targetType, mixedStorage.getSize()), mixedStorage, (i) -> { - Object o = mixedStorage.getItemAsObject(i); + Object o = mixedStorage.getItemBoxed(i); return switch (o) { case LocalTime d -> adapt(convertTime(d), problemAggregator); case LocalDate d -> adapt(convertDate(d), problemAggregator); @@ -74,10 +77,10 @@ private Storage castFromMixed( private Storage castLongStorage( ColumnLongStorage longStorage, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( - Builder.getForText(longStorage.getSize(), targetType), + Builder.getForText(targetType, longStorage.getSize()), longStorage, (i) -> { - long value = longStorage.get(i); + long value = longStorage.getItemAsLong(i); return adapt(Long.toString(value), problemAggregator); }); } @@ -85,10 +88,10 @@ private Storage castLongStorage( private Storage castBoolStorage( ColumnBooleanStorage boolStorage, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( - Builder.getForText(boolStorage.getSize(), targetType), + Builder.getForText(targetType, boolStorage.getSize()), boolStorage, (i) -> { - boolean value = boolStorage.get(i); + boolean value = boolStorage.getItemAsBoolean(i); return adapt(convertBoolean(value), problemAggregator); }); } @@ -96,10 +99,10 @@ private Storage castBoolStorage( private Storage castDoubleStorage( ColumnDoubleStorage doubleStorage, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( - Builder.getForText(doubleStorage.getSize(), targetType), + Builder.getForText(targetType, doubleStorage.getSize()), doubleStorage, (i) -> { - double value = doubleStorage.get(i); + double value = doubleStorage.getItemAsDouble(i); return adapt(Double.toString(value), problemAggregator); }); } @@ -107,10 +110,10 @@ private Storage castDoubleStorage( private Storage castTemporalStorage( Storage storage, Function converter, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( - Builder.getForText(storage.size(), targetType), + Builder.getForText(targetType, storage.getSize()), storage, (i) -> { - var value = storage.getItemBoxed((int) i); + var value = storage.getItemBoxed(i); return adapt(converter.apply(value), problemAggregator); }); } @@ -118,10 +121,10 @@ private Storage castTemporalStorage( private Storage adaptStringStorage( StringStorage stringStorage, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( - Builder.getForText(stringStorage.size(), targetType), + Builder.getForText(targetType, stringStorage.getSize()), stringStorage, (i) -> { - String value = stringStorage.getItem(i); + String value = stringStorage.getItemBoxed(i); // Adapting an existing string storage into a new type is done without warnings. return adaptWithoutWarning(value); }); @@ -172,8 +175,8 @@ private boolean canAvoidCopying(StringStorage stringStorage) { long maxLength = Long.MIN_VALUE; long minLength = Long.MAX_VALUE; - for (int i = 0; i < stringStorage.size(); i++) { - String value = stringStorage.getItem(i); + for (long i = 0; i < stringStorage.getSize(); i++) { + String value = stringStorage.getItemBoxed(i); if (value == null) { continue; } @@ -202,6 +205,6 @@ private boolean canAvoidCopying(StringStorage stringStorage) { * canAvoidCopying}. */ private Storage retypeStringStorage(StringStorage stringStorage) { - return new StringStorage(stringStorage.getData(), stringStorage.size(), targetType); + return new StringStorage(stringStorage.getData(), targetType); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToTimeOfDayStorageConverter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToTimeOfDayStorageConverter.java index eb9e547ea4c6..c4098a36cfa3 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToTimeOfDayStorageConverter.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToTimeOfDayStorageConverter.java @@ -27,12 +27,12 @@ public Storage cast(Storage storage, CastProblemAggregator problem } private Storage castFromMixed( - ColumnStorage mixedStorage, CastProblemAggregator problemAggregator) { + ColumnStorage mixedStorage, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( Builder.getForTime(mixedStorage.getSize()), mixedStorage, (i) -> { - Object o = mixedStorage.getItemAsObject(i); + Object o = mixedStorage.getItemBoxed(i); return switch (o) { case LocalTime d -> d; case ZonedDateTime d -> convertDateTime(d); @@ -45,12 +45,12 @@ private Storage castFromMixed( } private Storage convertDateTimeStorage( - DateTimeStorage dateTimeStorage, CastProblemAggregator problemAggregator) { + Storage dateTimeStorage, CastProblemAggregator problemAggregator) { return StorageConverter.innerLoop( - Builder.getForTime(dateTimeStorage.size()), + Builder.getForTime(dateTimeStorage.getSize()), dateTimeStorage, (i) -> { - ZonedDateTime dateTime = dateTimeStorage.getItem(i); + ZonedDateTime dateTime = dateTimeStorage.getItemBoxed(i); return convertDateTime(dateTime); }); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/GenericBinaryObjectMapOperation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/GenericBinaryObjectMapOperation.java index 726bb7520d6b..99e178be6aa6 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/GenericBinaryObjectMapOperation.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/GenericBinaryObjectMapOperation.java @@ -23,7 +23,7 @@ protected GenericBinaryObjectMapOperation( private final Class inputTypeClass; private final Class inputStorageTypeClass; - protected abstract Builder createOutputBuilder(int size); + protected abstract Builder createOutputBuilder(long size); protected abstract OutputType run(InputType value, InputType other); @@ -32,16 +32,17 @@ public Storage runBinaryMap( InputStorageType storage, Object arg, MapOperationProblemAggregator problemAggregator) { arg = Polyglot_Utils.convertPolyglotValue(arg); if (arg == null) { - int n = storage.size(); + long n = storage.getSize(); Builder builder = createOutputBuilder(n); - builder.appendNulls(n); + // ToDo: appendNulls should accept a long instead of an int. + builder.appendNulls(Math.toIntExact(n)); return builder.seal(); } else if (inputTypeClass.isInstance(arg)) { InputType casted = inputTypeClass.cast(arg); - int n = storage.size(); + long n = storage.getSize(); Builder builder = createOutputBuilder(n); Context context = Context.getCurrent(); - for (int i = 0; i < n; i++) { + for (long i = 0; i < n; i++) { if (storage.isNothing(i)) { builder.appendNulls(1); } else { @@ -63,10 +64,10 @@ public Storage runZip( InputStorageType storage, Storage arg, MapOperationProblemAggregator problemAggregator) { if (inputStorageTypeClass.isInstance(arg)) { InputStorageType otherCasted = inputStorageTypeClass.cast(arg); - int n = storage.size(); + long n = storage.getSize(); Builder builder = createOutputBuilder(n); Context context = Context.getCurrent(); - for (int i = 0; i < n; ++i) { + for (long i = 0; i < n; ++i) { if (storage.isNothing(i) || otherCasted.isNothing(i)) { builder.appendNulls(1); } else { @@ -81,10 +82,10 @@ public Storage runZip( return builder.seal(); } else if (arg.getType() instanceof AnyObjectType) { // TODO this case may not be needed once #7231 gets implemented - int n = storage.size(); + long n = storage.getSize(); Builder builder = createOutputBuilder(n); Context context = Context.getCurrent(); - for (int i = 0; i < n; ++i) { + for (long i = 0; i < n; ++i) { if (storage.isNothing(i) || arg.isNothing(i)) { builder.appendNulls(1); } else { diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/SpecializedIsInOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/SpecializedIsInOp.java index 1c33277d1376..f15aa0c36342 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/SpecializedIsInOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/SpecializedIsInOp.java @@ -3,6 +3,7 @@ import java.util.BitSet; import java.util.HashSet; import java.util.List; +import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.storage.BoolStorage; import org.enso.table.data.column.storage.Storage; import org.graalvm.polyglot.Context; @@ -52,25 +53,33 @@ public Storage runBinaryMap( } public Storage runMap(S storage, List arg) { - Context context = Context.getCurrent(); + if (arg.isEmpty()) { + int size = Math.toIntExact(storage.getSize()); + return new BoolStorage(new BitSet(), new BitSet(), size, false); + } + + long size = storage.getSize(); + var builder = Builder.getForBoolean(size); CompactRepresentation compactRepresentation = prepareList(arg); - BitSet newVals = new BitSet(); - BitSet isNothing = new BitSet(); - if (!arg.isEmpty()) { - for (int i = 0; i < storage.size(); i++) { - if (storage.isNothing(i)) { - isNothing.set(i); - } else if (compactRepresentation.coercedValues.contains(storage.getItemBoxed(i))) { - newVals.set(i); + + Context context = Context.getCurrent(); + for (long i = 0; i < size; i++) { + if (storage.isNothing(i)) { + builder.appendNulls(1); + } else { + if (compactRepresentation.coercedValues.contains(storage.getItemBoxed(i))) { + builder.appendBoolean(true); } else if (compactRepresentation.hasNulls) { - isNothing.set(i); + builder.appendNulls(1); + } else { + builder.appendBoolean(false); } - // Otherwise leave as default=false - - context.safepoint(); } + + context.safepoint(); } - return new BoolStorage(newVals, isNothing, storage.size(), false); + + return builder.seal(); } @Override diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/bool/BooleanIsInOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/bool/BooleanIsInOp.java index 80a9cd7b4797..b380382e8260 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/bool/BooleanIsInOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/bool/BooleanIsInOp.java @@ -60,10 +60,10 @@ public Storage runZip( } private BoolStorage run(BoolStorage storage, boolean hadNull, boolean hadTrue, boolean hadFalse) { - int size = storage.size(); + // ToDo: BoolStorage works on ints, so casting to an int here. + int size = (int) storage.getSize(); ImmutableBitSet values = new ImmutableBitSet(storage.getValues(), size); ImmutableBitSet isNothing = new ImmutableBitSet(storage.getIsNothingMap(), size); - boolean negated = storage.isNegated(); ImmutableBitSet newValues; ImmutableBitSet newIsNothing; diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/bool/GenericBinaryOpReturningBoolean.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/bool/GenericBinaryOpReturningBoolean.java index d6a2c2529a4c..e1ea3adc8fe0 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/bool/GenericBinaryOpReturningBoolean.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/bool/GenericBinaryOpReturningBoolean.java @@ -1,6 +1,6 @@ package org.enso.table.data.column.operation.map.bool; -import java.util.BitSet; +import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.operation.map.BinaryMapOperation; import org.enso.table.data.column.operation.map.MapOperationProblemAggregator; import org.enso.table.data.column.storage.BoolStorage; @@ -35,7 +35,7 @@ public GenericBinaryOpReturningBoolean(String name) { public Storage runBinaryMap( S storage, Object arg, MapOperationProblemAggregator problemAggregator) { if (arg == null) { - return BoolStorage.makeEmpty(storage.size()); + return BoolStorage.makeEmpty(storage.getSize()); } else { T argT = tryCast(arg); if (argT != null) { @@ -60,79 +60,76 @@ public Storage runZip( } } - private BoolStorage runHomogenousMap(S storage, T arg) { - BitSet newVals = new BitSet(); - BitSet newIsNothing = new BitSet(); + private Storage runHomogenousMap(S storage, T arg) { Context context = Context.getCurrent(); - int n = storage.size(); - for (int i = 0; i < n; i++) { + long n = storage.getSize(); + var builder = Builder.getForBoolean(n); + for (long i = 0; i < n; i++) { if (storage.isNothing(i)) { - newIsNothing.set(i); + builder.appendNulls(1); } else { T storageItem = storage.getItemBoxed(i); assert storageItem != null : "isNothing returned true but element was null"; boolean r = doOperation(storageItem, arg); - newVals.set(i, r); + builder.append(r); } context.safepoint(); } - return new BoolStorage(newVals, newIsNothing, n, false); + return builder.seal(); } - private BoolStorage runMixedMap(S storage, Object arg) { - BitSet newVals = new BitSet(); - BitSet newIsNothing = new BitSet(); + private Storage runMixedMap(S storage, Object arg) { Context context = Context.getCurrent(); - int n = storage.size(); - for (int i = 0; i < n; i++) { + long n = storage.getSize(); + var builder = Builder.getForBoolean(n); + for (long i = 0; i < n; i++) { if (storage.isNothing(i)) { - newIsNothing.set(i); + builder.appendNulls(1); } else { T storageItem = storage.getItemBoxed(i); assert storageItem != null : "isNothing returned true but element was null"; boolean r = doOther(storageItem, arg); - newVals.set(i, r); + builder.append(r); } context.safepoint(); } - return new BoolStorage(newVals, newIsNothing, n, false); + return builder.seal(); } - private BoolStorage runHomogenousZip(S storage, SpecializedStorage argStorage) { - BitSet newVals = new BitSet(); - BitSet newIsNothing = new BitSet(); + private Storage runHomogenousZip(S storage, SpecializedStorage argStorage) { + long n = storage.getSize(); + long m = argStorage.getSize(); + + var builder = Builder.getForBoolean(n); Context context = Context.getCurrent(); - int n = storage.size(); - int m = argStorage.size(); - for (int i = 0; i < n; i++) { - if (storage.isNothing(i) || !(i < m) || argStorage.isNothing(i)) { - newIsNothing.set(i); + for (long i = 0; i < n; i++) { + if (i >= m || storage.isNothing(i) || argStorage.isNothing(i)) { + builder.appendNulls(1); } else { T storageItem = storage.getItemBoxed(i); T argItem = argStorage.getItemBoxed(i); assert storageItem != null : "isNothing returned true but element was null"; assert argItem != null : "isNothing returned true but element was null"; boolean r = doOperation(storageItem, argItem); - newVals.set(i, r); + builder.appendBoolean(r); } context.safepoint(); } - return new BoolStorage(newVals, newIsNothing, n, false); + return builder.seal(); } - private BoolStorage runMixedZip(S storage, Storage argStorage) { - BitSet newVals = new BitSet(); - BitSet newIsNothing = new BitSet(); + private Storage runMixedZip(S storage, Storage argStorage) { Context context = Context.getCurrent(); - int n = storage.size(); - int m = argStorage.size(); - for (int i = 0; i < n; i++) { - if (storage.isNothing(i) || !(i < m) || argStorage.isNothing(i)) { - newIsNothing.set(i); + long n = storage.getSize(); + long m = argStorage.getSize(); + var builder = Builder.getForBoolean(n); + for (long i = 0; i < n; i++) { + if (i >= m || storage.isNothing(i) || argStorage.isNothing(i)) { + builder.appendNulls(1); } else { T storageItem = storage.getItemBoxed(i); Object argItem = argStorage.getItemBoxed(i); @@ -141,12 +138,12 @@ private BoolStorage runMixedZip(S storage, Storage argStorage) { T argT = tryCast(argItem); boolean r = (argT != null) ? doOperation(storageItem, argT) : doOther(storageItem, argItem); - newVals.set(i, r); + builder.append(r); } context.safepoint(); } - return new BoolStorage(newVals, newIsNothing, n, false); + return builder.seal(); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/datetime/TimeLikeCoalescingOperation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/datetime/TimeLikeCoalescingOperation.java index 0f67802707b2..9d8c442f2df6 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/datetime/TimeLikeCoalescingOperation.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/datetime/TimeLikeCoalescingOperation.java @@ -18,24 +18,23 @@ public TimeLikeCoalescingOperation(String name, Class inputTypeClass) { this.inputTypeClass = inputTypeClass; } - protected abstract Builder createOutputBuilder(int size); + protected abstract Builder createOutputBuilder(long size); protected abstract T doOperation(T a, T b); @Override public Storage runBinaryMap( SpecializedStorage storage, Object arg, MapOperationProblemAggregator problemAggregator) { - int size = storage.size(); if (arg == null) { return storage; } else { Object adapted = Polyglot_Utils.convertPolyglotValue(arg); if (inputTypeClass.isInstance(adapted)) { T casted = inputTypeClass.cast(adapted); - int n = storage.size(); - Builder builder = createOutputBuilder(n); + long size = storage.getSize(); + Builder builder = createOutputBuilder(size); Context context = Context.getCurrent(); - for (int i = 0; i < size; i++) { + for (long i = 0; i < size; i++) { T r = storage.isNothing(i) ? casted : doOperation(storage.getItemBoxed(i), casted); builder.append(r); context.safepoint(); @@ -57,10 +56,10 @@ public Storage runZip( if (arg.getType().equals(storage.getType())) { if (arg instanceof SpecializedStorage argStorage) { SpecializedStorage argTStorage = storage.castIfSameType(argStorage); - int n = storage.size(); + long n = storage.getSize(); Builder builder = createOutputBuilder(n); Context context = Context.getCurrent(); - for (int i = 0; i < n; i++) { + for (long i = 0; i < n; i++) { T a = storage.getItemBoxed(i); T b = argTStorage.getItemBoxed(i); T r; diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/BigDecimalRoundOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/BigDecimalRoundOp.java index 6fb5182ac1f9..1554aba79cfe 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/BigDecimalRoundOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/BigDecimalRoundOp.java @@ -7,7 +7,6 @@ import org.enso.table.data.column.operation.map.TernaryMapOperation; import org.enso.table.data.column.storage.SpecializedStorage; import org.enso.table.data.column.storage.Storage; -import org.enso.table.data.column.storage.type.BigDecimalType; import org.enso.table.error.UnexpectedTypeException; import org.graalvm.polyglot.Context; @@ -37,16 +36,15 @@ public Storage runTernaryMap( } assert decimalPlaces >= ROUND_MIN_DECIMAL_PLACES && decimalPlaces <= ROUND_MAX_DECIMAL_PLACES; + int decimalPlacesInt = (int) decimalPlaces.longValue(); - Builder builder = - Builder.getForType(BigDecimalType.INSTANCE, storage.size(), problemAggregator); - + Builder builder = Builder.getForBigDecimal(storage.getSize()); Context context = Context.getCurrent(); - for (int i = 0; i < storage.size(); i++) { + for (long i = 0; i < storage.getSize(); i++) { if (!storage.isNothing(i)) { - BigDecimal value = storage.getItem(i); - BigDecimal result = Decimal_Utils.round(value, (int) decimalPlaces.longValue(), useBankers); + BigDecimal value = storage.getItemBoxed(i); + BigDecimal result = Decimal_Utils.round(value, decimalPlacesInt, useBankers); builder.append(result); } else { builder.appendNulls(1); diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/DoubleRoundOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/DoubleRoundOp.java index 6add938e6b83..05ffb7445aaa 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/DoubleRoundOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/DoubleRoundOp.java @@ -1,13 +1,11 @@ package org.enso.table.data.column.operation.map.numeric; -import java.util.BitSet; import org.enso.polyglot.common_utils.Core_Math_Utils; import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.operation.map.MapOperationProblemAggregator; import org.enso.table.data.column.operation.map.TernaryMapOperation; import org.enso.table.data.column.storage.Storage; import org.enso.table.data.column.storage.numeric.DoubleStorage; -import org.enso.table.data.column.storage.numeric.LongStorage; import org.enso.table.data.column.storage.type.FloatType; import org.enso.table.data.column.storage.type.IntegerType; import org.enso.table.error.UnexpectedTypeException; @@ -38,33 +36,35 @@ public Storage runTernaryMap( if (decimalPlaces <= 0) { // Return Long storage - long[] out = new long[storage.size()]; - BitSet isNothing = new BitSet(); + var longBuilder = + Builder.getForLong(IntegerType.INT_64, storage.getSize(), problemAggregator); - for (int i = 0; i < storage.size(); i++) { + for (long i = 0; i < storage.getSize(); i++) { if (!storage.isNothing(i)) { double item = storage.getItemAsDouble(i); boolean special = Double.isNaN(item) || Double.isInfinite(item); if (!special) { - out[i] = (long) Core_Math_Utils.roundDouble(item, decimalPlaces, useBankers); + longBuilder.appendLong( + (long) Core_Math_Utils.roundDouble(item, decimalPlaces, useBankers)); } else { String msg = "Value is " + item; - problemAggregator.reportArithmeticError(msg, i); - isNothing.set(i); + // ToDo: ProblemAggregator should accept a long instead of an int. + problemAggregator.reportArithmeticError(msg, (int) i); + longBuilder.appendNulls(1); } } else { - isNothing.set(i); + longBuilder.appendNulls(1); } context.safepoint(); } - return new LongStorage(out, storage.size(), isNothing, IntegerType.INT_64); + return longBuilder.seal(); } else { // Return double storage. var doubleBuilder = - Builder.getForDouble(FloatType.FLOAT_64, storage.size(), problemAggregator); + Builder.getForDouble(FloatType.FLOAT_64, storage.getSize(), problemAggregator); - for (int i = 0; i < storage.size(); i++) { + for (long i = 0; i < storage.getSize(); i++) { if (!storage.isNothing(i)) { double item = storage.getItemAsDouble(i); boolean special = Double.isNaN(item) || Double.isInfinite(item); @@ -73,7 +73,8 @@ public Storage runTernaryMap( Core_Math_Utils.roundDouble(item, decimalPlaces, useBankers)); } else { String msg = "Value is " + item; - problemAggregator.reportArithmeticError(msg, i); + // ToDo: ProblemAggregator should accept a long instead of an int. + problemAggregator.reportArithmeticError(msg, (int) i); doubleBuilder.appendNulls(1); } } else { diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/LongRoundOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/LongRoundOp.java index 6d247b27dbad..4ccfe949b1b7 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/LongRoundOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/LongRoundOp.java @@ -1,12 +1,11 @@ package org.enso.table.data.column.operation.map.numeric; -import java.util.BitSet; import org.enso.polyglot.common_utils.Core_Math_Utils; +import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.operation.map.MapOperationProblemAggregator; import org.enso.table.data.column.operation.map.TernaryMapOperation; import org.enso.table.data.column.storage.Storage; import org.enso.table.data.column.storage.numeric.AbstractLongStorage; -import org.enso.table.data.column.storage.numeric.LongStorage; import org.enso.table.data.column.storage.type.IntegerType; import org.enso.table.error.UnexpectedTypeException; import org.graalvm.polyglot.Context; @@ -44,15 +43,13 @@ public Storage runTernaryMap( } Context context = Context.getCurrent(); - long[] out = new long[storage.size()]; - BitSet isNothing = new BitSet(); - - for (int i = 0; i < storage.size(); i++) { + var builder = Builder.getForLong(IntegerType.INT_64, storage.getSize(), problemAggregator); + for (long i = 0; i < storage.getSize(); i++) { if (!storage.isNothing(i)) { - long item = storage.getItem(i); + long item = storage.getItemAsLong(i); boolean outOfRange = item < ROUND_MIN_LONG || item > ROUND_MAX_LONG; if (!outOfRange) { - out[i] = Core_Math_Utils.roundLong(item, decimalPlaces, useBankers); + builder.appendLong(Core_Math_Utils.roundLong(item, decimalPlaces, useBankers)); } else { String msg = "Error: `round` can only accept values between " @@ -61,17 +58,17 @@ public Storage runTernaryMap( + ROUND_MAX_LONG + " (inclusive), but was " + item; - problemAggregator.reportIllegalArgumentError(msg, i); - isNothing.set(i); + // ToDo: ProblemAggregator should accept a long instead of an int. + problemAggregator.reportIllegalArgumentError(msg, (int) i); + builder.appendNulls(1); } - } else { - isNothing.set(i); + builder.appendNulls(1); } context.safepoint(); } - return new LongStorage(out, storage.size(), isNothing, IntegerType.INT_64); + return builder.seal(); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/AddOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/AddOp.java index 2306ef136ad9..f96a15f65f5d 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/AddOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/AddOp.java @@ -14,12 +14,12 @@ public AddOp() { @Override public double doDouble( - double a, double b, int ix, MapOperationProblemAggregator problemAggregator) { + double a, double b, long ix, MapOperationProblemAggregator problemAggregator) { return a + b; } @Override - public Long doLong(long a, long b, int ix, MapOperationProblemAggregator problemAggregator) { + public Long doLong(long a, long b, long ix, MapOperationProblemAggregator problemAggregator) { try { return Math.addExact(a, b); } catch (ArithmeticException e) { @@ -30,13 +30,13 @@ public Long doLong(long a, long b, int ix, MapOperationProblemAggregator problem @Override public BigInteger doBigInteger( - BigInteger a, BigInteger b, int ix, MapOperationProblemAggregator problemAggregator) { + BigInteger a, BigInteger b, long ix, MapOperationProblemAggregator problemAggregator) { return a.add(b); } @Override public BigDecimal doBigDecimal( - BigDecimal a, BigDecimal b, int ix, MapOperationProblemAggregator problemAggregator) { + BigDecimal a, BigDecimal b, long ix, MapOperationProblemAggregator problemAggregator) { return a.add(b); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/BigDecimalDivideOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/BigDecimalDivideOp.java index e5e20b5b86fe..d50bc841937c 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/BigDecimalDivideOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/BigDecimalDivideOp.java @@ -12,13 +12,13 @@ public BigDecimalDivideOp() { @Override public BigDecimal doBigDecimal( - BigDecimal a, BigDecimal b, int ix, MapOperationProblemAggregator problemAggregator) { + BigDecimal a, BigDecimal b, long ix, MapOperationProblemAggregator problemAggregator) { try { return a.divide(b); } catch (ArithmeticException e) { String extraMessage = " Please use `.divide` with an explicit `Math_Context` to limit the numeric precision."; - problemAggregator.reportArithmeticError(e.getMessage() + extraMessage, ix); + problemAggregator.reportArithmeticError(e.getMessage() + extraMessage, (int) ix); return null; } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/DivideOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/DivideOp.java index 9c1c42f1d4f5..ae8550b91207 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/DivideOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/DivideOp.java @@ -11,9 +11,10 @@ public DivideOp() { @Override public double doDouble( - double a, double b, int ix, MapOperationProblemAggregator problemAggregator) { + double a, double b, long ix, MapOperationProblemAggregator problemAggregator) { if (b == 0.0) { - problemAggregator.reportDivisionByZero(ix); + // ToDo: ProblemAggregator should accept a long instead of an int. + problemAggregator.reportDivisionByZero((int) ix); } return a / b; } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/MaxOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/MaxOp.java index da385141238e..dec9576fed39 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/MaxOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/MaxOp.java @@ -13,24 +13,24 @@ public MaxOp() { @Override public double doDouble( - double a, double b, int ix, MapOperationProblemAggregator problemAggregator) { + double a, double b, long ix, MapOperationProblemAggregator problemAggregator) { return Math.max(a, b); } @Override - public Long doLong(long a, long b, int ix, MapOperationProblemAggregator problemAggregator) { + public Long doLong(long a, long b, long ix, MapOperationProblemAggregator problemAggregator) { return Math.max(a, b); } @Override public BigInteger doBigInteger( - BigInteger a, BigInteger b, int ix, MapOperationProblemAggregator problemAggregator) { + BigInteger a, BigInteger b, long ix, MapOperationProblemAggregator problemAggregator) { return a.max(b); } @Override public BigDecimal doBigDecimal( - BigDecimal a, BigDecimal b, int ix, MapOperationProblemAggregator problemAggregator) { + BigDecimal a, BigDecimal b, long ix, MapOperationProblemAggregator problemAggregator) { return a.max(b); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/MinOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/MinOp.java index 1dd0b99f78ff..d900edded8b5 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/MinOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/MinOp.java @@ -13,24 +13,24 @@ public MinOp() { @Override public double doDouble( - double a, double b, int ix, MapOperationProblemAggregator problemAggregator) { + double a, double b, long ix, MapOperationProblemAggregator problemAggregator) { return Math.min(a, b); } @Override - public Long doLong(long a, long b, int ix, MapOperationProblemAggregator problemAggregator) { + public Long doLong(long a, long b, long ix, MapOperationProblemAggregator problemAggregator) { return Math.min(a, b); } @Override public BigInteger doBigInteger( - BigInteger a, BigInteger b, int ix, MapOperationProblemAggregator problemAggregator) { + BigInteger a, BigInteger b, long ix, MapOperationProblemAggregator problemAggregator) { return a.min(b); } @Override public BigDecimal doBigDecimal( - BigDecimal a, BigDecimal b, int ix, MapOperationProblemAggregator problemAggregator) { + BigDecimal a, BigDecimal b, long ix, MapOperationProblemAggregator problemAggregator) { return a.min(b); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/ModOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/ModOp.java index fb544c993700..187e49013d9a 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/ModOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/ModOp.java @@ -13,18 +13,20 @@ public ModOp() { @Override public double doDouble( - double a, double b, int ix, MapOperationProblemAggregator problemAggregator) { + double a, double b, long ix, MapOperationProblemAggregator problemAggregator) { if (b == 0.0) { - problemAggregator.reportDivisionByZero(ix); + // ToDo: ProblemAggregator should accept a long instead of an int. + problemAggregator.reportDivisionByZero((int) ix); } return a % b; } @Override - public Long doLong(long a, long b, int ix, MapOperationProblemAggregator problemAggregator) { + public Long doLong(long a, long b, long ix, MapOperationProblemAggregator problemAggregator) { if (b == 0) { - problemAggregator.reportDivisionByZero(ix); + // ToDo: ProblemAggregator should accept a long instead of an int. + problemAggregator.reportDivisionByZero((int) ix); return null; } @@ -33,9 +35,10 @@ public Long doLong(long a, long b, int ix, MapOperationProblemAggregator problem @Override public BigInteger doBigInteger( - BigInteger a, BigInteger b, int ix, MapOperationProblemAggregator problemAggregator) { + BigInteger a, BigInteger b, long ix, MapOperationProblemAggregator problemAggregator) { if (b.equals(BigInteger.ZERO)) { - problemAggregator.reportDivisionByZero(ix); + // ToDo: ProblemAggregator should accept a long instead of an int. + problemAggregator.reportDivisionByZero((int) ix); return null; } @@ -44,9 +47,10 @@ public BigInteger doBigInteger( @Override public BigDecimal doBigDecimal( - BigDecimal a, BigDecimal b, int ix, MapOperationProblemAggregator problemAggregator) { + BigDecimal a, BigDecimal b, long ix, MapOperationProblemAggregator problemAggregator) { if (b.equals(BigDecimal.ZERO)) { - problemAggregator.reportDivisionByZero(ix); + // ToDo: ProblemAggregator should accept a long instead of an int. + problemAggregator.reportDivisionByZero((int) ix); return null; } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/MulOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/MulOp.java index 781c1c1c1093..1f4d2a7c50a3 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/MulOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/MulOp.java @@ -14,12 +14,12 @@ public MulOp() { @Override public double doDouble( - double a, double b, int ix, MapOperationProblemAggregator problemAggregator) { + double a, double b, long ix, MapOperationProblemAggregator problemAggregator) { return a * b; } @Override - public Long doLong(long a, long b, int ix, MapOperationProblemAggregator problemAggregator) { + public Long doLong(long a, long b, long ix, MapOperationProblemAggregator problemAggregator) { try { return Math.multiplyExact(a, b); } catch (ArithmeticException e) { @@ -30,13 +30,13 @@ public Long doLong(long a, long b, int ix, MapOperationProblemAggregator problem @Override public BigInteger doBigInteger( - BigInteger a, BigInteger b, int ix, MapOperationProblemAggregator problemAggregator) { + BigInteger a, BigInteger b, long ix, MapOperationProblemAggregator problemAggregator) { return a.multiply(b); } @Override public BigDecimal doBigDecimal( - BigDecimal a, BigDecimal b, int ix, MapOperationProblemAggregator problemAggregator) { + BigDecimal a, BigDecimal b, long ix, MapOperationProblemAggregator problemAggregator) { return a.multiply(b); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpCoalescing.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpCoalescing.java index 42db3a7d4293..e97dfb0009af 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpCoalescing.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpCoalescing.java @@ -2,18 +2,15 @@ import java.math.BigDecimal; import java.math.BigInteger; -import java.util.BitSet; +import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.operation.map.MapOperationProblemAggregator; import org.enso.table.data.column.operation.map.numeric.helpers.BigDecimalArrayAdapter; import org.enso.table.data.column.operation.map.numeric.helpers.BigIntegerArrayAdapter; import org.enso.table.data.column.operation.map.numeric.helpers.DoubleArrayAdapter; -import org.enso.table.data.column.storage.SpecializedStorage; import org.enso.table.data.column.storage.Storage; import org.enso.table.data.column.storage.numeric.AbstractLongStorage; -import org.enso.table.data.column.storage.numeric.BigDecimalStorage; -import org.enso.table.data.column.storage.numeric.BigIntegerStorage; -import org.enso.table.data.column.storage.numeric.DoubleStorage; -import org.enso.table.data.column.storage.numeric.LongStorage; +import org.enso.table.data.column.storage.type.FloatType; +import org.enso.table.data.column.storage.type.IntegerType; import org.graalvm.polyglot.Context; /** @@ -27,18 +24,18 @@ public NumericBinaryOpCoalescing(String name) { } @Override - protected DoubleStorage runDoubleZip( + protected Storage runDoubleZip( DoubleArrayAdapter a, DoubleArrayAdapter b, MapOperationProblemAggregator problemAggregator) { + long n = a.size(); + long m = Math.min(n, b.size()); + var builder = Builder.getForDouble(FloatType.FLOAT_64, n, problemAggregator); Context context = Context.getCurrent(); - int n = a.size(); - int m = Math.min(a.size(), b.size()); - double[] out = new double[n]; - BitSet isNothing = new BitSet(); - for (int i = 0; i < m; i++) { + + for (long i = 0; i < n; i++) { boolean aNothing = a.isNothing(i); - boolean bNothing = b.isNothing(i); + boolean bNothing = i >= m || b.isNothing(i); if (aNothing && bNothing) { - isNothing.set(i); + builder.appendNulls(1); } else { double r; if (aNothing) { @@ -48,27 +45,17 @@ protected DoubleStorage runDoubleZip( } else { r = doDouble(a.getItemAsDouble(i), b.getItemAsDouble(i), i, problemAggregator); } - out[i] = r; + builder.appendDouble(r); } context.safepoint(); } - for (int i = m; i < n; ++i) { - if (a.isNothing(i)) { - isNothing.set(i); - } else { - out[i] = a.getItemAsDouble(i); - } - - context.safepoint(); - } - - return new DoubleStorage(out, n, isNothing); + return builder.seal(); } @Override - protected DoubleStorage runDoubleMap( + protected Storage runDoubleMap( DoubleArrayAdapter a, Double b, MapOperationProblemAggregator problemAggregator) { if (b == null) { return a.intoStorage(); @@ -76,46 +63,45 @@ protected DoubleStorage runDoubleMap( double bNonNull = b; Context context = Context.getCurrent(); - int n = a.size(); - double[] out = new double[n]; - BitSet isNothing = new BitSet(); - for (int i = 0; i < n; i++) { - out[i] = + long n = a.size(); + var builder = Builder.getForDouble(FloatType.FLOAT_64, n, problemAggregator); + for (long i = 0; i < n; i++) { + builder.appendDouble( a.isNothing(i) ? bNonNull - : doDouble(a.getItemAsDouble(i), bNonNull, i, problemAggregator); + : doDouble(a.getItemAsDouble(i), bNonNull, i, problemAggregator)); context.safepoint(); } - return new DoubleStorage(out, n, isNothing); + return builder.seal(); } @Override - protected LongStorage runLongZip( + protected Storage runLongZip( AbstractLongStorage a, AbstractLongStorage b, MapOperationProblemAggregator problemAggregator) { + long n = a.getSize(); + long m = Math.min(n, b.getSize()); + var builder = Builder.getForLong(IntegerType.INT_64, n, problemAggregator); Context context = Context.getCurrent(); - int n = a.size(); - int m = Math.min(a.size(), b.size()); - long[] out = new long[n]; - BitSet isNothing = new BitSet(); - for (int i = 0; i < m; i++) { + + for (long i = 0; i < n; i++) { boolean aNothing = a.isNothing(i); - boolean bNothing = b.isNothing(i); + boolean bNothing = i >= m || b.isNothing(i); if (aNothing && bNothing) { - isNothing.set(i); + builder.appendNulls(1); } else { if (aNothing) { - out[i] = b.getItem(i); + builder.appendLong(b.getItemAsLong(i)); } else if (bNothing) { - out[i] = a.getItem(i); + builder.appendLong(a.getItemAsLong(i)); } else { - Long r = doLong(a.getItem(i), b.getItem(i), i, problemAggregator); + Long r = doLong(a.getItemAsLong(i), b.getItemAsLong(i), i, problemAggregator); if (r == null) { - isNothing.set(i); + builder.appendNulls(1); } else { - out[i] = r; + builder.appendLong(r); } } } @@ -123,17 +109,7 @@ protected LongStorage runLongZip( context.safepoint(); } - for (int i = m; i < n; ++i) { - if (a.isNothing(i)) { - isNothing.set(i); - } else { - out[i] = a.getItem(i); - } - - context.safepoint(); - } - - return new LongStorage(out, n, isNothing, INTEGER_RESULT_TYPE); + return builder.seal(); } protected Storage runLongMap( @@ -144,130 +120,128 @@ protected Storage runLongMap( long bNonNull = b; Context context = Context.getCurrent(); - int n = a.size(); - long[] out = new long[n]; - BitSet isNothing = new BitSet(); - for (int i = 0; i < n; i++) { + long n = a.getSize(); + var builder = Builder.getForLong(IntegerType.INT_64, n, problemAggregator); + for (long i = 0; i < n; i++) { if (a.isNothing(i)) { - out[i] = bNonNull; + builder.appendLong(bNonNull); } else { - Long r = doLong(a.getItem(i), bNonNull, i, problemAggregator); + Long r = doLong(a.getItemAsLong(i), bNonNull, i, problemAggregator); if (r == null) { - isNothing.set(i); + builder.appendNulls(1); } else { - out[i] = r; + builder.appendLong(r); } } context.safepoint(); } - return new LongStorage(out, n, isNothing, INTEGER_RESULT_TYPE); + return builder.seal(); } - protected BigIntegerStorage runBigIntegerZip( + protected Storage runBigIntegerZip( BigIntegerArrayAdapter a, BigIntegerArrayAdapter b, MapOperationProblemAggregator problemAggregator) { + long n = a.size(); + long m = Math.min(n, b.size()); + var builder = Builder.getForBigInteger(n, problemAggregator); Context context = Context.getCurrent(); - int n = a.size(); - int m = Math.min(a.size(), b.size()); - BigInteger[] out = new BigInteger[n]; - for (int i = 0; i < m; i++) { + + for (long i = 0; i < n; i++) { BigInteger x = a.getItem(i); - BigInteger y = b.getItem(i); + BigInteger y = i >= m ? null : b.getItem(i); if (x == null && y == null) { - out[i] = null; + builder.appendNulls(1); } else { if (x == null) { - out[i] = y; + builder.append(y); } else if (y == null) { - out[i] = x; + builder.append(x); } else { BigInteger r = doBigInteger(x, y, i, problemAggregator); - out[i] = r; + builder.append(r); } } context.safepoint(); } - return new BigIntegerStorage(out, n); + return builder.seal(); } - protected BigIntegerStorage runBigIntegerMap( + protected Storage runBigIntegerMap( BigIntegerArrayAdapter a, BigInteger b, MapOperationProblemAggregator problemAggregator) { if (b == null) { return a.intoStorage(); } Context context = Context.getCurrent(); - int n = a.size(); - BigInteger[] out = new BigInteger[n]; - for (int i = 0; i < n; i++) { + long n = a.size(); + var builder = Builder.getForBigInteger(n, problemAggregator); + for (long i = 0; i < n; i++) { BigInteger x = a.getItem(i); if (x == null) { - out[i] = b; + builder.append(b); } else { - BigInteger r = doBigInteger(x, b, i, problemAggregator); - out[i] = r; + builder.append(doBigInteger(x, b, i, problemAggregator)); } context.safepoint(); } - return new BigIntegerStorage(out, n); + return builder.seal(); } - protected BigDecimalStorage runBigDecimalZip( + protected Storage runBigDecimalZip( BigDecimalArrayAdapter a, BigDecimalArrayAdapter b, MapOperationProblemAggregator problemAggregator) { + long n = a.size(); + long m = Math.min(a.size(), b.size()); + var builder = Builder.getForBigDecimal(n); Context context = Context.getCurrent(); - int n = a.size(); - int m = Math.min(a.size(), b.size()); - BigDecimal[] out = new BigDecimal[n]; - for (int i = 0; i < m; i++) { + + for (long i = 0; i < n; i++) { BigDecimal x = a.getItem(i); - BigDecimal y = b.getItem(i); + BigDecimal y = i >= m ? null : b.getItem(i); if (x == null && y == null) { - out[i] = null; + builder.appendNulls(1); } else { if (x == null) { - out[i] = y; + builder.append(y); } else if (y == null) { - out[i] = x; + builder.append(x); } else { - BigDecimal r = doBigDecimal(x, y, i, problemAggregator); - out[i] = r; + builder.append(doBigDecimal(x, y, i, problemAggregator)); } } context.safepoint(); } - return new BigDecimalStorage(out, n); + return builder.seal(); } - protected SpecializedStorage runBigDecimalMap( + protected Storage runBigDecimalMap( BigDecimalArrayAdapter a, BigDecimal b, MapOperationProblemAggregator problemAggregator) { if (b == null) { return a.intoStorage(); } Context context = Context.getCurrent(); - int n = a.size(); - BigDecimal[] out = new BigDecimal[n]; - for (int i = 0; i < n; i++) { + long n = a.size(); + var builder = Builder.getForBigDecimal(n); + for (long i = 0; i < n; i++) { BigDecimal x = a.getItem(i); if (x == null) { - out[i] = b; + builder.append(b); } else { - BigDecimal r = doBigDecimal(x, b, i, problemAggregator); - out[i] = r; + builder.append(doBigDecimal(x, b, i, problemAggregator)); } context.safepoint(); } - return new BigDecimalStorage(out, n); + return builder.seal(); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpDefinition.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpDefinition.java index d9ff6db9028a..61f63cade6f6 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpDefinition.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpDefinition.java @@ -5,13 +5,13 @@ import org.enso.table.data.column.operation.map.MapOperationProblemAggregator; public interface NumericBinaryOpDefinition { - double doDouble(double a, double b, int ix, MapOperationProblemAggregator problemAggregator); + double doDouble(double a, double b, long ix, MapOperationProblemAggregator problemAggregator); - Long doLong(long a, long b, int ix, MapOperationProblemAggregator problemAggregator); + Long doLong(long a, long b, long ix, MapOperationProblemAggregator problemAggregator); BigInteger doBigInteger( - BigInteger a, BigInteger b, int ix, MapOperationProblemAggregator problemAggregator); + BigInteger a, BigInteger b, long ix, MapOperationProblemAggregator problemAggregator); BigDecimal doBigDecimal( - BigDecimal a, BigDecimal b, int ix, MapOperationProblemAggregator problemAggregator); + BigDecimal a, BigDecimal b, long ix, MapOperationProblemAggregator problemAggregator); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpImplementation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpImplementation.java index c5960adbfb8d..05c7b1a2310c 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpImplementation.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpImplementation.java @@ -1,23 +1,21 @@ package org.enso.table.data.column.operation.map.numeric.arithmetic; -import static org.enso.table.data.column.operation.map.numeric.helpers.DoubleArrayAdapter.fromAnyStorage; - import java.math.BigDecimal; import java.math.BigInteger; -import java.util.BitSet; import org.enso.base.polyglot.NumericConverter; +import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.operation.map.BinaryMapOperation; import org.enso.table.data.column.operation.map.MapOperationProblemAggregator; import org.enso.table.data.column.operation.map.numeric.helpers.BigDecimalArrayAdapter; import org.enso.table.data.column.operation.map.numeric.helpers.BigIntegerArrayAdapter; import org.enso.table.data.column.operation.map.numeric.helpers.DoubleArrayAdapter; -import org.enso.table.data.column.storage.SpecializedStorage; import org.enso.table.data.column.storage.Storage; import org.enso.table.data.column.storage.numeric.AbstractLongStorage; import org.enso.table.data.column.storage.numeric.BigDecimalStorage; import org.enso.table.data.column.storage.numeric.BigIntegerStorage; import org.enso.table.data.column.storage.numeric.DoubleStorage; import org.enso.table.data.column.storage.numeric.LongStorage; +import org.enso.table.data.column.storage.type.FloatType; import org.enso.table.data.column.storage.type.IntegerType; import org.enso.table.error.UnexpectedTypeException; import org.graalvm.polyglot.Context; @@ -46,7 +44,9 @@ public Storage runBinaryMap( case BigIntegerStorage s -> runBigIntegerMap( BigIntegerArrayAdapter.fromStorage(s), rhs, problemAggregator); case BigDecimalStorage s -> runBigDecimalMap( - BigDecimalArrayAdapter.fromStorage(s), new BigDecimal(rhs), problemAggregator); + BigDecimalArrayAdapter.fromBigDecimalStorage(s), + new BigDecimal(rhs), + problemAggregator); case DoubleStorage s -> runDoubleMap(s, rhs.doubleValue(), problemAggregator); default -> throw new IllegalStateException( "Unsupported storage: " + storage.getClass().getCanonicalName()); @@ -60,7 +60,7 @@ public Storage runBinaryMap( BigInteger.valueOf(argAsLong), problemAggregator); case BigDecimalStorage s -> runBigDecimalMap( - BigDecimalArrayAdapter.fromStorage(s), + BigDecimalArrayAdapter.fromBigDecimalStorage(s), BigDecimal.valueOf(argAsLong), problemAggregator); case DoubleStorage s -> runDoubleMap(s, (double) argAsLong, problemAggregator); @@ -73,9 +73,9 @@ public Storage runBinaryMap( case AbstractLongStorage s -> runDoubleMap( DoubleArrayAdapter.fromStorage(s), doubleArg, problemAggregator); case BigIntegerStorage s -> runDoubleMap( - DoubleArrayAdapter.fromStorage(s), doubleArg, problemAggregator); + DoubleArrayAdapter.fromBigIntegerStorage(s), doubleArg, problemAggregator); case BigDecimalStorage s -> runBigDecimalMap( - BigDecimalArrayAdapter.fromStorage(s), + BigDecimalArrayAdapter.fromBigDecimalStorage(s), BigDecimal.valueOf(doubleArg), problemAggregator); case DoubleStorage s -> runDoubleMap(s, doubleArg, problemAggregator); @@ -98,10 +98,10 @@ public Storage runZip( case DoubleStorage lhs -> switch (arg) { case BigDecimalStorage rhs -> { BigDecimalArrayAdapter left = BigDecimalArrayAdapter.fromStorage(lhs); - BigDecimalArrayAdapter right = BigDecimalArrayAdapter.fromStorage(rhs); + BigDecimalArrayAdapter right = BigDecimalArrayAdapter.fromBigDecimalStorage(rhs); yield runBigDecimalZip(left, right, problemAggregator); } - default -> runDoubleZip(lhs, fromAnyStorage(arg), problemAggregator); + default -> runDoubleZip(lhs, DoubleArrayAdapter.fromAnyStorage(arg), problemAggregator); }; case AbstractLongStorage lhs -> switch (arg) { @@ -115,7 +115,7 @@ public Storage runZip( DoubleArrayAdapter.fromStorage(lhs), rhs, problemAggregator); case BigDecimalStorage rhs -> { BigDecimalArrayAdapter left = BigDecimalArrayAdapter.fromStorage(lhs); - BigDecimalArrayAdapter right = BigDecimalArrayAdapter.fromStorage(rhs); + BigDecimalArrayAdapter right = BigDecimalArrayAdapter.fromBigDecimalStorage(rhs); yield runBigDecimalZip(left, right, problemAggregator); } default -> throw new IllegalStateException( @@ -135,10 +135,10 @@ yield switch (arg) { yield runBigIntegerZip(left, right, problemAggregator); } case DoubleStorage rhs -> runDoubleZip( - DoubleArrayAdapter.fromStorage(lhs), rhs, problemAggregator); + DoubleArrayAdapter.fromBigIntegerStorage(lhs), rhs, problemAggregator); case BigDecimalStorage rhs -> { - BigDecimalArrayAdapter left = BigDecimalArrayAdapter.fromStorage(lhs); - BigDecimalArrayAdapter right = BigDecimalArrayAdapter.fromStorage(rhs); + BigDecimalArrayAdapter left = BigDecimalArrayAdapter.fromBigIntegerStorage(lhs); + BigDecimalArrayAdapter right = BigDecimalArrayAdapter.fromBigDecimalStorage(rhs); yield runBigDecimalZip(left, right, problemAggregator); } default -> throw new IllegalStateException( @@ -147,7 +147,7 @@ yield switch (arg) { } case BigDecimalStorage lhs -> { - BigDecimalArrayAdapter left = BigDecimalArrayAdapter.fromStorage(lhs); + BigDecimalArrayAdapter left = BigDecimalArrayAdapter.fromBigDecimalStorage(lhs); BigDecimalArrayAdapter right = BigDecimalArrayAdapter.fromAnyStorage(arg); yield runBigDecimalZip(left, right, problemAggregator); } @@ -157,41 +157,40 @@ yield switch (arg) { }; } - protected DoubleStorage runDoubleZip( + protected Storage runDoubleZip( DoubleArrayAdapter a, DoubleArrayAdapter b, MapOperationProblemAggregator problemAggregator) { Context context = Context.getCurrent(); - int n = a.size(); - int m = Math.min(a.size(), b.size()); - double[] out = new double[n]; - BitSet isNothing = new BitSet(); - for (int i = 0; i < m; i++) { + long n = a.size(); + long m = Math.min(n, b.size()); + var builder = Builder.getForDouble(FloatType.FLOAT_64, n, problemAggregator); + for (long i = 0; i < m; i++) { if (a.isNothing(i) || b.isNothing(i)) { - isNothing.set(i); + builder.appendNulls(1); } else { - out[i] = doDouble(a.getItemAsDouble(i), b.getItemAsDouble(i), i, problemAggregator); + builder.append(doDouble(a.getItemAsDouble(i), b.getItemAsDouble(i), i, problemAggregator)); } context.safepoint(); } if (m < n) { - isNothing.set(m, n); + builder.appendNulls(Math.toIntExact(n - m)); } - return new DoubleStorage(out, n, isNothing); + return builder.seal(); } private static Storage allNullStorageOfSameType(Storage storage) { return switch (storage) { - case AbstractLongStorage s -> LongStorage.makeEmpty(storage.size(), INTEGER_RESULT_TYPE); - case BigIntegerStorage s -> BigIntegerStorage.makeEmpty(storage.size()); - case DoubleStorage s -> DoubleStorage.makeEmpty(storage.size()); + case AbstractLongStorage s -> LongStorage.makeEmpty(storage.getSize(), INTEGER_RESULT_TYPE); + case BigIntegerStorage s -> BigIntegerStorage.makeEmpty(storage.getSize()); + case DoubleStorage s -> DoubleStorage.makeEmpty(storage.getSize()); default -> throw new IllegalStateException( "Unsupported storage: " + storage.getClass().getCanonicalName()); }; } - protected DoubleStorage runDoubleMap( + protected Storage runDoubleMap( DoubleArrayAdapter a, Double b, MapOperationProblemAggregator problemAggregator) { if (b == null) { return DoubleStorage.makeEmpty(a.size()); @@ -199,161 +198,159 @@ protected DoubleStorage runDoubleMap( double bNonNull = b; Context context = Context.getCurrent(); - int n = a.size(); - double[] out = new double[n]; - BitSet isNothing = new BitSet(); - for (int i = 0; i < n; i++) { + long n = a.size(); + var builder = Builder.getForDouble(FloatType.FLOAT_64, n, problemAggregator); + for (long i = 0; i < n; i++) { if (a.isNothing(i)) { - isNothing.set(i); + builder.appendNulls(1); } else { - out[i] = doDouble(a.getItemAsDouble(i), bNonNull, i, problemAggregator); + builder.appendDouble(doDouble(a.getItemAsDouble(i), bNonNull, i, problemAggregator)); } context.safepoint(); } - return new DoubleStorage(out, n, isNothing); + return builder.seal(); } - protected LongStorage runLongZip( + protected Storage runLongZip( AbstractLongStorage a, AbstractLongStorage b, MapOperationProblemAggregator problemAggregator) { Context context = Context.getCurrent(); - int n = a.size(); - int m = Math.min(a.size(), b.size()); - long[] out = new long[n]; - BitSet isNothing = new BitSet(); - for (int i = 0; i < m; i++) { - if (a.isNothing(i) || b.isNothing(i)) { - isNothing.set(i); + long n = a.getSize(); + long m = Math.min(n, b.getSize()); + var builder = Builder.getForLong(INTEGER_RESULT_TYPE, n, problemAggregator); + for (long i = 0; i < n; i++) { + if (a.isNothing(i) || i >= m || b.isNothing(i)) { + builder.appendNulls(1); } else { - Long r = doLong(a.getItem(i), b.getItem(i), i, problemAggregator); + Long r = doLong(a.getItemAsLong(i), b.getItemAsLong(i), i, problemAggregator); if (r == null) { - isNothing.set(i); + builder.appendNulls(1); } else { - out[i] = r; + builder.appendLong(r); } } context.safepoint(); } - if (m < n) { - isNothing.set(m, n); - } - - return new LongStorage(out, n, isNothing, INTEGER_RESULT_TYPE); + return builder.seal(); } protected Storage runLongMap( AbstractLongStorage a, Long b, MapOperationProblemAggregator problemAggregator) { if (b == null) { - return LongStorage.makeEmpty(a.size(), INTEGER_RESULT_TYPE); + return LongStorage.makeEmpty(a.getSize(), INTEGER_RESULT_TYPE); } long bNonNull = b; Context context = Context.getCurrent(); - int n = a.size(); - long[] out = new long[n]; - BitSet isNothing = new BitSet(); - for (int i = 0; i < n; i++) { + long n = a.getSize(); + var builder = Builder.getForLong(INTEGER_RESULT_TYPE, n, problemAggregator); + for (long i = 0; i < n; i++) { if (a.isNothing(i)) { - isNothing.set(i); + builder.appendNulls(1); } else { - Long r = doLong(a.getItem(i), bNonNull, i, problemAggregator); + Long r = doLong(a.getItemAsLong(i), bNonNull, i, problemAggregator); if (r == null) { - isNothing.set(i); + builder.appendNulls(1); } else { - out[i] = r; + builder.appendLong(r); } } context.safepoint(); } - return new LongStorage(out, n, isNothing, INTEGER_RESULT_TYPE); + return builder.seal(); } - protected BigIntegerStorage runBigIntegerZip( + protected Storage runBigIntegerZip( BigIntegerArrayAdapter a, BigIntegerArrayAdapter b, MapOperationProblemAggregator problemAggregator) { Context context = Context.getCurrent(); - int n = a.size(); - int m = Math.min(a.size(), b.size()); - BigInteger[] out = new BigInteger[n]; - for (int i = 0; i < m; i++) { + long n = a.size(); + long m = Math.min(n, b.size()); + var builder = Builder.getForBigInteger(n, problemAggregator); + for (long i = 0; i < m; i++) { BigInteger x = a.getItem(i); BigInteger y = b.getItem(i); if (x != null && y != null) { - BigInteger r = doBigInteger(x, y, i, problemAggregator); - out[i] = r; + builder.append(doBigInteger(x, y, i, problemAggregator)); + } else { + builder.appendNulls(1); } context.safepoint(); } - return new BigIntegerStorage(out, n); + if (m < n) { + builder.appendNulls(Math.toIntExact(n - m)); + } + + return builder.seal(); } - protected BigIntegerStorage runBigIntegerMap( + protected Storage runBigIntegerMap( BigIntegerArrayAdapter a, BigInteger b, MapOperationProblemAggregator problemAggregator) { Context context = Context.getCurrent(); - int n = a.size(); - BigInteger[] out = new BigInteger[n]; - for (int i = 0; i < n; i++) { + long n = a.size(); + var builder = Builder.getForBigInteger(n, problemAggregator); + for (long i = 0; i < n; i++) { BigInteger x = a.getItem(i); if (x == null || b == null) { - out[i] = null; + builder.appendNulls(1); } else { - BigInteger r = doBigInteger(x, b, i, problemAggregator); - out[i] = r; + builder.append(doBigInteger(x, b, i, problemAggregator)); } context.safepoint(); } - return new BigIntegerStorage(out, n); + return builder.seal(); } - protected BigDecimalStorage runBigDecimalZip( + protected Storage runBigDecimalZip( BigDecimalArrayAdapter a, BigDecimalArrayAdapter b, MapOperationProblemAggregator problemAggregator) { Context context = Context.getCurrent(); - int n = a.size(); - int m = Math.min(a.size(), b.size()); - BigDecimal[] out = new BigDecimal[n]; - for (int i = 0; i < m; i++) { + long n = a.size(); + long m = Math.min(a.size(), b.size()); + var builder = Builder.getForBigDecimal(n); + for (long i = 0; i < n; i++) { BigDecimal x = a.getItem(i); - BigDecimal y = b.getItem(i); + BigDecimal y = i >= m ? null : b.getItem(i); if (x != null && y != null) { - BigDecimal r = doBigDecimal(x, y, i, problemAggregator); - out[i] = r; + builder.append(doBigDecimal(x, y, i, problemAggregator)); + } else { + builder.appendNulls(1); } context.safepoint(); } - return new BigDecimalStorage(out, n); + return builder.seal(); } - protected SpecializedStorage runBigDecimalMap( + protected Storage runBigDecimalMap( BigDecimalArrayAdapter a, BigDecimal b, MapOperationProblemAggregator problemAggregator) { Context context = Context.getCurrent(); - int n = a.size(); - BigDecimal[] out = new BigDecimal[n]; - for (int i = 0; i < n; i++) { + long n = a.size(); + var builder = Builder.getForBigDecimal(n); + + for (long i = 0; i < n; i++) { BigDecimal x = a.getItem(i); if (x == null || b == null) { - out[i] = null; + builder.appendNulls(1); } else { - BigDecimal r = doBigDecimal(x, b, i, problemAggregator); - out[i] = r; + builder.append(doBigDecimal(x, b, i, problemAggregator)); } context.safepoint(); } - return new BigDecimalStorage(out, n); + return builder.seal(); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpReturningBigDecimal.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpReturningBigDecimal.java index cec24ce3687d..4dad49cb2829 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpReturningBigDecimal.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpReturningBigDecimal.java @@ -1,7 +1,5 @@ package org.enso.table.data.column.operation.map.numeric.arithmetic; -import static org.enso.table.data.column.operation.map.numeric.helpers.BigDecimalArrayAdapter.fromAnyStorage; - import java.math.BigDecimal; import java.math.BigInteger; import org.enso.base.polyglot.NumericConverter; @@ -21,10 +19,10 @@ public NumericBinaryOpReturningBigDecimal(String name) { public Storage runBinaryMap( I storage, Object arg, MapOperationProblemAggregator problemAggregator) { if (arg == null) { - return BigDecimalStorage.makeEmpty(storage.size()); + return BigDecimalStorage.makeEmpty(storage.getSize()); } - BigDecimalArrayAdapter lhs = fromAnyStorage(storage); + BigDecimalArrayAdapter lhs = BigDecimalArrayAdapter.fromAnyStorage(storage); BigDecimal rhs = NumericConverter.coerceToBigDecimal(arg); return runBigDecimalMap(lhs, rhs, problemAggregator); } @@ -38,7 +36,7 @@ public Storage runZip( } @Override - public Long doLong(long a, long b, int ix, MapOperationProblemAggregator problemAggregator) { + public Long doLong(long a, long b, long ix, MapOperationProblemAggregator problemAggregator) { throw new IllegalStateException( "Impossible: should not reach here - a NumericOpReturningBigDecimal should always use the" + " doBigDecimal branch."); @@ -46,7 +44,7 @@ public Long doLong(long a, long b, int ix, MapOperationProblemAggregator problem @Override public BigInteger doBigInteger( - BigInteger a, BigInteger b, int ix, MapOperationProblemAggregator problemAggregator) { + BigInteger a, BigInteger b, long ix, MapOperationProblemAggregator problemAggregator) { throw new IllegalStateException( "Impossible: should not reach here - a NumericOpReturningBigDecimal should always use the" + " doBigDecimal branch."); @@ -54,7 +52,7 @@ public BigInteger doBigInteger( @Override public double doDouble( - double a, double b, int ix, MapOperationProblemAggregator problemAggregator) { + double a, double b, long ix, MapOperationProblemAggregator problemAggregator) { throw new IllegalStateException( "Impossible: should not reach here - a NumericOpReturningBigDecimal should always use the" + " doBigDecimal branch."); diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpReturningDouble.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpReturningDouble.java index d256a9a58a85..8639915cba8c 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpReturningDouble.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpReturningDouble.java @@ -1,7 +1,5 @@ package org.enso.table.data.column.operation.map.numeric.arithmetic; -import static org.enso.table.data.column.operation.map.numeric.helpers.DoubleArrayAdapter.fromAnyStorage; - import java.math.BigDecimal; import java.math.BigInteger; import org.enso.base.polyglot.NumericConverter; @@ -20,10 +18,10 @@ public NumericBinaryOpReturningDouble(String name) { public Storage runBinaryMap( I storage, Object arg, MapOperationProblemAggregator problemAggregator) { if (arg == null) { - return DoubleStorage.makeEmpty(storage.size()); + return DoubleStorage.makeEmpty(storage.getSize()); } - DoubleArrayAdapter lhs = fromAnyStorage(storage); + DoubleArrayAdapter lhs = DoubleArrayAdapter.fromAnyStorage(storage); double rhs = (arg instanceof BigInteger bigInteger) ? bigInteger.doubleValue() @@ -34,13 +32,13 @@ public Storage runBinaryMap( @Override public Storage runZip( I storage, Storage arg, MapOperationProblemAggregator problemAggregator) { - DoubleArrayAdapter lhs = fromAnyStorage(storage); - DoubleArrayAdapter rhs = fromAnyStorage(arg); + DoubleArrayAdapter lhs = DoubleArrayAdapter.fromAnyStorage(storage); + DoubleArrayAdapter rhs = DoubleArrayAdapter.fromAnyStorage(arg); return runDoubleZip(lhs, rhs, problemAggregator); } @Override - public Long doLong(long a, long b, int ix, MapOperationProblemAggregator problemAggregator) { + public Long doLong(long a, long b, long ix, MapOperationProblemAggregator problemAggregator) { throw new IllegalStateException( "Impossible: should not reach here - a NumericOpReturningDouble should always use the" + " doDouble branch."); @@ -48,7 +46,7 @@ public Long doLong(long a, long b, int ix, MapOperationProblemAggregator problem @Override public BigInteger doBigInteger( - BigInteger a, BigInteger b, int ix, MapOperationProblemAggregator problemAggregator) { + BigInteger a, BigInteger b, long ix, MapOperationProblemAggregator problemAggregator) { throw new IllegalStateException( "Impossible: should not reach here - a NumericOpReturningDouble should always use the" + " doDouble branch."); @@ -56,7 +54,7 @@ public BigInteger doBigInteger( @Override public BigDecimal doBigDecimal( - BigDecimal a, BigDecimal b, int ix, MapOperationProblemAggregator problemAggregator) { + BigDecimal a, BigDecimal b, long ix, MapOperationProblemAggregator problemAggregator) { throw new IllegalStateException( "Impossible: should not reach here - a NumericOpReturningDouble should always use the" + " doDouble branch."); diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/PowerOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/PowerOp.java index a2ff5851d043..ddc1ed19cae1 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/PowerOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/PowerOp.java @@ -11,7 +11,7 @@ public PowerOp() { @Override public double doDouble( - double a, double b, int ix, MapOperationProblemAggregator problemAggregator) { + double a, double b, long ix, MapOperationProblemAggregator problemAggregator) { return Math.pow(a, b); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/SubOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/SubOp.java index d00712e8a2c5..d5c405446515 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/SubOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/SubOp.java @@ -14,12 +14,12 @@ public SubOp() { @Override public double doDouble( - double a, double b, int ix, MapOperationProblemAggregator problemAggregator) { + double a, double b, long ix, MapOperationProblemAggregator problemAggregator) { return a - b; } @Override - public Long doLong(long a, long b, int ix, MapOperationProblemAggregator problemAggregator) { + public Long doLong(long a, long b, long ix, MapOperationProblemAggregator problemAggregator) { try { return Math.subtractExact(a, b); } catch (ArithmeticException e) { @@ -30,13 +30,13 @@ public Long doLong(long a, long b, int ix, MapOperationProblemAggregator problem @Override public BigInteger doBigInteger( - BigInteger a, BigInteger b, int ix, MapOperationProblemAggregator problemAggregator) { + BigInteger a, BigInteger b, long ix, MapOperationProblemAggregator problemAggregator) { return a.subtract(b); } @Override public BigDecimal doBigDecimal( - BigDecimal a, BigDecimal b, int ix, MapOperationProblemAggregator problemAggregator) { + BigDecimal a, BigDecimal b, long ix, MapOperationProblemAggregator problemAggregator) { return a.subtract(b); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/comparisons/EqualsComparison.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/comparisons/EqualsComparison.java index c423041e6a8e..2d306c00b9b3 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/comparisons/EqualsComparison.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/comparisons/EqualsComparison.java @@ -4,7 +4,6 @@ import java.math.BigInteger; import org.enso.table.data.column.operation.map.MapOperationProblemAggregator; import org.enso.table.data.column.operation.map.numeric.helpers.DoubleArrayAdapter; -import org.enso.table.data.column.storage.BoolStorage; import org.enso.table.data.column.storage.Storage; public class EqualsComparison> @@ -19,14 +18,14 @@ protected boolean doDouble(double a, double b) { } @Override - protected BoolStorage runDoubleMap( + protected Storage runDoubleMap( DoubleArrayAdapter lhs, double rhs, MapOperationProblemAggregator problemAggregator) { problemAggregator.reportFloatingPointEquality(-1); return super.runDoubleMap(lhs, rhs, problemAggregator); } @Override - protected BoolStorage runDoubleZip( + protected Storage runDoubleZip( DoubleArrayAdapter lhs, DoubleArrayAdapter rhs, MapOperationProblemAggregator problemAggregator) { diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/comparisons/NumericComparison.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/comparisons/NumericComparison.java index 08283b778018..7f78ec323647 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/comparisons/NumericComparison.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/comparisons/NumericComparison.java @@ -1,12 +1,10 @@ package org.enso.table.data.column.operation.map.numeric.comparisons; -import static org.enso.table.data.column.operation.map.numeric.helpers.DoubleArrayAdapter.fromAnyStorage; - import java.math.BigDecimal; import java.math.BigInteger; -import java.util.BitSet; import org.enso.base.CompareException; import org.enso.base.polyglot.NumericConverter; +import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.operation.map.BinaryMapOperation; import org.enso.table.data.column.operation.map.MapOperationProblemAggregator; import org.enso.table.data.column.operation.map.numeric.helpers.BigDecimalArrayAdapter; @@ -19,7 +17,6 @@ import org.enso.table.data.column.storage.numeric.BigIntegerStorage; import org.enso.table.data.column.storage.numeric.DoubleStorage; import org.enso.table.data.column.storage.type.AnyObjectType; -import org.enso.table.util.BitSets; import org.graalvm.polyglot.Context; public abstract class NumericComparison> @@ -42,10 +39,10 @@ public NumericComparison(String name) { } @Override - public BoolStorage runBinaryMap( + public Storage runBinaryMap( I storage, Object arg, MapOperationProblemAggregator problemAggregator) { if (arg == null) { - return BoolStorage.makeEmpty(storage.size()); + return BoolStorage.makeEmpty(storage.getSize()); } else if (arg instanceof BigInteger bigInteger) { return switch (storage) { case AbstractLongStorage s -> runBigIntegerMap( @@ -53,7 +50,9 @@ public BoolStorage runBinaryMap( case BigIntegerStorage s -> runBigIntegerMap( BigIntegerArrayAdapter.fromStorage(s), bigInteger, problemAggregator); case BigDecimalStorage s -> runBigDecimalMap( - BigDecimalArrayAdapter.fromStorage(s), new BigDecimal(bigInteger), problemAggregator); + BigDecimalArrayAdapter.fromBigDecimalStorage(s), + new BigDecimal(bigInteger), + problemAggregator); case DoubleStorage s -> runDoubleMap(s, bigInteger.doubleValue(), problemAggregator); default -> throw new IllegalStateException( "Unsupported lhs storage: " + storage.getClass().getCanonicalName()); @@ -63,9 +62,9 @@ public BoolStorage runBinaryMap( case AbstractLongStorage s -> runBigDecimalMap( BigDecimalArrayAdapter.fromStorage(s), bigDecimal, problemAggregator); case BigIntegerStorage s -> runBigDecimalMap( - BigDecimalArrayAdapter.fromStorage(s), bigDecimal, problemAggregator); + BigDecimalArrayAdapter.fromBigIntegerStorage(s), bigDecimal, problemAggregator); case BigDecimalStorage s -> runBigDecimalMap( - BigDecimalArrayAdapter.fromStorage(s), bigDecimal, problemAggregator); + BigDecimalArrayAdapter.fromBigDecimalStorage(s), bigDecimal, problemAggregator); case DoubleStorage s -> runBigDecimalMap( BigDecimalArrayAdapter.fromStorage(s), bigDecimal, problemAggregator); default -> throw new IllegalStateException( @@ -78,7 +77,9 @@ public BoolStorage runBinaryMap( case BigIntegerStorage s -> runBigIntegerMap( BigIntegerArrayAdapter.fromStorage(s), BigInteger.valueOf(rhs), problemAggregator); case BigDecimalStorage s -> runBigDecimalMap( - BigDecimalArrayAdapter.fromStorage(s), BigDecimal.valueOf(rhs), problemAggregator); + BigDecimalArrayAdapter.fromBigDecimalStorage(s), + BigDecimal.valueOf(rhs), + problemAggregator); case DoubleStorage s -> runDoubleMap(s, (double) rhs, problemAggregator); default -> throw new IllegalStateException( "Unsupported lhs storage: " + storage.getClass().getCanonicalName()); @@ -87,144 +88,128 @@ public BoolStorage runBinaryMap( double rhs = NumericConverter.coerceToDouble(arg); return switch (storage) { case BigDecimalStorage s -> runBigDecimalMap( - BigDecimalArrayAdapter.fromStorage(s), BigDecimal.valueOf(rhs), problemAggregator); + BigDecimalArrayAdapter.fromBigDecimalStorage(s), + BigDecimal.valueOf(rhs), + problemAggregator); default -> { DoubleArrayAdapter lhs = DoubleArrayAdapter.fromAnyStorage(storage); yield runDoubleMap(lhs, rhs, problemAggregator); } }; } else { - int n = storage.size(); - BitSet isNothing = new BitSet(); - BitSet comparisonResults = new BitSet(); + long n = storage.getSize(); + var builder = Builder.getForBoolean(n); Context context = Context.getCurrent(); for (int i = 0; i < n; ++i) { Object item = storage.getItemBoxed(i); if (item == null) { - isNothing.set(i); + builder.appendNulls(1); } else { boolean r = onOtherType(item, arg); - if (r) { - comparisonResults.set(i); - } + builder.appendBoolean(r); } context.safepoint(); } - return new BoolStorage(comparisonResults, isNothing, n, false); + return builder.seal(); } } - protected BoolStorage runLongMap( + protected Storage runLongMap( AbstractLongStorage lhs, long rhs, MapOperationProblemAggregator problemAggregator) { - int n = lhs.size(); - BitSet comparisonResults = new BitSet(); - BitSet isNothing = BitSets.makeDuplicate(lhs.getIsNothingMap()); + long n = lhs.getSize(); Context context = Context.getCurrent(); - for (int i = 0; i < n; ++i) { - if (!lhs.isNothing(i)) { - long item = lhs.getItem(i); + var builder = Builder.getForBoolean(n); + for (long i = 0; i < n; ++i) { + if (lhs.isNothing(i)) { + builder.appendNulls(1); + } else { + long item = lhs.getItemAsLong(i); boolean r = doLong(item, rhs); - if (r) { - comparisonResults.set(i); - } + builder.appendBoolean(r); } context.safepoint(); } - return new BoolStorage(comparisonResults, isNothing, n, false); + return builder.seal(); } - protected BoolStorage runDoubleMap( + protected Storage runDoubleMap( DoubleArrayAdapter lhs, double rhs, MapOperationProblemAggregator problemAggregator) { - int n = lhs.size(); - BitSet comparisonResults = new BitSet(); - BitSet isNothing = new BitSet(); + long n = lhs.size(); + var builder = Builder.getForBoolean(n); Context context = Context.getCurrent(); - for (int i = 0; i < n; ++i) { + for (long i = 0; i < n; ++i) { if (lhs.isNothing(i)) { - isNothing.set(i); + builder.appendNulls(1); } else { double item = lhs.getItemAsDouble(i); boolean r = doDouble(item, rhs); - if (r) { - comparisonResults.set(i); - } + builder.appendBoolean(r); } context.safepoint(); } - return new BoolStorage(comparisonResults, isNothing, n, false); + return builder.seal(); } - protected BoolStorage runBigIntegerMap( + protected Storage runBigIntegerMap( BigIntegerArrayAdapter lhs, BigInteger rhs, MapOperationProblemAggregator problemAggregator) { - int n = lhs.size(); - BitSet comparisonResults = new BitSet(); - BitSet isNothing = new BitSet(); + long n = lhs.size(); + var builder = Builder.getForBoolean(n); Context context = Context.getCurrent(); - for (int i = 0; i < n; ++i) { + for (long i = 0; i < n; ++i) { BigInteger item = lhs.getItem(i); if (item == null) { - isNothing.set(i); + builder.appendNulls(1); } else { boolean r = doBigInteger(item, rhs); - if (r) { - comparisonResults.set(i); - } + builder.appendBoolean(r); } - context.safepoint(); } - - return new BoolStorage(comparisonResults, isNothing, n, false); + return builder.seal(); } - protected BoolStorage runBigDecimalMap( + protected Storage runBigDecimalMap( BigDecimalArrayAdapter lhs, BigDecimal rhs, MapOperationProblemAggregator problemAggregator) { - int n = lhs.size(); - BitSet comparisonResults = new BitSet(); - BitSet isNothing = new BitSet(); + long n = lhs.size(); + var builder = Builder.getForBoolean(n); Context context = Context.getCurrent(); for (int i = 0; i < n; ++i) { BigDecimal item = lhs.getItem(i); if (item == null) { - isNothing.set(i); + builder.appendNulls(1); } else { - boolean r = doBigDecimal(item, rhs); - if (r) { - comparisonResults.set(i); - } + builder.append(doBigDecimal(item, rhs)); } context.safepoint(); } - return new BoolStorage(comparisonResults, isNothing, n, false); + return builder.seal(); } @Override - public BoolStorage runZip( + public Storage runZip( I storage, Storage arg, MapOperationProblemAggregator problemAggregator) { return switch (storage) { - case DoubleStorage lhs -> { - yield switch (arg) { - case BigDecimalStorage rhs -> runBigDecimalZip( - BigDecimalArrayAdapter.fromStorage(lhs), - BigDecimalArrayAdapter.fromStorage(rhs), - problemAggregator); - default -> { - if (arg.getType() instanceof AnyObjectType) { - yield runMixedZip(lhs, arg, problemAggregator); - } else { - yield runDoubleZip(lhs, fromAnyStorage(arg), problemAggregator); - } + case DoubleStorage lhs -> switch (arg) { + case BigDecimalStorage rhs -> runBigDecimalZip( + BigDecimalArrayAdapter.fromStorage(lhs), + BigDecimalArrayAdapter.fromBigDecimalStorage(rhs), + problemAggregator); + default -> { + if (arg.getType() instanceof AnyObjectType) { + yield runMixedZip(lhs, arg, problemAggregator); + } else { + yield runDoubleZip(lhs, DoubleArrayAdapter.fromAnyStorage(arg), problemAggregator); } - }; - } + } + }; case AbstractLongStorage lhs -> switch (arg) { case AbstractLongStorage rhs -> runLongZip(lhs, rhs, problemAggregator); @@ -235,34 +220,32 @@ yield switch (arg) { } case BigDecimalStorage rhs -> runBigDecimalZip( BigDecimalArrayAdapter.fromStorage(lhs), - BigDecimalArrayAdapter.fromStorage(rhs), + BigDecimalArrayAdapter.fromBigDecimalStorage(rhs), problemAggregator); case DoubleStorage rhs -> runDoubleZip( DoubleArrayAdapter.fromStorage(lhs), rhs, problemAggregator); default -> runMixedZip(lhs, arg, problemAggregator); }; - case BigIntegerStorage lhs -> { - yield switch (arg) { - case AbstractLongStorage rhs -> { - BigIntegerArrayAdapter left = BigIntegerArrayAdapter.fromStorage(lhs); - BigIntegerArrayAdapter right = BigIntegerArrayAdapter.fromStorage(rhs); - yield runBigIntegerZip(left, right, problemAggregator); - } - case BigIntegerStorage rhs -> { - BigIntegerArrayAdapter left = BigIntegerArrayAdapter.fromStorage(lhs); - BigIntegerArrayAdapter right = BigIntegerArrayAdapter.fromStorage(rhs); - yield runBigIntegerZip(left, right, problemAggregator); - } - case BigDecimalStorage rhs -> runBigDecimalZip( - BigDecimalArrayAdapter.fromStorage(lhs), - BigDecimalArrayAdapter.fromStorage(rhs), - problemAggregator); - case DoubleStorage rhs -> runDoubleZip( - DoubleArrayAdapter.fromStorage(lhs), rhs, problemAggregator); - default -> runMixedZip(lhs, arg, problemAggregator); - }; - } + case BigIntegerStorage lhs -> switch (arg) { + case AbstractLongStorage rhs -> { + BigIntegerArrayAdapter left = BigIntegerArrayAdapter.fromStorage(lhs); + BigIntegerArrayAdapter right = BigIntegerArrayAdapter.fromStorage(rhs); + yield runBigIntegerZip(left, right, problemAggregator); + } + case BigIntegerStorage rhs -> { + BigIntegerArrayAdapter left = BigIntegerArrayAdapter.fromStorage(lhs); + BigIntegerArrayAdapter right = BigIntegerArrayAdapter.fromStorage(rhs); + yield runBigIntegerZip(left, right, problemAggregator); + } + case BigDecimalStorage rhs -> runBigDecimalZip( + BigDecimalArrayAdapter.fromBigIntegerStorage(lhs), + BigDecimalArrayAdapter.fromBigDecimalStorage(rhs), + problemAggregator); + case DoubleStorage rhs -> runDoubleZip( + DoubleArrayAdapter.fromBigIntegerStorage(lhs), rhs, problemAggregator); + default -> runMixedZip(lhs, arg, problemAggregator); + }; case BigDecimalStorage lhs -> { if (arg instanceof AbstractLongStorage @@ -282,144 +265,114 @@ yield switch (arg) { }; } - protected BoolStorage runLongZip( + protected Storage runLongZip( AbstractLongStorage lhs, AbstractLongStorage rhs, MapOperationProblemAggregator problemAggregator) { - int n = lhs.size(); - int m = Math.min(lhs.size(), rhs.size()); - BitSet comparisonResults = new BitSet(); - BitSet isNothing = new BitSet(); + long n = lhs.getSize(); + long m = Math.min(n, rhs.getSize()); + var builder = Builder.getForBoolean(n); Context context = Context.getCurrent(); - for (int i = 0; i < m; ++i) { - if (lhs.isNothing(i) || rhs.isNothing(i)) { - isNothing.set(i); + for (long i = 0; i < n; ++i) { + if (lhs.isNothing(i) || (i >= m || rhs.isNothing(i))) { + builder.appendNulls(1); } else { - long x = lhs.getItem(i); - long y = rhs.getItem(i); + long x = lhs.getItemAsLong(i); + long y = rhs.getItemAsLong(i); boolean r = doLong(x, y); - if (r) { - comparisonResults.set(i); - } + builder.appendBoolean(r); } context.safepoint(); } - if (m < n) { - isNothing.set(m, n); - } - - return new BoolStorage(comparisonResults, isNothing, n, false); + return builder.seal(); } - protected BoolStorage runDoubleZip( + protected Storage runDoubleZip( DoubleArrayAdapter lhs, DoubleArrayAdapter rhs, MapOperationProblemAggregator problemAggregator) { - int n = lhs.size(); - int m = Math.min(lhs.size(), rhs.size()); - BitSet comparisonResults = new BitSet(); - BitSet isNothing = new BitSet(); + long n = lhs.size(); + long m = Math.min(n, rhs.size()); + var builder = Builder.getForBoolean(n); Context context = Context.getCurrent(); - for (int i = 0; i < m; ++i) { - if (lhs.isNothing(i) || rhs.isNothing(i)) { - isNothing.set(i); + for (long i = 0; i < n; ++i) { + if (lhs.isNothing(i) || (i >= m || rhs.isNothing(i))) { + builder.appendNulls(1); } else { double x = lhs.getItemAsDouble(i); double y = rhs.getItemAsDouble(i); boolean r = doDouble(x, y); - if (r) { - comparisonResults.set(i); - } + builder.appendBoolean(r); } context.safepoint(); } - if (m < n) { - isNothing.set(m, n); - } - - return new BoolStorage(comparisonResults, isNothing, n, false); + return builder.seal(); } - protected BoolStorage runBigIntegerZip( + protected Storage runBigIntegerZip( BigIntegerArrayAdapter lhs, BigIntegerArrayAdapter rhs, MapOperationProblemAggregator problemAggregator) { - int n = lhs.size(); - int m = Math.min(lhs.size(), rhs.size()); - BitSet comparisonResults = new BitSet(); - BitSet isNothing = new BitSet(); + long n = lhs.size(); + long m = Math.min(n, rhs.size()); + var builder = Builder.getForBoolean(n); Context context = Context.getCurrent(); - for (int i = 0; i < m; ++i) { + for (long i = 0; i < n; ++i) { BigInteger x = lhs.getItem(i); - BigInteger y = rhs.getItem(i); + BigInteger y = i >= m ? null : rhs.getItem(i); if (x == null || y == null) { - isNothing.set(i); + builder.appendNulls(1); } else { boolean r = doBigInteger(x, y); - if (r) { - comparisonResults.set(i); - } + builder.appendBoolean(r); } context.safepoint(); } - if (m < n) { - isNothing.set(m, n); - } - - return new BoolStorage(comparisonResults, isNothing, n, false); + return builder.seal(); } - protected BoolStorage runBigDecimalZip( + protected Storage runBigDecimalZip( BigDecimalArrayAdapter lhs, BigDecimalArrayAdapter rhs, MapOperationProblemAggregator problemAggregator) { - int n = lhs.size(); - int m = Math.min(lhs.size(), rhs.size()); - BitSet comparisonResults = new BitSet(); - BitSet isNothing = new BitSet(); + long n = lhs.size(); + long m = Math.min(n, rhs.size()); + var builder = Builder.getForBoolean(n); Context context = Context.getCurrent(); - for (int i = 0; i < m; ++i) { + for (int i = 0; i < n; ++i) { BigDecimal x = lhs.getItem(i); - BigDecimal y = rhs.getItem(i); + BigDecimal y = i >= m ? null : rhs.getItem(i); if (x == null || y == null) { - isNothing.set(i); + builder.appendNulls(1); } else { - boolean r = doBigDecimal(x, y); - if (r) { - comparisonResults.set(i); - } + builder.appendBoolean(doBigDecimal(x, y)); } context.safepoint(); } - if (m < n) { - isNothing.set(m, n); - } - - return new BoolStorage(comparisonResults, isNothing, n, false); + return builder.seal(); } - protected BoolStorage runMixedZip( + protected Storage runMixedZip( Storage lhs, Storage rhs, MapOperationProblemAggregator problemAggregator) { - int n = lhs.size(); - int m = Math.min(lhs.size(), rhs.size()); - BitSet comparisonResults = new BitSet(); - BitSet isNothing = new BitSet(); + long n = lhs.getSize(); + long m = Math.min(n, rhs.getSize()); + var builder = Builder.getForBoolean(n); Context context = Context.getCurrent(); - for (int i = 0; i < m; ++i) { + for (long i = 0; i < n; ++i) { Object x = lhs.getItemBoxed(i); - Object y = rhs.getItemBoxed(i); + Object y = i >= m ? null : rhs.getItemBoxed(i); if (x == null || y == null) { - isNothing.set(i); + builder.appendNulls(1); } else { - boolean r = false; + boolean r; // Any number is coercible to double, if the value is not coercible, it is not a supported // number type. if (NumericConverter.isCoercibleToDouble(x) && NumericConverter.isCoercibleToDouble(y)) { @@ -444,18 +397,12 @@ protected BoolStorage runMixedZip( r = onOtherType(x, y); } - if (r) { - comparisonResults.set(i); - } + builder.appendBoolean(r); } context.safepoint(); } - if (m < n) { - isNothing.set(m, n); - } - - return new BoolStorage(comparisonResults, isNothing, n, false); + return builder.seal(); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/BigDecimalArrayAdapter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/BigDecimalArrayAdapter.java index 112c53582345..acf4c6a5dca3 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/BigDecimalArrayAdapter.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/BigDecimalArrayAdapter.java @@ -1,127 +1,133 @@ package org.enso.table.data.column.operation.map.numeric.helpers; import java.math.BigDecimal; -import org.enso.table.data.column.storage.SpecializedStorage; +import java.math.BigInteger; +import org.enso.table.data.column.builder.Builder; +import org.enso.table.data.column.storage.ColumnDoubleStorage; +import org.enso.table.data.column.storage.ColumnLongStorage; +import org.enso.table.data.column.storage.ColumnStorage; import org.enso.table.data.column.storage.Storage; -import org.enso.table.data.column.storage.numeric.AbstractLongStorage; import org.enso.table.data.column.storage.numeric.BigDecimalStorage; import org.enso.table.data.column.storage.numeric.BigIntegerStorage; -import org.enso.table.data.column.storage.numeric.DoubleStorage; public interface BigDecimalArrayAdapter { - BigDecimal getItem(int i); + BigDecimal getItem(long i); - int size(); + long size(); - default SpecializedStorage intoStorage() { - int n = size(); - BigDecimal[] values = new BigDecimal[n]; - for (int i = 0; i < n; i++) { - values[i] = getItem(i); + default Storage intoStorage() { + long n = size(); + var builder = Builder.getForBigDecimal(n); + for (long i = 0; i < n; i++) { + builder.append(getItem(i)); } - return new BigDecimalStorage(values, n); + return builder.seal(); } - static BigDecimalArrayAdapter fromStorage(SpecializedStorage storage) { + static BigDecimalArrayAdapter fromBigDecimalStorage(ColumnStorage storage) { return new BigDecimalStorageAsBigDecimal(storage); } - static BigDecimalArrayAdapter fromStorage(BigIntegerStorage storage) { + static BigDecimalArrayAdapter fromBigIntegerStorage(ColumnStorage storage) { return new BigIntegerStorageAsBigDecimal(storage); } - static BigDecimalArrayAdapter fromStorage(AbstractLongStorage storage) { + static BigDecimalArrayAdapter fromStorage(ColumnLongStorage storage) { return new LongStorageAsBigDecimal(storage); } - static BigDecimalArrayAdapter fromStorage(DoubleStorage storage) { + static BigDecimalArrayAdapter fromStorage(ColumnDoubleStorage storage) { return new DoubleStorageAsBigDecimal(storage); } - static BigDecimalArrayAdapter fromAnyStorage(Storage storage) { + static BigDecimalArrayAdapter fromAnyStorage(ColumnStorage storage) { return switch (storage) { - case DoubleStorage s -> fromStorage(s); - case AbstractLongStorage s -> fromStorage(s); - case BigIntegerStorage s -> fromStorage(s); - case BigDecimalStorage s -> fromStorage(s); + case ColumnDoubleStorage s -> fromStorage(s); + case ColumnLongStorage s -> fromStorage(s); + case BigIntegerStorage s -> new BigIntegerStorageAsBigDecimal(s); + case BigDecimalStorage s -> new BigDecimalStorageAsBigDecimal(s); default -> throw new IllegalStateException( "Unsupported storage: " + storage.getClass().getCanonicalName()); }; } class BigDecimalStorageAsBigDecimal implements BigDecimalArrayAdapter { - private final SpecializedStorage storage; + private final ColumnStorage storage; - private BigDecimalStorageAsBigDecimal(SpecializedStorage storage) { + private BigDecimalStorageAsBigDecimal(ColumnStorage storage) { this.storage = storage; } @Override - public BigDecimal getItem(int i) { + public BigDecimal getItem(long i) { return storage.getItemBoxed(i); } @Override - public int size() { - return storage.size(); + public long size() { + return storage.getSize(); } @Override - public SpecializedStorage intoStorage() { - return storage; + public Storage intoStorage() { + if (storage instanceof Storage specialized) { + return specialized; + } else { + return BigDecimalArrayAdapter.super.intoStorage(); + } } } class BigIntegerStorageAsBigDecimal implements BigDecimalArrayAdapter { - private final BigIntegerStorage storage; + private final ColumnStorage storage; - private BigIntegerStorageAsBigDecimal(BigIntegerStorage storage) { + private BigIntegerStorageAsBigDecimal(ColumnStorage storage) { this.storage = storage; } @Override - public BigDecimal getItem(int i) { + public BigDecimal getItem(long i) { return new BigDecimal(storage.getItemBoxed(i)); } @Override - public int size() { - return storage.size(); + public long size() { + return storage.getSize(); } } class LongStorageAsBigDecimal implements BigDecimalArrayAdapter { - private final AbstractLongStorage storage; + private final ColumnLongStorage storage; - private LongStorageAsBigDecimal(AbstractLongStorage storage) { + private LongStorageAsBigDecimal(ColumnLongStorage storage) { this.storage = storage; } @Override - public BigDecimal getItem(int i) { + public BigDecimal getItem(long i) { if (storage.isNothing(i)) { return null; } else { - long x = storage.getItem(i); + long x = storage.getItemAsLong(i); return BigDecimal.valueOf(x); } } @Override - public int size() { - return storage.size(); + public long size() { + return storage.getSize(); } } class DoubleStorageAsBigDecimal implements BigDecimalArrayAdapter { - private final DoubleStorage storage; + private final ColumnDoubleStorage storage; - private DoubleStorageAsBigDecimal(DoubleStorage storage) { + private DoubleStorageAsBigDecimal(ColumnDoubleStorage storage) { this.storage = storage; } @Override - public BigDecimal getItem(int i) { + public BigDecimal getItem(long i) { if (storage.isNothing(i)) { return null; } else { @@ -131,8 +137,8 @@ public BigDecimal getItem(int i) { } @Override - public int size() { - return storage.size(); + public long size() { + return storage.getSize(); } } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/BigIntegerArrayAdapter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/BigIntegerArrayAdapter.java index 76cd8611e321..dfcd857b4ec3 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/BigIntegerArrayAdapter.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/BigIntegerArrayAdapter.java @@ -1,74 +1,76 @@ package org.enso.table.data.column.operation.map.numeric.helpers; import java.math.BigInteger; -import org.enso.table.data.column.storage.numeric.AbstractLongStorage; -import org.enso.table.data.column.storage.numeric.BigIntegerStorage; +import org.enso.table.data.column.builder.Builder; +import org.enso.table.data.column.storage.ColumnLongStorage; +import org.enso.table.data.column.storage.Storage; +import org.enso.table.problems.BlackholeProblemAggregator; public interface BigIntegerArrayAdapter { - BigInteger getItem(int i); + BigInteger getItem(long i); - int size(); + long size(); - default BigIntegerStorage intoStorage() { - int n = size(); - BigInteger[] values = new BigInteger[n]; - for (int i = 0; i < n; i++) { - values[i] = getItem(i); + default Storage intoStorage() { + long n = size(); + var builder = Builder.getForBigInteger(n, BlackholeProblemAggregator.INSTANCE); + for (long i = 0; i < n; i++) { + builder.append(getItem(i)); } - return new BigIntegerStorage(values, n); + return builder.seal(); } - static BigIntegerArrayAdapter fromStorage(BigIntegerStorage storage) { + static BigIntegerArrayAdapter fromStorage(Storage storage) { return new BigIntegerStorageAsBigInteger(storage); } - static BigIntegerArrayAdapter fromStorage(AbstractLongStorage storage) { + static BigIntegerArrayAdapter fromStorage(ColumnLongStorage storage) { return new LongStorageAsBigInteger(storage); } class BigIntegerStorageAsBigInteger implements BigIntegerArrayAdapter { - private final BigIntegerStorage storage; + private final Storage storage; - private BigIntegerStorageAsBigInteger(BigIntegerStorage storage) { + private BigIntegerStorageAsBigInteger(Storage storage) { this.storage = storage; } @Override - public BigInteger getItem(int i) { + public BigInteger getItem(long i) { return storage.getItemBoxed(i); } @Override - public int size() { - return storage.size(); + public long size() { + return storage.getSize(); } @Override - public BigIntegerStorage intoStorage() { + public Storage intoStorage() { return storage; } } class LongStorageAsBigInteger implements BigIntegerArrayAdapter { - private final AbstractLongStorage storage; + private final ColumnLongStorage storage; - private LongStorageAsBigInteger(AbstractLongStorage storage) { + private LongStorageAsBigInteger(ColumnLongStorage storage) { this.storage = storage; } @Override - public BigInteger getItem(int i) { + public BigInteger getItem(long i) { if (storage.isNothing(i)) { return null; } else { - long x = storage.getItem(i); + long x = storage.getItemAsLong(i); return BigInteger.valueOf(x); } } @Override - public int size() { - return storage.size(); + public long size() { + return storage.getSize(); } } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/DoubleArrayAdapter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/DoubleArrayAdapter.java index adb19242be85..091666120985 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/DoubleArrayAdapter.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/DoubleArrayAdapter.java @@ -2,43 +2,44 @@ import java.math.BigDecimal; import java.math.BigInteger; -import java.util.BitSet; +import org.enso.table.data.column.builder.Builder; +import org.enso.table.data.column.storage.ColumnLongStorage; import org.enso.table.data.column.storage.Storage; -import org.enso.table.data.column.storage.numeric.AbstractLongStorage; import org.enso.table.data.column.storage.numeric.BigDecimalStorage; import org.enso.table.data.column.storage.numeric.BigIntegerStorage; import org.enso.table.data.column.storage.numeric.DoubleStorage; +import org.enso.table.data.column.storage.type.FloatType; +import org.enso.table.problems.BlackholeProblemAggregator; public interface DoubleArrayAdapter { - double getItemAsDouble(int i); + double getItemAsDouble(long i); boolean isNothing(long i); - int size(); + long size(); - default DoubleStorage intoStorage() { - int n = size(); - double[] values = new double[n]; - BitSet isNothing = new BitSet(); - for (int i = 0; i < n; i++) { + default Storage intoStorage() { + long n = size(); + var builder = Builder.getForDouble(FloatType.FLOAT_64, n, BlackholeProblemAggregator.INSTANCE); + for (long i = 0; i < n; i++) { if (isNothing(i)) { - isNothing.set(i); + builder.appendNulls(1); } else { - values[i] = getItemAsDouble(i); + builder.appendDouble(getItemAsDouble(i)); } } - return new DoubleStorage(values, n, isNothing); + return builder.seal(); } - static DoubleArrayAdapter fromStorage(BigIntegerStorage storage) { + static DoubleArrayAdapter fromBigIntegerStorage(Storage storage) { return new BigIntegerStorageAsDouble(storage); } - static DoubleArrayAdapter fromStorage(BigDecimalStorage storage) { + static DoubleArrayAdapter fromBigDecimalStorage(Storage storage) { return new BigDecimalStorageAsDouble(storage); } - static DoubleArrayAdapter fromStorage(AbstractLongStorage storage) { + static DoubleArrayAdapter fromStorage(ColumnLongStorage storage) { return new LongStorageAsDouble(storage); } @@ -49,24 +50,24 @@ static DoubleArrayAdapter fromStorage(DoubleStorage storage) { static DoubleArrayAdapter fromAnyStorage(Storage storage) { return switch (storage) { case DoubleStorage s -> fromStorage(s); - case AbstractLongStorage s -> fromStorage(s); - case BigIntegerStorage s -> fromStorage(s); - case BigDecimalStorage s -> fromStorage(s); + case ColumnLongStorage s -> fromStorage(s); + case BigIntegerStorage s -> fromBigIntegerStorage(s); + case BigDecimalStorage s -> fromBigDecimalStorage(s); default -> throw new IllegalStateException( "Unsupported storage: " + storage.getClass().getCanonicalName()); }; } class LongStorageAsDouble implements DoubleArrayAdapter { - private final AbstractLongStorage storage; + private final ColumnLongStorage storage; - private LongStorageAsDouble(AbstractLongStorage storage) { + private LongStorageAsDouble(ColumnLongStorage storage) { this.storage = storage; } @Override - public double getItemAsDouble(int i) { - long x = storage.getItem(i); + public double getItemAsDouble(long i) { + long x = storage.getItemAsLong(i); return (double) x; } @@ -76,56 +77,56 @@ public boolean isNothing(long i) { } @Override - public int size() { - return storage.size(); + public long size() { + return storage.getSize(); } } class BigIntegerStorageAsDouble implements DoubleArrayAdapter { - private final BigIntegerStorage storage; + private final Storage storage; - private BigIntegerStorageAsDouble(BigIntegerStorage storage) { + private BigIntegerStorageAsDouble(Storage storage) { this.storage = storage; } @Override - public double getItemAsDouble(int i) { - BigInteger x = storage.getItem(i); + public double getItemAsDouble(long i) { + BigInteger x = storage.getItemBoxed(i); return x.doubleValue(); } @Override public boolean isNothing(long i) { - return storage.getItem(i) == null; + return storage.isNothing(i); } @Override - public int size() { - return storage.size(); + public long size() { + return storage.getSize(); } } class BigDecimalStorageAsDouble implements DoubleArrayAdapter { - private final BigDecimalStorage storage; + private final Storage storage; - private BigDecimalStorageAsDouble(BigDecimalStorage storage) { + private BigDecimalStorageAsDouble(Storage storage) { this.storage = storage; } @Override - public double getItemAsDouble(int i) { - BigDecimal x = storage.getItem(i); + public double getItemAsDouble(long i) { + BigDecimal x = storage.getItemBoxed(i); return x.doubleValue(); } @Override public boolean isNothing(long i) { - return storage.getItem(i) == null; + return storage.isNothing(i); } @Override - public int size() { - return storage.size(); + public long size() { + return storage.getSize(); } } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/CoalescingStringStringOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/CoalescingStringStringOp.java index e81514717c98..06457fc0cc28 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/CoalescingStringStringOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/CoalescingStringStringOp.java @@ -1,5 +1,6 @@ package org.enso.table.data.column.operation.map.text; +import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.operation.map.MapOperationProblemAggregator; import org.enso.table.data.column.storage.SpecializedStorage; import org.enso.table.data.column.storage.Storage; @@ -14,46 +15,48 @@ public CoalescingStringStringOp(String name) { } @Override - public Storage runBinaryMap( + public Storage runBinaryMap( SpecializedStorage storage, Object arg, MapOperationProblemAggregator problemAggregator) { - int size = storage.size(); if (arg == null) { return storage; } else if (arg instanceof String argString) { - String[] newVals = new String[size]; + TextType argumentType = TextType.preciseTypeForValue(argString); + TextType newType = computeResultType((TextType) storage.getType(), argumentType); + + long size = storage.getSize(); + var builder = Builder.getForText(newType, size); Context context = Context.getCurrent(); - for (int i = 0; i < size; i++) { + for (long i = 0; i < size; i++) { if (storage.isNothing(i)) { - newVals[i] = argString; + builder.append(argString); } else { - newVals[i] = doString(storage.getItem(i), argString); + builder.append(doString(storage.getItemBoxed(i), argString)); } context.safepoint(); } - TextType argumentType = TextType.preciseTypeForValue(argString); - TextType newType = computeResultType((TextType) storage.getType(), argumentType); - return new StringStorage(newVals, size, newType); + return builder.seal(); } else { throw new UnexpectedTypeException("a Text"); } } @Override - public Storage runZip( + public Storage runZip( SpecializedStorage storage, Storage arg, MapOperationProblemAggregator problemAggregator) { if (arg instanceof StringStorage v) { - int size = storage.size(); - String[] newVals = new String[size]; + long size = storage.getSize(); + TextType newType = computeResultType((TextType) storage.getType(), v.getType()); + var builder = Builder.getForText(newType, size); Context context = Context.getCurrent(); - for (int i = 0; i < size; i++) { - String a = storage.getItem(i); - String b = v.getItem(i); + for (long i = 0; i < size; i++) { + String a = storage.getItemBoxed(i); + String b = v.getItemBoxed(i); String r; if (a == null && b == null) { r = null; @@ -67,13 +70,11 @@ public Storage runZip( } } - newVals[i] = r; - + builder.append(r); context.safepoint(); } - TextType newType = computeResultType((TextType) storage.getType(), v.getType()); - return new StringStorage(newVals, size, newType); + return builder.seal(); } else { throw new UnexpectedTypeException("a Text column"); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/LikeOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/LikeOp.java index ffdcde1512d2..c1f636f10d6e 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/LikeOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/LikeOp.java @@ -1,9 +1,9 @@ package org.enso.table.data.column.operation.map.text; import com.ibm.icu.impl.UnicodeRegex; -import java.util.BitSet; import java.util.regex.Pattern; import org.enso.base.Regex_Utils; +import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.operation.map.MapOperationProblemAggregator; import org.enso.table.data.column.storage.BoolStorage; import org.enso.table.data.column.storage.SpecializedStorage; @@ -35,30 +35,27 @@ protected boolean doString(String a, String b) { } @Override - public BoolStorage runBinaryMap( + public Storage runBinaryMap( SpecializedStorage storage, Object arg, MapOperationProblemAggregator problemAggregator) { if (arg == null) { - BitSet newVals = new BitSet(); - BitSet newIsNothing = new BitSet(); - newIsNothing.set(0, storage.size()); - return new BoolStorage(newVals, newIsNothing, storage.size(), false); + return BoolStorage.makeEmpty(storage.getSize()); } else if (arg instanceof String argString) { Pattern pattern = createRegexPatternFromSql(argString); - BitSet newVals = new BitSet(); - BitSet newIsNothing = new BitSet(); + long size = storage.getSize(); + var builder = Builder.getForBoolean(size); Context context = Context.getCurrent(); - for (int i = 0; i < storage.size(); i++) { + for (long i = 0; i < size; i++) { if (storage.isNothing(i)) { - newIsNothing.set(i); - } else if (pattern.matcher(storage.getItem(i)).matches()) { - newVals.set(i); + builder.appendNulls(1); + } else { + builder.appendBoolean(pattern.matcher(storage.getItemBoxed(i)).matches()); } context.safepoint(); } - return new BoolStorage(newVals, newIsNothing, storage.size(), false); + return builder.seal(); } else { throw new UnexpectedTypeException("a Text"); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringBooleanOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringBooleanOp.java index c4cd9d982b0d..aa086a69a81e 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringBooleanOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringBooleanOp.java @@ -1,6 +1,6 @@ package org.enso.table.data.column.operation.map.text; -import java.util.BitSet; +import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.operation.map.BinaryMapOperation; import org.enso.table.data.column.operation.map.MapOperationProblemAggregator; import org.enso.table.data.column.storage.BoolStorage; @@ -23,89 +23,76 @@ protected boolean doObject(String a, Object o) { } @Override - public BoolStorage runBinaryMap( + public Storage runBinaryMap( SpecializedStorage storage, Object arg, MapOperationProblemAggregator problemAggregator) { if (arg == null) { - BitSet newVals = new BitSet(); - BitSet newIsNothing = new BitSet(); - newIsNothing.set(0, storage.size()); - return new BoolStorage(newVals, newIsNothing, storage.size(), false); + return BoolStorage.makeEmpty(storage.getSize()); } else if (arg instanceof String argString) { - BitSet newVals = new BitSet(); - BitSet newIsNothing = new BitSet(); Context context = Context.getCurrent(); - for (int i = 0; i < storage.size(); i++) { + long size = storage.getSize(); + var builder = Builder.getForBoolean(size); + for (long i = 0; i < size; i++) { if (storage.isNothing(i)) { - newIsNothing.set(i); - } else if (doString(storage.getItem(i), argString)) { - newVals.set(i); + builder.appendNulls(1); + } else { + builder.appendBoolean(doString(storage.getItemBoxed(i), argString)); } - context.safepoint(); } - return new BoolStorage(newVals, newIsNothing, storage.size(), false); + return builder.seal(); } else { - BitSet newVals = new BitSet(); - BitSet newIsNothing = new BitSet(); Context context = Context.getCurrent(); - for (int i = 0; i < storage.size(); i++) { + long size = storage.getSize(); + var builder = Builder.getForBoolean(size); + for (long i = 0; i < size; i++) { if (storage.isNothing(i)) { - newIsNothing.set(i); - } else if (doObject(storage.getItem(i), arg)) { - newVals.set(i); + builder.appendNulls(1); + } else { + builder.appendBoolean(doObject(storage.getItemBoxed(i), arg)); } - context.safepoint(); } - return new BoolStorage(newVals, newIsNothing, storage.size(), false); + return builder.seal(); } } @Override - public BoolStorage runZip( + public Storage runZip( SpecializedStorage storage, Storage arg, MapOperationProblemAggregator problemAggregator) { Context context = Context.getCurrent(); if (arg instanceof StringStorage v) { - BitSet newVals = new BitSet(); - BitSet newIsNothing = new BitSet(); - for (int i = 0; i < storage.size(); i++) { - if (!storage.isNothing(i) && i < v.size() && !v.isNothing(i)) { - if (doString(storage.getItem(i), v.getItem(i))) { - newVals.set(i); - } + long size = storage.getSize(); + var builder = Builder.getForBoolean(size); + for (long i = 0; i < size; i++) { + if (!storage.isNothing(i) && i < v.getSize() && !v.isNothing(i)) { + builder.appendBoolean(doString(storage.getItemBoxed(i), v.getItemBoxed(i))); } else { - newIsNothing.set(i); + builder.appendNulls(1); } - context.safepoint(); } - return new BoolStorage(newVals, newIsNothing, storage.size(), false); + return builder.seal(); } else { - BitSet newVals = new BitSet(); - BitSet newIsNothing = new BitSet(); - for (int i = 0; i < storage.size(); i++) { - if (!storage.isNothing(i) && i < arg.size() && !arg.isNothing(i)) { + long size = storage.getSize(); + var builder = Builder.getForBoolean(size); + for (long i = 0; i < size; i++) { + if (!storage.isNothing(i) && i < arg.getSize() && !arg.isNothing(i)) { Object x = arg.getItemBoxed(i); if (x instanceof String str) { - if (doString(storage.getItem(i), str)) { - newVals.set(i); - } + builder.appendBoolean(doString(storage.getItemBoxed(i), str)); } else { - if (doObject(storage.getItem(i), x)) { - newVals.set(i); - } + builder.appendBoolean(doObject(storage.getItemBoxed(i), x)); } } else { - newIsNothing.set(i); + builder.appendNulls(1); } - context.safepoint(); } - return new BoolStorage(newVals, newIsNothing, storage.size(), false); + return builder.seal(); } } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringLongToStringOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringLongToStringOp.java index ea9390fac5e7..b6d5fb8576a1 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringLongToStringOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringLongToStringOp.java @@ -20,54 +20,48 @@ public StringLongToStringOp(String name) { protected abstract String doOperation(String a, long b); @Override - public Storage runBinaryMap( + public Storage runBinaryMap( SpecializedStorage storage, Object arg, MapOperationProblemAggregator problemAggregator) { - int size = storage.size(); + long size = storage.getSize(); if (arg == null) { - var builder = Builder.getForType(TextType.VARIABLE_LENGTH, size, problemAggregator); - builder.appendNulls(size); - return builder.seal(); + return StringStorage.makeEmpty((TextType) storage.getType(), size); } else if (arg instanceof Long argLong) { - String[] newVals = new String[size]; + var builder = Builder.getForText((TextType) storage.getType(), size); Context context = Context.getCurrent(); - for (int i = 0; i < size; i++) { + for (long i = 0; i < size; i++) { if (storage.isNothing(i)) { - newVals[i] = null; + builder.appendNulls(1); } else { - newVals[i] = doOperation(storage.getItem(i), argLong); + builder.append(doOperation(storage.getItemBoxed(i), argLong)); } - context.safepoint(); } - - return new StringStorage(newVals, size, (TextType) storage.getType()); + return builder.seal(); } else { throw new UnexpectedTypeException("a Text"); } } @Override - public Storage runZip( + public Storage runZip( SpecializedStorage storage, Storage arg, MapOperationProblemAggregator problemAggregator) { if (arg instanceof LongStorage v) { - int size = storage.size(); - String[] newVals = new String[size]; + long size = storage.getSize(); + var builder = Builder.getForText(TextType.VARIABLE_LENGTH, size); Context context = Context.getCurrent(); - for (int i = 0; i < size; i++) { + for (long i = 0; i < size; i++) { if (storage.isNothing(i) || v.isNothing(i)) { - newVals[i] = null; + builder.appendNulls(1); } else { - newVals[i] = doOperation(storage.getItem(i), v.getItem(i)); + builder.append(doOperation(storage.getItemBoxed(i), v.getItemBoxed(i))); } - context.safepoint(); } - - return new StringStorage(newVals, size, (TextType) storage.getType()); + return builder.seal(); } else { throw new UnexpectedTypeException("a Text column"); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringStringOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringStringOp.java index fc807b9209b2..b17dfa4d355f 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringStringOp.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringStringOp.java @@ -21,57 +21,53 @@ public StringStringOp(String name) { protected abstract TextType computeResultType(TextType a, TextType b); @Override - public Storage runBinaryMap( + public Storage runBinaryMap( SpecializedStorage storage, Object arg, MapOperationProblemAggregator problemAggregator) { - int size = storage.size(); + long size = storage.getSize(); if (arg == null) { - var builder = Builder.getForType(TextType.VARIABLE_LENGTH, size, problemAggregator); - builder.appendNulls(size); - return builder.seal(); + return StringStorage.makeEmpty(TextType.VARIABLE_LENGTH, size); } else if (arg instanceof String argString) { - String[] newVals = new String[size]; + TextType argumentType = TextType.preciseTypeForValue(argString); + TextType newType = computeResultType((TextType) storage.getType(), argumentType); + + var builder = Builder.getForText(newType, size); Context context = Context.getCurrent(); - for (int i = 0; i < size; i++) { + for (long i = 0; i < size; i++) { if (storage.isNothing(i)) { - newVals[i] = null; + builder.appendNulls(1); } else { - newVals[i] = doString(storage.getItem(i), argString); + builder.append(doString(storage.getItemBoxed(i), argString)); } - context.safepoint(); } - TextType argumentType = TextType.preciseTypeForValue(argString); - TextType newType = computeResultType((TextType) storage.getType(), argumentType); - return new StringStorage(newVals, size, newType); + return builder.seal(); } else { throw new UnexpectedTypeException("a Text"); } } @Override - public Storage runZip( + public Storage runZip( SpecializedStorage storage, Storage arg, MapOperationProblemAggregator problemAggregator) { if (arg instanceof StringStorage v) { - int size = storage.size(); - String[] newVals = new String[size]; + TextType newType = computeResultType((TextType) storage.getType(), v.getType()); + long size = storage.getSize(); + var builder = Builder.getForText(newType, size); Context context = Context.getCurrent(); - for (int i = 0; i < size; i++) { + for (long i = 0; i < size; i++) { if (storage.isNothing(i) || v.isNothing(i)) { - newVals[i] = null; + builder.appendNulls(1); } else { - newVals[i] = doString(storage.getItem(i), v.getItem(i)); + builder.append(doString(storage.getItemBoxed(i), v.getItemBoxed(i))); } - context.safepoint(); } - - TextType newType = computeResultType((TextType) storage.getType(), v.getType()); - return new StringStorage(newVals, size, newType); + return builder.seal(); } else { throw new UnexpectedTypeException("a Text column"); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/AbstractUnaryBooleanOperation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/AbstractUnaryBooleanOperation.java index b905a6e78b42..c5255a05e382 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/AbstractUnaryBooleanOperation.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/AbstractUnaryBooleanOperation.java @@ -19,7 +19,7 @@ protected AbstractUnaryBooleanOperation(String name, boolean nothingUnchanged) { @Override protected BuilderForBoolean createBuilder( - ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { + ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { return Builder.getForBoolean(storage.getSize()); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/AbstractUnaryLongOperation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/AbstractUnaryLongOperation.java index 27c6790ff8e4..e3dddbcd232d 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/AbstractUnaryLongOperation.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/AbstractUnaryLongOperation.java @@ -26,7 +26,7 @@ protected AbstractUnaryLongOperation( @Override protected BuilderForLong createBuilder( - ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { + ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { return Builder.getForLong(returnType, storage.getSize(), problemAggregator); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/AbstractUnaryOperation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/AbstractUnaryOperation.java index a862d71cc2f9..2582158bbe99 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/AbstractUnaryOperation.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/AbstractUnaryOperation.java @@ -33,11 +33,11 @@ public String getName() { } @Override - public abstract boolean canApply(ColumnStorage storage); + public abstract boolean canApply(ColumnStorage storage); @Override - public ColumnStorage apply( - ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { + public ColumnStorage apply( + ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { var builder = createBuilder(storage, problemAggregator); switch (storage) { @@ -53,7 +53,7 @@ public ColumnStorage apply( } protected Builder createBuilder( - ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { + ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { return Builder.getInferredBuilder(storage.getSize(), problemAggregator); } @@ -83,7 +83,7 @@ protected void applyDouble( /** Apply the operation to an Object Storage. */ protected void applyObject( - ColumnStorage objectStorage, + ColumnStorage objectStorage, Builder builder, MapOperationProblemAggregator problemAggregator) { UnaryOperation.applyOverObjectStorage( diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/DatePartOperation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/DatePartOperation.java index d7dfbcedd32d..f991a1603e2b 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/DatePartOperation.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/DatePartOperation.java @@ -65,7 +65,7 @@ protected DatePartOperation(String name, TemporalField field, boolean timeField) } @Override - public boolean canApply(ColumnStorage storage) { + public boolean canApply(ColumnStorage storage) { return timeField ? storage.getType().hasTime() : storage.getType().hasDate(); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/DateTruncateOperation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/DateTruncateOperation.java index 7052c8496c47..2f4114ede7f5 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/DateTruncateOperation.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/DateTruncateOperation.java @@ -6,7 +6,6 @@ import org.enso.table.data.column.operation.map.MapOperationProblemAggregator; import org.enso.table.data.column.storage.ColumnStorage; import org.enso.table.data.column.storage.type.DateTimeType; -import org.enso.table.data.column.storage.type.DateType; public class DateTruncateOperation extends AbstractUnaryOperation { public static String TRUNCATE = "truncate"; @@ -17,14 +16,14 @@ private DateTruncateOperation() { } @Override - public boolean canApply(ColumnStorage storage) { + public boolean canApply(ColumnStorage storage) { return storage.getType() == DateTimeType.INSTANCE; } @Override protected Builder createBuilder( - ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { - return Builder.getForType(DateType.INSTANCE, storage.getSize(), problemAggregator); + ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { + return Builder.getForDate(storage.getSize()); } @Override diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsEmptyOperation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsEmptyOperation.java index 816337967e03..8b99b3315ba8 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsEmptyOperation.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsEmptyOperation.java @@ -19,7 +19,7 @@ private IsEmptyOperation() { } @Override - public boolean canApply(ColumnStorage storage) { + public boolean canApply(ColumnStorage storage) { var type = storage.getType(); // We also allow this operation on Mixed type to facilitate `internal_is_empty` helper. return type instanceof TextType || type instanceof AnyObjectType; diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsFiniteOperation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsFiniteOperation.java index b89e363fa481..bbd34f8127a0 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsFiniteOperation.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsFiniteOperation.java @@ -16,13 +16,13 @@ private IsFiniteOperation() { } @Override - public boolean canApply(ColumnStorage storage) { + public boolean canApply(ColumnStorage storage) { return storage.getType().isNumeric(); } @Override - public ColumnStorage apply( - ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { + public ColumnStorage apply( + ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { if (storage instanceof ColumnLongStorage && storage instanceof ColumnStorageWithNothingMap withNothingMap) { // For a Column of Longs where we have the Nothing map, we can produce result immediately. diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsInfiniteOperation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsInfiniteOperation.java index 0eb112bc9805..3459e52ba821 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsInfiniteOperation.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsInfiniteOperation.java @@ -16,13 +16,13 @@ private IsInfiniteOperation() { } @Override - public boolean canApply(ColumnStorage storage) { + public boolean canApply(ColumnStorage storage) { return storage.getType().isNumeric(); } @Override - public ColumnStorage apply( - ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { + public ColumnStorage apply( + ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { if (storage instanceof ColumnLongStorage && storage instanceof ColumnStorageWithNothingMap withNothingMap) { // For a Column of Longs where we have the Nothing map, we can produce result immediately. diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsNaNOperation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsNaNOperation.java index dbed77648987..a7e5a4f36a91 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsNaNOperation.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsNaNOperation.java @@ -21,15 +21,15 @@ private IsNaNOperation() { } @Override - public boolean canApply(ColumnStorage storage) { + public boolean canApply(ColumnStorage storage) { var type = storage.getType(); // We also allow this operation on Mixed type to facilitate `internal_is_nan` helper. return type.isNumeric() || type instanceof AnyObjectType; } @Override - public ColumnStorage apply( - ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { + public ColumnStorage apply( + ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { if (storage instanceof ColumnLongStorage && storage instanceof ColumnStorageWithNothingMap withNothingMap) { // For a Column of Longs where we have the Nothing map, we can produce result immediately. diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsNothingOperation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsNothingOperation.java index 45754c9e4129..01403e665cb8 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsNothingOperation.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/IsNothingOperation.java @@ -18,13 +18,13 @@ private IsNothingOperation() { } @Override - public boolean canApply(ColumnStorage storage) { + public boolean canApply(ColumnStorage storage) { return true; } @Override - public ColumnStorage apply( - ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { + public ColumnStorage apply( + ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { if (storage instanceof ColumnStorageWithNothingMap withNothingMap) { return new BoolStorage( withNothingMap.getIsNothingMap(), new BitSet(), (int) storage.getSize(), false); diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/NotOperation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/NotOperation.java index 61aac76dc510..3a17fff0951d 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/NotOperation.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/NotOperation.java @@ -20,13 +20,13 @@ private NotOperation() { } @Override - public boolean canApply(ColumnStorage storage) { + public boolean canApply(ColumnStorage storage) { return storage.getType() instanceof BooleanType || storage.getType() instanceof NullType; } @Override - public ColumnStorage apply( - ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { + public ColumnStorage apply( + ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { if (storage instanceof BoolStorage boolStorage) { return boolStorage.makeNegated(); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/TextLengthOperation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/TextLengthOperation.java index 2fd8158c88fb..60d90345024f 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/TextLengthOperation.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/TextLengthOperation.java @@ -17,7 +17,7 @@ private TextLengthOperation() { } @Override - public boolean canApply(ColumnStorage storage) { + public boolean canApply(ColumnStorage storage) { return storage.getType() instanceof TextType; } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/UnaryRoundOperation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/UnaryRoundOperation.java index 9fb8a2fcf524..b6180686c179 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/UnaryRoundOperation.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/unary/UnaryRoundOperation.java @@ -45,18 +45,18 @@ private UnaryRoundOperation( } protected Builder createBuilder( - ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { + ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { return Builder.getInferredBuilder(storage.getSize(), problemAggregator); } @Override - public boolean canApply(ColumnStorage storage) { + public boolean canApply(ColumnStorage storage) { return storage.getType().isNumeric(); } @Override - public ColumnStorage apply( - ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { + public ColumnStorage apply( + ColumnStorage storage, MapOperationProblemAggregator problemAggregator) { if (storage instanceof ColumnLongStorage || storage instanceof BigIntegerStorage) { // For an integral type storage, the operation is an identity operation. return storage; diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/BoolStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/BoolStorage.java index 4f5bd16f23bb..571c50f29299 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/BoolStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/BoolStorage.java @@ -38,13 +38,15 @@ public BoolStorage(BitSet values, BitSet isNothing, int size, boolean negated) { this.negated = negated; } - public static BoolStorage makeEmpty(int size) { - BitSet isNothing = new BitSet(size); - isNothing.set(0, size); - return new BoolStorage(new BitSet(), isNothing, size, false); + public static BoolStorage makeEmpty(long size) { + int checkedSize = Builder.checkSize(size); + + BitSet isNothing = new BitSet(checkedSize); + isNothing.set(0, checkedSize); + return new BoolStorage(new BitSet(), isNothing, checkedSize, false); } - public static BoolStorage makeConstant(int size, boolean r) { + private static BoolStorage makeConstant(int size, boolean r) { return new BoolStorage(new BitSet(), new BitSet(), size, r); } @@ -53,26 +55,34 @@ public BoolStorage makeNegated() { } @Override - public int size() { + public long getSize() { return size; } + @Override + public Boolean getItemBoxed(long idx) { + return isNothing(idx) ? null : getItemAsBoolean(idx); + } + @Override public StorageType getType() { return BooleanType.INSTANCE; } @Override - public Boolean getItemBoxed(int idx) { - return isNothing.get(idx) ? null : getItem(idx); - } + public boolean getItemAsBoolean(long index) throws ValueIsNothingException { + if (isNothing(index)) { + throw new ValueIsNothingException(index); + } - public boolean getItem(long idx) { - return negated != values.get((int) idx); + return negated != values.get((int) index); } @Override public boolean isNothing(long idx) { + if (idx < 0 || idx >= getSize()) { + throw new IndexOutOfBoundsException(idx); + } return isNothing.get((int) idx); } @@ -93,10 +103,19 @@ public Storage runVectorizedZip( return ops.runZip(name, this, argument, problemAggregator); } + public boolean isNegated() { + return negated; + } + public BitSet getValues() { return values; } + @Override + public BitSet getIsNothingMap() { + return isNothing; + } + /** * Creates a new BoolStorage in which all missing values have been replaced by arg. * @@ -133,21 +152,21 @@ public Storage fillMissingFromPrevious(BoolStorage missingIndicator) { boolean previousValue = false; boolean hasPrevious = false; - BitSet newIsNothing = new BitSet(); - BitSet newValues = new BitSet(); + long size = getSize(); + var builder = Builder.getForBoolean(size); Context context = Context.getCurrent(); - for (int i = 0; i < size; i++) { - boolean isCurrentValueMissing = isNothing.get(i); + for (long i = 0; i < size; i++) { + boolean isCurrentValueMissing = isNothing(i); if (isCurrentValueMissing) { if (hasPrevious) { - newValues.set(i, previousValue); + builder.appendBoolean(previousValue); } else { - newIsNothing.set(i); + builder.appendNulls(1); } } else { - boolean currentValue = getItem(i); - newValues.set(i, currentValue); + boolean currentValue = getItemAsBoolean(i); + builder.appendBoolean(currentValue); previousValue = currentValue; hasPrevious = true; } @@ -155,53 +174,40 @@ public Storage fillMissingFromPrevious(BoolStorage missingIndicator) { context.safepoint(); } - return new BoolStorage(newValues, newIsNothing, size, false); + return builder.seal(); } @Override - public BoolStorage applyFilter(BitSet filterMask, int newLength) { + public Storage applyFilter(BitSet filterMask, int newLength) { Context context = Context.getCurrent(); - BitSet newIsNothing = new BitSet(); - BitSet newValues = new BitSet(); - int resultIx = 0; + var builder = Builder.getForBoolean(newLength); for (int i = 0; i < size; i++) { if (filterMask.get(i)) { if (isNothing.get(i)) { - newIsNothing.set(resultIx++); - } else if (values.get(i)) { - newValues.set(resultIx++); + builder.appendNulls(1); } else { - // We don't set any bits, but still increment the counter to indicate that we have just - // 'inserted' a false value. - resultIx++; + builder.appendBoolean(getItemAsBoolean(i)); } } - context.safepoint(); } - return new BoolStorage(newValues, newIsNothing, newLength, negated); + return builder.seal(); } @Override - public BoolStorage applyMask(OrderMask mask) { + public Storage applyMask(OrderMask mask) { Context context = Context.getCurrent(); - BitSet newNa = new BitSet(); - BitSet newVals = new BitSet(); + var builder = Builder.getForBoolean(mask.length()); for (int i = 0; i < mask.length(); i++) { int position = mask.get(i); if (position == OrderMask.NOT_FOUND_INDEX || isNothing.get(position)) { - newNa.set(i); - } else if (values.get(position)) { - newVals.set(i); + builder.appendNulls(1); + } else { + builder.appendBoolean(getItemAsBoolean(position)); } - context.safepoint(); } - return new BoolStorage(newVals, newNa, mask.length(), negated); - } - - public boolean isNegated() { - return negated; + return builder.seal(); } public Storage iif( @@ -216,7 +222,7 @@ public Storage iif( for (int i = 0; i < size; i++) { if (isNothing.get(i)) { builder.appendNulls(1); - } else if (getItem(i)) { + } else if (getItemAsBoolean(i)) { builder.append(on_true.apply(i)); } else { builder.append(on_false.apply(i)); @@ -299,36 +305,22 @@ public Storage appendNulls(int count) { } @Override - public BoolStorage slice(List ranges) { + public Storage slice(List ranges) { Context context = Context.getCurrent(); int newSize = SliceRange.totalLength(ranges); - BitSet newValues = new BitSet(newSize); - BitSet newIsNothing = new BitSet(newSize); - int offset = 0; + var builder = Builder.getForBoolean(newSize); for (SliceRange range : ranges) { int length = range.end() - range.start(); for (int i = 0; i < length; ++i) { - newValues.set(offset + i, values.get(range.start() + i)); - newIsNothing.set(offset + i, isNothing.get(range.start() + i)); + if (isNothing.get(range.start() + i)) { + builder.appendNulls(1); + } else { + builder.appendBoolean(getItemAsBoolean(range.start() + i)); + } context.safepoint(); } - offset += length; } - - return new BoolStorage(newValues, newIsNothing, newSize, negated); - } - - @Override - public BitSet getIsNothingMap() { - return isNothing; - } - - @Override - public boolean get(long index) throws ValueIsNothingException { - if (isNothing(index)) { - throw new ValueIsNothingException(index); - } - return getItem(index); + return builder.seal(); } private static class BoolEq extends BinaryMapOperation { @@ -340,7 +332,7 @@ public BoolEq() { public BoolStorage runBinaryMap( BoolStorage storage, Object arg, MapOperationProblemAggregator problemAggregator) { if (arg == null) { - return BoolStorage.makeEmpty(storage.size); + return BoolStorage.makeEmpty(storage.getSize()); } else if (arg instanceof Boolean v) { if (v) { return storage; @@ -353,23 +345,21 @@ public BoolStorage runBinaryMap( } @Override - public BoolStorage runZip( + public Storage runZip( BoolStorage storage, Storage arg, MapOperationProblemAggregator problemAggregator) { + long n = storage.getSize(); + var builder = Builder.getForBoolean(n); Context context = Context.getCurrent(); - BitSet out = new BitSet(); - BitSet isNothing = new BitSet(); - for (int i = 0; i < storage.size; i++) { - if (!storage.isNothing(i) && i < arg.size() && !arg.isNothing(i)) { - if (((Boolean) storage.getItem(i)).equals(arg.getItemBoxed(i))) { - out.set(i); - } + for (long i = 0; i < n; i++) { + if (!storage.isNothing(i) && i < arg.getSize() && !arg.isNothing(i)) { + builder.appendBoolean( + ((Boolean) storage.getItemAsBoolean(i)).equals(arg.getItemBoxed(i))); } else { - isNothing.set(i); + builder.appendNulls(1); } - context.safepoint(); } - return new BoolStorage(out, isNothing, storage.size, false); + return builder.seal(); } } @@ -527,42 +517,36 @@ public BoolCompareOp(String name) { public Storage runZip( BoolStorage storage, Storage arg, MapOperationProblemAggregator problemAggregator) { if (arg instanceof BoolStorage argBoolStorage) { - BitSet out = new BitSet(); - BitSet isNothing = new BitSet(); - int n = storage.size; - int m = Math.min(n, argBoolStorage.size); + long n = storage.getSize(); + long m = Math.min(n, argBoolStorage.getSize()); + var builder = Builder.getForBoolean(n); Context context = Context.getCurrent(); - for (int i = 0; i < m; i++) { - if (storage.isNothing(i) || argBoolStorage.isNothing(i)) { - isNothing.set(i); + for (long i = 0; i < n; i++) { + if (storage.isNothing(i) || (i >= m || argBoolStorage.isNothing(i))) { + builder.appendNulls(1); } else { - boolean a = storage.getItem(i); - boolean b = argBoolStorage.getItem(i); + boolean a = storage.getItemAsBoolean(i); + boolean b = argBoolStorage.getItemAsBoolean(i); boolean r = doCompare(a, b); - out.set(i, r); + builder.appendBoolean(r); } - context.safepoint(); } - - isNothing.set(m, n); - - return new BoolStorage(out, isNothing, storage.size, false); + return builder.seal(); } else if (arg.getType() instanceof AnyObjectType) { - BitSet out = new BitSet(); - BitSet isNothing = new BitSet(); - int n = storage.size; - int m = Math.min(n, arg.size()); + long n = storage.getSize(); + long m = Math.min(n, arg.getSize()); + var builder = Builder.getForBoolean(n); Context context = Context.getCurrent(); - for (int i = 0; i < m; i++) { - if (storage.isNothing(i) || arg.isNothing(i)) { - isNothing.set(i); + for (long i = 0; i < n; i++) { + if (storage.isNothing(i) || (i >= m || arg.isNothing(i))) { + builder.appendNulls(1); } else { - boolean a = storage.getItem(i); + boolean a = storage.getItemAsBoolean(i); Object b = arg.getItemBoxed(i); if (b instanceof Boolean bBool) { boolean r = doCompare(a, bBool); - out.set(i, r); + builder.appendBoolean(r); } else { assert b != null; throw new CompareException(a, b); @@ -571,10 +555,7 @@ public Storage runZip( context.safepoint(); } - - isNothing.set(m, n); - - return new BoolStorage(out, isNothing, storage.size, false); + return builder.seal(); } else { throw new UnexpectedColumnTypeException("Boolean"); } @@ -590,7 +571,7 @@ public BoolLess() { public Storage runBinaryMap( BoolStorage storage, Object arg, MapOperationProblemAggregator problemAggregator) { if (arg == null) { - return BoolStorage.makeEmpty(storage.size); + return BoolStorage.makeEmpty(storage.getSize()); } if (arg instanceof Boolean b) { @@ -621,7 +602,7 @@ public BoolLessOrEqual() { public Storage runBinaryMap( BoolStorage storage, Object arg, MapOperationProblemAggregator problemAggregator) { if (arg == null) { - return BoolStorage.makeEmpty(storage.size); + return BoolStorage.makeEmpty(storage.getSize()); } if (arg instanceof Boolean b) { @@ -652,7 +633,7 @@ public BoolGreater() { public Storage runBinaryMap( BoolStorage storage, Object arg, MapOperationProblemAggregator problemAggregator) { if (arg == null) { - return BoolStorage.makeEmpty(storage.size); + return BoolStorage.makeEmpty(storage.getSize()); } if (arg instanceof Boolean b) { @@ -683,7 +664,7 @@ public BoolGreaterOrEqual() { public Storage runBinaryMap( BoolStorage storage, Object arg, MapOperationProblemAggregator problemAggregator) { if (arg == null) { - return BoolStorage.makeEmpty(storage.size); + return BoolStorage.makeEmpty(storage.getSize()); } if (arg instanceof Boolean b) { @@ -716,40 +697,28 @@ public BoolCoalescingOp(String name) { public Storage runZip( BoolStorage storage, Storage arg, MapOperationProblemAggregator problemAggregator) { if (arg instanceof BoolStorage argBoolStorage) { - int n = storage.size; - int m = Math.min(n, argBoolStorage.size()); - BitSet out = new BitSet(); - BitSet isNothing = new BitSet(); + long n = storage.getSize(); + long m = Math.min(n, argBoolStorage.getSize()); + var builder = Builder.getForBoolean(n); Context context = Context.getCurrent(); - for (int i = 0; i < m; i++) { + for (long i = 0; i < n; i++) { boolean isNothingA = storage.isNothing(i); - boolean isNothingB = argBoolStorage.isNothing(i); + boolean isNothingB = i >= m || argBoolStorage.isNothing(i); if (isNothingA && isNothingB) { - isNothing.set(i); + builder.appendNulls(1); } else { if (isNothingA) { - out.set(i, argBoolStorage.getItem(i)); + builder.appendBoolean(argBoolStorage.getItemAsBoolean(i)); } else if (isNothingB) { - out.set(i, storage.getItem(i)); + builder.appendBoolean(storage.getItemAsBoolean(i)); } else { - out.set(i, doOperation(storage.getItem(i), argBoolStorage.getItem(i))); + builder.appendBoolean( + doOperation(storage.getItemAsBoolean(i), argBoolStorage.getItemAsBoolean(i))); } } - context.safepoint(); } - - for (int i = m; i < n; i++) { - if (storage.isNothing(i)) { - isNothing.set(i); - } else { - out.set(i, storage.getItem(i)); - } - - context.safepoint(); - } - - return new BoolStorage(out, isNothing, storage.size, false); + return builder.seal(); } else { throw new UnexpectedColumnTypeException("Boolean"); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnBooleanStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnBooleanStorage.java index 16c778cf8b50..111a8efbf0ee 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnBooleanStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnBooleanStorage.java @@ -1,6 +1,6 @@ package org.enso.table.data.column.storage; -public interface ColumnBooleanStorage extends ColumnStorage { +public interface ColumnBooleanStorage extends ColumnStorage { /** Gets the value at a given index. Throws ValueIsNothingException if the index is nothing. */ - boolean get(long index) throws ValueIsNothingException; + boolean getItemAsBoolean(long index) throws ValueIsNothingException; } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnDoubleStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnDoubleStorage.java index 658222d153bc..10122ed65aff 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnDoubleStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnDoubleStorage.java @@ -1,6 +1,6 @@ package org.enso.table.data.column.storage; -public interface ColumnDoubleStorage extends ColumnStorage { +public interface ColumnDoubleStorage extends ColumnStorage { /** Gets the value at a given index. Throws ValueIsNothingException if the index is nothing. */ - double get(long index) throws ValueIsNothingException; + double getItemAsDouble(long index) throws ValueIsNothingException; } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnLongStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnLongStorage.java index 0a07c3e8cf75..42fe865b0377 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnLongStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnLongStorage.java @@ -1,6 +1,6 @@ package org.enso.table.data.column.storage; -public interface ColumnLongStorage extends ColumnStorage { +public interface ColumnLongStorage extends ColumnStorage { /** Gets the value at a given index. Throws ValueIsNothingException if the index is nothing. */ - long get(long index) throws ValueIsNothingException; + long getItemAsLong(long index) throws ValueIsNothingException; } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnStorage.java index 362503ce27b5..09cc34737ed2 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnStorage.java @@ -3,7 +3,7 @@ import org.enso.table.data.column.storage.type.StorageType; /** Basic interface of a column storage. */ -public interface ColumnStorage { +public interface ColumnStorage { /* Gets the size of the storage. */ long getSize(); @@ -19,5 +19,5 @@ public interface ColumnStorage { boolean isNothing(long index); /* Gets the value at a given index. */ - Object getItemAsObject(long index); + T getItemBoxed(long index); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnStorageWithNothingMap.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnStorageWithNothingMap.java index 1c2d3c81a9ab..7424af929517 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnStorageWithNothingMap.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnStorageWithNothingMap.java @@ -2,7 +2,7 @@ import java.util.BitSet; -public interface ColumnStorageWithNothingMap extends ColumnStorage { +public interface ColumnStorageWithNothingMap { /** Gets the isNothing map for the storage. */ BitSet getIsNothingMap(); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/MixedStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/MixedStorage.java index 331eccc34981..79bb0b76c846 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/MixedStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/MixedStorage.java @@ -19,7 +19,7 @@ * specific type. */ public final class MixedStorage extends ObjectStorage implements ColumnStorageWithInferredStorage { - private StorageType inferredType = null; + private StorageType inferredType; /** * Holds a specialized storage for the inferred type, if available. @@ -29,8 +29,7 @@ public final class MixedStorage extends ObjectStorage implements ColumnStorageWi * inferred type. This allows it to support operations of that type. * *

Once the specialized storage is first computed, all vectorized operations will be forwarded - * to it - assuming that it will most likely provide more efficient implementations, even for - * operations that are also defined on ObjectStorage. + * to it - assuming that it will most likely provide more efficient implementations. */ private Storage cachedInferredStorage = null; @@ -38,16 +37,15 @@ public final class MixedStorage extends ObjectStorage implements ColumnStorageWi /** * @param data the underlying data - * @param size the number of items stored */ - public MixedStorage(Object[] data, int size) { - super(data, size); + public MixedStorage(Object[] data) { + super(data); inferredType = null; } @Override - protected SpecializedStorage newInstance(Object[] data, int size) { - return new MixedStorage(data, size); + protected SpecializedStorage newInstance(Object[] data) { + return new MixedStorage(data); } private boolean isNumeric(StorageType type) { @@ -79,7 +77,7 @@ public StorageType inferPreciseType() { StorageType currentType = null; Context context = Context.getCurrent(); - for (int i = 0; i < size(); i++) { + for (long i = 0; i < getSize(); i++) { var item = getItemBoxed(i); if (item == null) { continue; @@ -133,8 +131,8 @@ public Storage getInferredStorage() { // for purposes of a // computation. Builder builder = - Builder.getForType(inferredType, size(), BlackholeProblemAggregator.INSTANCE); - for (int i = 0; i < size(); i++) { + Builder.getForType(inferredType, getSize(), BlackholeProblemAggregator.INSTANCE); + for (long i = 0; i < getSize(); i++) { builder.append(getItemBoxed(i)); } cachedInferredStorage = builder.seal(); diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/MixedStorageFacade.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/MixedStorageFacade.java index aa728f3b8f34..584e3b14638a 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/MixedStorageFacade.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/MixedStorageFacade.java @@ -22,8 +22,8 @@ public MixedStorageFacade(Storage storage) { } @Override - public int size() { - return underlyingStorage.size(); + public long getSize() { + return underlyingStorage.getSize(); } @Override @@ -47,7 +47,7 @@ public boolean isNothing(long idx) { } @Override - public Object getItemBoxed(int idx) { + public Object getItemBoxed(long idx) { return underlyingStorage.getItemBoxed(idx); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/NullStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/NullStorage.java index 085ecc24b490..d76901955b4b 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/NullStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/NullStorage.java @@ -16,15 +16,15 @@ /** A specialized storage that can be used by columns that contain only null values. */ public class NullStorage extends Storage { - private final int size; + private final long size; private final MapOperationStorage ops = buildOps(); - public NullStorage(int size) { + public NullStorage(long size) { this.size = size; } @Override - public int size() { + public long getSize() { return size; } @@ -35,11 +35,17 @@ public StorageType getType() { @Override public boolean isNothing(long index) { + if (index < 0 || index >= getSize()) { + throw new IndexOutOfBoundsException(index); + } return true; } @Override - public Void getItemBoxed(int idx) { + public Void getItemBoxed(long idx) { + if (idx < 0 || idx >= getSize()) { + throw new IndexOutOfBoundsException(idx); + } return null; } @@ -170,7 +176,8 @@ public CoalescingNullOp(String name) { @Override public Storage runBinaryMap( NullStorage storage, Object arg, MapOperationProblemAggregator problemAggregator) { - return Storage.fromRepeatedItem(Value.asValue(arg), storage.size(), problemAggregator); + int checkedSize = Builder.checkSize(storage.getSize()); + return Storage.fromRepeatedItem(Value.asValue(arg), checkedSize, problemAggregator); } @Override @@ -191,10 +198,10 @@ public BoolAndNullOp(String name) { public Storage runBinaryMap( NullStorage storage, Object arg, MapOperationProblemAggregator problemAggregator) { if (arg == null) { - return new NullStorage(storage.size()); + return new NullStorage(storage.getSize()); } else if (arg instanceof Boolean b) { - return Storage.fromRepeatedItem( - Value.asValue(doBool(b)), storage.size(), problemAggregator); + int checkedSize = Builder.checkSize(storage.getSize()); + return Storage.fromRepeatedItem(Value.asValue(doBool(b)), checkedSize, problemAggregator); } else { throw new UnexpectedTypeException("Boolean", arg.toString()); } @@ -203,8 +210,8 @@ public Storage runBinaryMap( @Override public Storage runZip( NullStorage storage, Storage arg, MapOperationProblemAggregator problemAggregator) { - BuilderForBoolean builder = Builder.getForBoolean(storage.size()); - for (int i = 0; i < storage.size(); i++) { + BuilderForBoolean builder = Builder.getForBoolean(storage.getSize()); + for (long i = 0; i < storage.getSize(); i++) { if (arg.isNothing(i)) { builder.appendNulls(1); } else if (arg.getItemBoxed(i) instanceof Boolean bool) { diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/ObjectStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/ObjectStorage.java index 6830baca374a..30bd39654669 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/ObjectStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/ObjectStorage.java @@ -2,35 +2,26 @@ import org.enso.table.data.column.operation.map.MapOperationStorage; import org.enso.table.data.column.storage.type.AnyObjectType; -import org.enso.table.data.column.storage.type.StorageType; /** A column storing arbitrary Java objects. */ public sealed class ObjectStorage extends SpecializedStorage permits MixedStorage { + /** An empty object storage. */ + public static ObjectStorage EMPTY = new ObjectStorage(new Object[0]); + /** * @param data the underlying data - * @param size the number of items stored */ - public ObjectStorage(Object[] data, int size) { - super(data, size, buildObjectOps()); + public ObjectStorage(Object[] data) { + super(AnyObjectType.INSTANCE, data, new MapOperationStorage<>()); } @Override - protected SpecializedStorage newInstance(Object[] data, int size) { - return new ObjectStorage(data, size); + protected SpecializedStorage newInstance(Object[] data) { + return new ObjectStorage(data); } @Override protected Object[] newUnderlyingArray(int size) { return new Object[size]; } - - @Override - public StorageType getType() { - return AnyObjectType.INSTANCE; - } - - public static > MapOperationStorage buildObjectOps() { - MapOperationStorage ops = new MapOperationStorage<>(); - return ops; - } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/SpecializedStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/SpecializedStorage.java index 43f06ac4fa5c..a39e08b36c4f 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/SpecializedStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/SpecializedStorage.java @@ -1,6 +1,5 @@ package org.enso.table.data.column.storage; -import java.util.AbstractList; import java.util.BitSet; import java.util.List; import org.enso.table.data.column.operation.CountNothing; @@ -13,52 +12,49 @@ public abstract class SpecializedStorage extends Storage { - protected abstract SpecializedStorage newInstance(T[] data, int size); + protected abstract SpecializedStorage newInstance(T[] data); protected abstract T[] newUnderlyingArray(int size); - @Override - public abstract StorageType getType(); - /** * @param data the underlying data - * @param size the number of items stored + * @param ops the operations supported by this storage */ protected SpecializedStorage( - T[] data, int size, MapOperationStorage> ops) { + StorageType type, T[] data, MapOperationStorage> ops) { + this.type = type; this.data = data; - this.size = size; this.ops = ops; } protected final T[] data; - protected final int size; + private final StorageType type; private final MapOperationStorage> ops; - /** - * @inheritDoc - */ @Override - public int size() { - return size; + public final long getSize() { + return data.length; + } + + @Override + public StorageType getType() { + return type; } /** * @param idx an index * @return the data item contained at the given index. */ - public T getItem(long idx) { + public T getItemBoxed(long idx) { + if (idx < 0 || idx >= data.length) { + throw new IndexOutOfBoundsException(idx); + } return data[(int) idx]; } - @Override - public T getItemBoxed(int idx) { - return data[idx]; - } - @Override public boolean isNothing(long idx) { - return data[(int) idx] == null; + return this.getItemBoxed(idx) == null; } @Override @@ -97,14 +93,14 @@ public SpecializedStorage applyFilter(BitSet filterMask, int newLength) { Context context = Context.getCurrent(); T[] newData = newUnderlyingArray(newLength); int resIx = 0; - for (int i = 0; i < size; i++) { + for (int i = 0; i < data.length; i++) { if (filterMask.get(i)) { newData[resIx++] = data[i]; } context.safepoint(); } - return newInstance(newData, newLength); + return newInstance(newData); } @Override @@ -116,7 +112,7 @@ public SpecializedStorage applyMask(OrderMask mask) { newData[i] = position == OrderMask.NOT_FOUND_INDEX ? null : data[position]; context.safepoint(); } - return newInstance(newData, newData.length); + return newInstance(newData); } public T[] getData() { @@ -125,10 +121,10 @@ public T[] getData() { @Override public SpecializedStorage slice(int offset, int limit) { - int newSize = Math.min(size - offset, limit); + int newSize = Math.min(data.length - offset, limit); T[] newData = newUnderlyingArray(newSize); System.arraycopy(data, offset, newData, 0, newSize); - return newInstance(newData, newSize); + return newInstance(newData); } @Override @@ -144,14 +140,14 @@ public SpecializedStorage slice(List ranges) { context.safepoint(); } - return newInstance(newData, newSize); + return newInstance(newData); } @Override public Storage appendNulls(int count) { - T[] newData = newUnderlyingArray(size + count); - System.arraycopy(data, 0, newData, 0, size); - return newInstance(newData, size + count); + T[] newData = newUnderlyingArray(data.length + count); + System.arraycopy(data, 0, newData, 0, data.length); + return newInstance(newData); } @Override @@ -161,14 +157,14 @@ public Storage fillMissingFromPrevious(BoolStorage missingIndicator) { "Missing indicator must not contain missing values itself."); } - T[] newData = newUnderlyingArray(size); + T[] newData = newUnderlyingArray(data.length); T previous = null; boolean hasPrevious = false; Context context = Context.getCurrent(); - for (int i = 0; i < size; i++) { + for (int i = 0; i < data.length; i++) { boolean isCurrentValueMissing = - missingIndicator == null ? isNothing(i) : missingIndicator.getItem(i); + missingIndicator == null ? isNothing(i) : missingIndicator.getItemAsBoolean(i); if (!isCurrentValueMissing) { previous = data[i]; hasPrevious = true; @@ -178,30 +174,7 @@ public Storage fillMissingFromPrevious(BoolStorage missingIndicator) { context.safepoint(); } - return newInstance(newData, size); - } - - @Override - public List toList() { - return new ReadOnlyList<>(this); - } - - private static class ReadOnlyList extends AbstractList { - private final SpecializedStorage storage; - - public ReadOnlyList(SpecializedStorage storage) { - this.storage = storage; - } - - @Override - public Object get(int index) { - return storage.getItemBoxed(index); - } - - @Override - public int size() { - return storage.size(); - } + return newInstance(newData); } /** diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/Storage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/Storage.java index b8f7b7cf8e44..d6958b036767 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/Storage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/Storage.java @@ -10,29 +10,38 @@ import org.enso.table.data.column.operation.cast.StorageConverter; import org.enso.table.data.column.operation.map.MapOperationProblemAggregator; import org.enso.table.data.column.storage.numeric.LongConstantStorage; -import org.enso.table.data.column.storage.numeric.LongStorage; import org.enso.table.data.column.storage.type.IntegerType; import org.enso.table.data.column.storage.type.StorageType; import org.enso.table.data.mask.OrderMask; import org.enso.table.data.mask.SliceRange; +import org.enso.table.problems.BlackholeProblemAggregator; import org.enso.table.problems.ProblemAggregator; import org.graalvm.polyglot.Context; import org.graalvm.polyglot.Value; /** An abstract representation of a data column. */ -public abstract class Storage implements ColumnStorage { +public abstract class Storage implements ColumnStorage { + @Override + public abstract long getSize(); + + @Override + public abstract StorageType getType(); + /** - * @return the number of elements in this column (including NAs) + * Returns a more specialized storage, if available. + * + *

This storage should have the same type as returned by {@code inferPreciseType}. See {@link + * MixedStorage} for more information. */ - public abstract int size(); + public Storage tryGettingMoreSpecializedStorage() { + return this; + } @Override - public long getSize() { - return size(); - } + public abstract boolean isNothing(long index); @Override - public abstract StorageType getType(); + public abstract T getItemBoxed(long index); /** * @return the type of the values in this column's storage. Most storages just return their type. @@ -55,27 +64,6 @@ public StorageType inferPreciseTypeShrunk() { return getType(); } - /** - * Returns a more specialized storage, if available. - * - *

This storage should have the same type as returned by {@code inferPreciseType}. See {@link - * MixedStorage} for more information. - */ - public Storage tryGettingMoreSpecializedStorage() { - return this; - } - - @Override - public abstract boolean isNothing(long index); - - /** - * Returns a boxed representation of an item. Missing values are denoted with null. - * - * @param idx the index to look up - * @return the item at position {@code idx} - */ - public abstract T getItemBoxed(int idx); - /** A container for names of vectorizable operation. */ public static final class Maps { public static final String EQ = "=="; @@ -148,14 +136,15 @@ public final Storage binaryMap( boolean skipNulls, StorageType expectedResultType, ProblemAggregator problemAggregator) { - Builder storageBuilder = Builder.getForType(expectedResultType, size(), problemAggregator); + Builder storageBuilder = Builder.getForType(expectedResultType, getSize(), problemAggregator); if (skipNulls && argument == null) { - storageBuilder.appendNulls(size()); + // ToDo: appendNulls should take a long, not an int. Should have a constant Storage for null. + storageBuilder.appendNulls((int) getSize()); return storageBuilder.seal(); } Context context = Context.getCurrent(); - for (int i = 0; i < size(); i++) { + for (long i = 0; i < getSize(); i++) { Object it = getItemBoxed(i); if (skipNulls && it == null) { storageBuilder.appendNulls(1); @@ -185,11 +174,11 @@ public final Storage zip( boolean skipNa, StorageType expectedResultType, ProblemAggregator problemAggregator) { - Builder storageBuilder = Builder.getForType(expectedResultType, size(), problemAggregator); + Builder storageBuilder = Builder.getForType(expectedResultType, getSize(), problemAggregator); Context context = Context.getCurrent(); - for (int i = 0; i < size(); i++) { + for (long i = 0; i < getSize(); i++) { Object it1 = getItemBoxed(i); - Object it2 = i < arg.size() ? arg.getItemBoxed(i) : null; + Object it2 = i < arg.getSize() ? arg.getItemBoxed(i) : null; if (skipNa && (it1 == null || it2 == null)) { storageBuilder.appendNulls(1); } else { @@ -325,10 +314,10 @@ private void checkFallback(Object fallback, StorageType storageType, String oper */ public Storage fillMissing( Value arg, StorageType commonType, ProblemAggregator problemAggregator) { - Builder builder = Builder.getForType(commonType, size(), problemAggregator); + Builder builder = Builder.getForType(commonType, getSize(), problemAggregator); Object convertedFallback = Polyglot_Utils.convertPolyglotValue(arg); Context context = Context.getCurrent(); - for (int i = 0; i < size(); i++) { + for (long i = 0; i < getSize(); i++) { Object it = getItemBoxed(i); builder.append(it == null ? convertedFallback : it); context.safepoint(); @@ -346,13 +335,12 @@ public Storage fillMissing( */ public Storage fillMissingFrom( Storage other, StorageType commonType, ProblemAggregator problemAggregator) { - var builder = Builder.getForType(commonType, size(), problemAggregator); + var builder = Builder.getForType(commonType, getSize(), problemAggregator); Context context = Context.getCurrent(); - for (int i = 0; i < size(); i++) { + for (long i = 0; i < getSize(); i++) { builder.append(isNothing(i) ? other.getItemBoxed(i) : getItemBoxed(i)); context.safepoint(); } - return builder.seal(); } @@ -410,17 +398,18 @@ public List toList() { * @return a storage counting the number of times each value in this one has been seen before. */ public Storage duplicateCount() { - long[] data = new long[size()]; HashMap occurenceCount = new HashMap<>(); Context context = Context.getCurrent(); - for (int i = 0; i < size(); i++) { + var builder = + Builder.getForLong(IntegerType.INT_64, getSize(), BlackholeProblemAggregator.INSTANCE); + for (long i = 0; i < getSize(); i++) { var value = getItemBoxed(i); var count = occurenceCount.getOrDefault(value, 0); - data[i] = count; + builder.appendLong(count); occurenceCount.put(value, count + 1); context.safepoint(); } - return new LongStorage(data, IntegerType.INT_64); + return builder.seal(); } public final Storage cast( @@ -429,11 +418,6 @@ public final Storage cast( return converter.cast(this, castProblemAggregator); } - @Override - public Object getItemAsObject(long index) { - return getItemBoxed((int) index); - } - /** Creates a storage containing a single repeated item. */ public static Storage fromRepeatedItem( Value item, int repeat, ProblemAggregator problemAggregator) { diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/StorageListView.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/StorageListView.java index 1de25bb6a21c..a75b97691dfa 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/StorageListView.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/StorageListView.java @@ -22,7 +22,7 @@ public class StorageListView implements List { * @param storage the storage to wrap. */ public StorageListView(Storage storage) { - this(storage, 0, storage.size()); + this(storage, 0, Math.toIntExact(storage.getSize())); } private StorageListView(Storage storage, int from, int to) { diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/StringStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/StringStorage.java index b7268a8f431f..ed6b87e6c89d 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/StringStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/StringStorage.java @@ -1,11 +1,11 @@ package org.enso.table.data.column.storage; -import java.util.BitSet; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import org.enso.base.CompareException; import org.enso.base.Text_Utils; +import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.operation.CountUntrimmed; import org.enso.table.data.column.operation.map.BinaryMapOperation; import org.enso.table.data.column.operation.map.MapOperationProblemAggregator; @@ -24,37 +24,39 @@ /** A column storing strings. */ public final class StringStorage extends SpecializedStorage { private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(StringStorage.class); - - private final TextType type; private Future untrimmedCount; /** * @param data the underlying data - * @param size the number of items stored * @param type the type of the column */ - public StringStorage(String[] data, int size, TextType type) { - super(data, size, buildOps()); - this.type = type; + public StringStorage(String[] data, TextType type) { + super(type, data, buildOps()); untrimmedCount = CompletableFuture.supplyAsync( () -> CountUntrimmed.compute(this, CountUntrimmed.DEFAULT_SAMPLE_SIZE, null)); } + public static StringStorage makeEmpty(TextType type, long size) { + int intSize = Builder.checkSize(size); + return new StringStorage(new String[intSize], type); + } + @Override - protected SpecializedStorage newInstance(String[] data, int size) { - return new StringStorage(data, size, type); + public TextType getType() { + // As the type is fixed, we can safely cast it. + return (TextType) super.getType(); } @Override - protected String[] newUnderlyingArray(int size) { - return new String[size]; + protected SpecializedStorage newInstance(String[] data) { + return new StringStorage(data, getType()); } @Override - public TextType getType() { - return type; + protected String[] newUnderlyingArray(int size) { + return new String[size]; } /** @@ -81,48 +83,48 @@ public Long cachedUntrimmedCount() throws InterruptedException { } private static MapOperationStorage> buildOps() { - MapOperationStorage> t = ObjectStorage.buildObjectOps(); + MapOperationStorage> t = new MapOperationStorage<>(); t.add( new BinaryMapOperation<>(Maps.EQ) { @Override - public BoolStorage runBinaryMap( + public Storage runBinaryMap( SpecializedStorage storage, Object arg, MapOperationProblemAggregator problemAggregator) { - BitSet r = new BitSet(); - BitSet isNothing = new BitSet(); + long size = storage.getSize(); + var builder = Builder.getForBoolean(size); Context context = Context.getCurrent(); - for (int i = 0; i < storage.size(); i++) { - if (storage.getItem(i) == null || arg == null) { - isNothing.set(i); - } else if (arg instanceof String s && Text_Utils.equals(storage.getItem(i), s)) { - r.set(i); + for (long i = 0; i < size; i++) { + if (storage.getItemBoxed(i) == null || arg == null) { + builder.appendNulls(1); + } else { + builder.appendBoolean( + arg instanceof String s && Text_Utils.equals(storage.getItemBoxed(i), s)); } - context.safepoint(); } - return new BoolStorage(r, isNothing, storage.size(), false); + return builder.seal(); } @Override - public BoolStorage runZip( + public Storage runZip( SpecializedStorage storage, Storage arg, MapOperationProblemAggregator problemAggregator) { - BitSet r = new BitSet(); - BitSet isNothing = new BitSet(); + long size = storage.getSize(); + var builder = Builder.getForBoolean(size); Context context = Context.getCurrent(); - for (int i = 0; i < storage.size(); i++) { - if (storage.getItem(i) == null || i >= arg.size() || arg.isNothing(i)) { - isNothing.set(i); - } else if (arg.getItemBoxed(i) instanceof String s - && Text_Utils.equals(storage.getItem(i), s)) { - r.set(i); + for (long i = 0; i < size; i++) { + if (storage.getItemBoxed(i) == null || i >= arg.getSize() || arg.isNothing(i)) { + builder.appendNulls(1); + } else { + builder.appendBoolean( + arg.getItemBoxed(i) instanceof String s + && Text_Utils.equals(storage.getItemBoxed(i), s)); } - context.safepoint(); } - return new BoolStorage(r, isNothing, storage.size(), false); + return builder.seal(); } }); t.add( @@ -239,14 +241,15 @@ protected TextType computeResultType(TextType a, TextType b) { @Override public StorageType inferPreciseTypeShrunk() { + var type = getType(); if (type.fixedLength()) { return type; } long minLength = Long.MAX_VALUE; long maxLength = Long.MIN_VALUE; - for (int i = 0; i < size(); i++) { - String s = getItem(i); + for (long i = 0; i < getSize(); i++) { + String s = getItemBoxed(i); if (s != null) { long length = Text_Utils.grapheme_length(s); minLength = Math.min(minLength, length); diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/datetime/DateStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/datetime/DateStorage.java index 2f6687b5a195..fe1183c25fd8 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/datetime/DateStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/datetime/DateStorage.java @@ -7,23 +7,19 @@ import org.enso.table.data.column.operation.map.datetime.DateTimeIsInOp; import org.enso.table.data.column.operation.map.datetime.TimeLikeBinaryOpReturningBoolean; import org.enso.table.data.column.operation.map.datetime.TimeLikeCoalescingOperation; -import org.enso.table.data.column.storage.ObjectStorage; import org.enso.table.data.column.storage.SpecializedStorage; import org.enso.table.data.column.storage.type.DateType; -import org.enso.table.data.column.storage.type.StorageType; public final class DateStorage extends SpecializedStorage { /** * @param data the underlying data - * @param size the number of items stored */ - public DateStorage(LocalDate[] data, int size) { - super(data, size, buildOps()); + public DateStorage(LocalDate[] data) { + super(DateType.INSTANCE, data, buildOps()); } private static MapOperationStorage> buildOps() { - MapOperationStorage> t = - ObjectStorage.buildObjectOps(); + MapOperationStorage> t = new MapOperationStorage<>(); t.add(new DateTimeIsInOp<>(LocalDate.class)); t.add( new TimeLikeBinaryOpReturningBoolean<>(Maps.EQ, LocalDate.class) { @@ -68,8 +64,8 @@ protected boolean doOperation(LocalDate a, LocalDate b) { t.add( new TimeLikeCoalescingOperation<>(Maps.MIN, LocalDate.class) { @Override - protected Builder createOutputBuilder(int size) { - return Builder.getForType(DateType.INSTANCE, size, null); + protected Builder createOutputBuilder(long size) { + return Builder.getForDate(size); } @Override @@ -80,8 +76,8 @@ protected LocalDate doOperation(LocalDate a, LocalDate b) { t.add( new TimeLikeCoalescingOperation<>(Maps.MAX, LocalDate.class) { @Override - protected Builder createOutputBuilder(int size) { - return Builder.getForType(DateType.INSTANCE, size, null); + protected Builder createOutputBuilder(long size) { + return Builder.getForDate(size); } @Override @@ -93,8 +89,8 @@ protected LocalDate doOperation(LocalDate a, LocalDate b) { } @Override - protected SpecializedStorage newInstance(LocalDate[] data, int size) { - return new DateStorage(data, size); + protected SpecializedStorage newInstance(LocalDate[] data) { + return new DateStorage(data); } @Override @@ -102,11 +98,6 @@ protected LocalDate[] newUnderlyingArray(int size) { return new LocalDate[size]; } - @Override - public StorageType getType() { - return DateType.INSTANCE; - } - private abstract static class DateComparisonOp extends TimeLikeBinaryOpReturningBoolean { public DateComparisonOp(String name) { diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/datetime/DateTimeStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/datetime/DateTimeStorage.java index 649d675971a8..dd94258cd563 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/datetime/DateTimeStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/datetime/DateTimeStorage.java @@ -9,23 +9,20 @@ import org.enso.table.data.column.operation.map.datetime.DateTimeIsInOp; import org.enso.table.data.column.operation.map.datetime.TimeLikeBinaryOpReturningBoolean; import org.enso.table.data.column.operation.map.datetime.TimeLikeCoalescingOperation; -import org.enso.table.data.column.storage.ObjectStorage; import org.enso.table.data.column.storage.SpecializedStorage; import org.enso.table.data.column.storage.type.DateTimeType; -import org.enso.table.data.column.storage.type.StorageType; public final class DateTimeStorage extends SpecializedStorage { /** * @param data the underlying data - * @param size the number of items stored */ - public DateTimeStorage(ZonedDateTime[] data, int size) { - super(data, size, buildOps()); + public DateTimeStorage(ZonedDateTime[] data) { + super(DateTimeType.INSTANCE, data, buildOps()); } private static MapOperationStorage> buildOps() { MapOperationStorage> t = - ObjectStorage.buildObjectOps(); + new MapOperationStorage<>(); t.add(new DateTimeIsInOp<>(ZonedDateTime.class)); t.add( new TimeLikeBinaryOpReturningBoolean<>(Maps.EQ, ZonedDateTime.class) { @@ -72,7 +69,7 @@ protected boolean doOperation(ZonedDateTime a, ZonedDateTime b) { ZonedDateTime, SpecializedStorage, Duration>( Maps.SUB, ZonedDateTime.class, DateTimeStorage.class) { @Override - protected Builder createOutputBuilder(int size) { + protected Builder createOutputBuilder(long size) { return Builder.getObjectBuilder(size); } @@ -84,8 +81,8 @@ protected Duration run(ZonedDateTime value, ZonedDateTime other) { t.add( new TimeLikeCoalescingOperation<>(Maps.MIN, ZonedDateTime.class) { @Override - protected Builder createOutputBuilder(int size) { - return Builder.getForType(DateTimeType.INSTANCE, size, null); + protected Builder createOutputBuilder(long size) { + return Builder.getForDateTime(size); } @Override @@ -96,8 +93,8 @@ protected ZonedDateTime doOperation(ZonedDateTime a, ZonedDateTime b) { t.add( new TimeLikeCoalescingOperation<>(Maps.MAX, ZonedDateTime.class) { @Override - protected Builder createOutputBuilder(int size) { - return Builder.getForType(DateTimeType.INSTANCE, size, null); + protected Builder createOutputBuilder(long size) { + return Builder.getForDateTime(size); } @Override @@ -109,8 +106,8 @@ protected ZonedDateTime doOperation(ZonedDateTime a, ZonedDateTime b) { } @Override - protected SpecializedStorage newInstance(ZonedDateTime[] data, int size) { - return new DateTimeStorage(data, size); + protected SpecializedStorage newInstance(ZonedDateTime[] data) { + return new DateTimeStorage(data); } @Override @@ -118,11 +115,6 @@ protected ZonedDateTime[] newUnderlyingArray(int size) { return new ZonedDateTime[size]; } - @Override - public StorageType getType() { - return DateTimeType.INSTANCE; - } - private abstract static class DateTimeComparisonOp extends TimeLikeBinaryOpReturningBoolean { public DateTimeComparisonOp(String name) { diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/datetime/TimeOfDayStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/datetime/TimeOfDayStorage.java index c63df48f5c1a..eea97c07311a 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/datetime/TimeOfDayStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/datetime/TimeOfDayStorage.java @@ -9,23 +9,19 @@ import org.enso.table.data.column.operation.map.datetime.DateTimeIsInOp; import org.enso.table.data.column.operation.map.datetime.TimeLikeBinaryOpReturningBoolean; import org.enso.table.data.column.operation.map.datetime.TimeLikeCoalescingOperation; -import org.enso.table.data.column.storage.ObjectStorage; import org.enso.table.data.column.storage.SpecializedStorage; -import org.enso.table.data.column.storage.type.StorageType; import org.enso.table.data.column.storage.type.TimeOfDayType; public final class TimeOfDayStorage extends SpecializedStorage { /** * @param data the underlying data - * @param size the number of items stored */ - public TimeOfDayStorage(LocalTime[] data, int size) { - super(data, size, buildOps()); + public TimeOfDayStorage(LocalTime[] data) { + super(TimeOfDayType.INSTANCE, data, buildOps()); } private static MapOperationStorage> buildOps() { - MapOperationStorage> t = - ObjectStorage.buildObjectOps(); + MapOperationStorage> t = new MapOperationStorage<>(); t.add(new DateTimeIsInOp<>(LocalTime.class)); t.add( new TimeLikeBinaryOpReturningBoolean<>(Maps.EQ, LocalTime.class) { @@ -71,7 +67,7 @@ protected boolean doOperation(LocalTime a, LocalTime b) { new GenericBinaryObjectMapOperation, Duration>( Maps.SUB, LocalTime.class, TimeOfDayStorage.class) { @Override - protected Builder createOutputBuilder(int size) { + protected Builder createOutputBuilder(long size) { return Builder.getObjectBuilder(size); } @@ -83,8 +79,8 @@ protected Duration run(LocalTime value, LocalTime other) { t.add( new TimeLikeCoalescingOperation<>(Maps.MIN, LocalTime.class) { @Override - protected Builder createOutputBuilder(int size) { - return Builder.getForType(TimeOfDayType.INSTANCE, size, null); + protected Builder createOutputBuilder(long size) { + return Builder.getForTime(size); } @Override @@ -95,8 +91,8 @@ protected LocalTime doOperation(LocalTime a, LocalTime b) { t.add( new TimeLikeCoalescingOperation<>(Maps.MAX, LocalTime.class) { @Override - protected Builder createOutputBuilder(int size) { - return Builder.getForType(TimeOfDayType.INSTANCE, size, null); + protected Builder createOutputBuilder(long size) { + return Builder.getForTime(size); } @Override @@ -108,8 +104,8 @@ protected LocalTime doOperation(LocalTime a, LocalTime b) { } @Override - protected SpecializedStorage newInstance(LocalTime[] data, int size) { - return new TimeOfDayStorage(data, size); + protected SpecializedStorage newInstance(LocalTime[] data) { + return new TimeOfDayStorage(data); } @Override @@ -117,11 +113,6 @@ protected LocalTime[] newUnderlyingArray(int size) { return new LocalTime[size]; } - @Override - public StorageType getType() { - return TimeOfDayType.INSTANCE; - } - private abstract static class TimeOfDayComparisonOp extends TimeLikeBinaryOpReturningBoolean { public TimeOfDayComparisonOp(String name) { diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/AbstractLongStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/AbstractLongStorage.java index 4d89175a03d9..e27c73a26e80 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/AbstractLongStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/AbstractLongStorage.java @@ -1,6 +1,8 @@ package org.enso.table.data.column.storage.numeric; import java.util.BitSet; +import java.util.List; +import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.operation.map.MapOperationProblemAggregator; import org.enso.table.data.column.operation.map.MapOperationStorage; import org.enso.table.data.column.operation.map.numeric.LongRoundOp; @@ -18,17 +20,49 @@ import org.enso.table.data.column.operation.map.numeric.comparisons.LessComparison; import org.enso.table.data.column.operation.map.numeric.comparisons.LessOrEqualComparison; import org.enso.table.data.column.operation.map.numeric.isin.LongIsInOp; -import org.enso.table.data.column.storage.*; +import org.enso.table.data.column.storage.BoolStorage; +import org.enso.table.data.column.storage.ColumnLongStorage; +import org.enso.table.data.column.storage.Storage; +import org.enso.table.data.column.storage.ValueIsNothingException; import org.enso.table.data.column.storage.type.IntegerType; import org.enso.table.data.column.storage.type.StorageType; +import org.enso.table.data.mask.OrderMask; +import org.enso.table.data.mask.SliceRange; +import org.enso.table.problems.BlackholeProblemAggregator; import org.graalvm.polyglot.Context; -public abstract class AbstractLongStorage extends NumericStorage - implements ColumnLongStorage, ColumnStorageWithNothingMap { - public abstract long getItem(int idx); - +public abstract class AbstractLongStorage extends Storage implements ColumnLongStorage { private static final MapOperationStorage ops = buildOps(); + private final long size; + private final IntegerType type; + + protected AbstractLongStorage(long size, IntegerType type) { + this.size = size; + this.type = type; + } + + @Override + public final long getSize() { + return size; + } + + @Override + public IntegerType getType() { + return type; + } + + @Override + public Long getItemBoxed(long index) { + return isNothing(index) ? null : getItemAsLong(index); + } + + @Override + public abstract boolean isNothing(long idx); + + @Override + public abstract long getItemAsLong(long index) throws ValueIsNothingException; + @Override public boolean isBinaryOpVectorized(String name) { return ops.isSupportedBinary(name); @@ -60,9 +94,6 @@ public Storage runVectorizedZip( return ops.runZip(name, this, argument, problemAggregator); } - @Override - public abstract IntegerType getType(); - @Override public StorageType inferPreciseType() { return getType(); @@ -81,14 +112,14 @@ public StorageType inferPreciseTypeShrunk() { new IntegerType[] {IntegerType.INT_16, IntegerType.INT_32, IntegerType.INT_64}; int currentTypeIdx = 0; - int n = size(); + long n = getSize(); Context context = Context.getCurrent(); - for (int i = 0; i < n; i++) { + for (long i = 0; i < n; i++) { if (isNothing(i)) { continue; } - long item = getItem(i); + long item = getItemAsLong(i); while (!possibleTypes[currentTypeIdx].fits(item)) { currentTypeIdx++; } @@ -124,30 +155,29 @@ private static MapOperationStorage buildOps() { } @Override - public AbstractLongStorage fillMissingFromPrevious(BoolStorage missingIndicator) { + public Storage fillMissingFromPrevious(BoolStorage missingIndicator) { if (missingIndicator != null) { throw new IllegalStateException( "Custom missing value semantics are not supported by AbstractLongStorage."); } - int n = size(); - long[] newData = new long[n]; - BitSet newIsNothing = new BitSet(); + long n = getSize(); + var builder = Builder.getForLong(getType(), n, BlackholeProblemAggregator.INSTANCE); long previousValue = 0; boolean hasPrevious = false; Context context = Context.getCurrent(); - for (int i = 0; i < n; i++) { + for (long i = 0; i < n; i++) { boolean isCurrentNothing = isNothing(i); if (isCurrentNothing) { if (hasPrevious) { - newData[i] = previousValue; + builder.appendLong(previousValue); } else { - newIsNothing.set(i); + builder.appendNulls(1); } } else { - long currentValue = getItem(i); - newData[i] = currentValue; + long currentValue = getItemAsLong(i); + builder.appendLong(currentValue); previousValue = currentValue; hasPrevious = true; } @@ -155,7 +185,7 @@ public AbstractLongStorage fillMissingFromPrevious(BoolStorage missingIndicator) context.safepoint(); } - return new LongStorage(newData, n, newIsNothing, getType()); + return builder.seal(); } /** @@ -166,13 +196,90 @@ public AbstractLongStorage fillMissingFromPrevious(BoolStorage missingIndicator) public abstract AbstractLongStorage widen(IntegerType widerType); @Override - public long get(long index) throws ValueIsNothingException { - if (isNothing(index)) { - throw new ValueIsNothingException(index); + public Storage applyFilter(BitSet filterMask, int newLength) { + var builder = Builder.getForLong(getType(), newLength, BlackholeProblemAggregator.INSTANCE); + Context context = Context.getCurrent(); + for (int i = 0; i < getSize(); i++) { + if (filterMask.get(i)) { + if (isNothing(i)) { + builder.appendNulls(1); + } else { + builder.appendLong(getItemAsLong(i)); + } + } + + context.safepoint(); + } + return builder.seal(); + } + + @Override + public Storage applyMask(OrderMask mask) { + var builder = Builder.getForLong(getType(), mask.length(), BlackholeProblemAggregator.INSTANCE); + Context context = Context.getCurrent(); + for (int i = 0; i < mask.length(); i++) { + int position = mask.get(i); + if (position == OrderMask.NOT_FOUND_INDEX || isNothing(position)) { + builder.appendNulls(1); + } else { + builder.appendLong(getItemAsLong(position)); + } + + context.safepoint(); } - return getItem((int) index); + return builder.seal(); } @Override - public abstract BitSet getIsNothingMap(); + public Storage slice(int offset, int limit) { + int size = (int) getSize(); + int newSize = Math.min(size - offset, limit); + var builder = Builder.getForLong(getType(), newSize, BlackholeProblemAggregator.INSTANCE); + Context context = Context.getCurrent(); + for (int i = 0; i < newSize; i++) { + if (isNothing(offset + i)) { + builder.appendNulls(1); + } else { + builder.appendLong(getItemAsLong(offset + i)); + } + context.safepoint(); + } + return builder.seal(); + } + + @Override + public Storage slice(List ranges) { + int newSize = SliceRange.totalLength(ranges); + var builder = Builder.getForLong(getType(), newSize, BlackholeProblemAggregator.INSTANCE); + Context context = Context.getCurrent(); + for (SliceRange range : ranges) { + int rangeStart = range.start(); + int length = range.end() - rangeStart; + for (int i = 0; i < length; i++) { + if (isNothing(rangeStart + i)) { + builder.appendNulls(1); + } else { + builder.appendLong(getItemAsLong(rangeStart + i)); + } + context.safepoint(); + } + } + return builder.seal(); + } + + @Override + public Storage appendNulls(int count) { + final AbstractLongStorage parent = this; + int size = (int) parent.getSize(); + return new ComputedNullableLongStorage(size + count) { + @Override + protected Long computeItem(int idx) { + if (idx < size) { + return parent.getItemBoxed(idx); + } else { + return null; + } + } + }; + } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/BigDecimalStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/BigDecimalStorage.java index 2b7a07ea54e3..78e51fe886ef 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/BigDecimalStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/BigDecimalStorage.java @@ -1,6 +1,7 @@ package org.enso.table.data.column.storage.numeric; import java.math.BigDecimal; +import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.operation.map.MapOperationStorage; import org.enso.table.data.column.operation.map.numeric.BigDecimalRoundOp; import org.enso.table.data.column.operation.map.numeric.arithmetic.AddOp; @@ -16,27 +17,25 @@ import org.enso.table.data.column.operation.map.numeric.comparisons.GreaterOrEqualComparison; import org.enso.table.data.column.operation.map.numeric.comparisons.LessComparison; import org.enso.table.data.column.operation.map.numeric.comparisons.LessOrEqualComparison; -import org.enso.table.data.column.storage.ObjectStorage; import org.enso.table.data.column.storage.SpecializedStorage; import org.enso.table.data.column.storage.type.BigDecimalType; -import org.enso.table.data.column.storage.type.StorageType; public final class BigDecimalStorage extends SpecializedStorage { /** * @param data the underlying data - * @param size the number of items stored */ - public BigDecimalStorage(BigDecimal[] data, int size) { - super(data, size, buildOps()); + public BigDecimalStorage(BigDecimal[] data) { + super(BigDecimalType.INSTANCE, data, buildOps()); } - public static BigDecimalStorage makeEmpty(int size) { - return new BigDecimalStorage(new BigDecimal[size], size); + public static BigDecimalStorage makeEmpty(long size) { + int intSize = Builder.checkSize(size); + return new BigDecimalStorage(new BigDecimal[intSize]); } private static MapOperationStorage> buildOps() { MapOperationStorage> ops = - ObjectStorage.buildObjectOps(); + new MapOperationStorage<>(); return ops.add(new AddOp<>()) .add(new SubOp<>()) .add(new MulOp<>()) @@ -54,17 +53,12 @@ private static MapOperationStorage> b } @Override - protected SpecializedStorage newInstance(BigDecimal[] data, int size) { - return new BigDecimalStorage(data, size); + protected SpecializedStorage newInstance(BigDecimal[] data) { + return new BigDecimalStorage(data); } @Override protected BigDecimal[] newUnderlyingArray(int size) { return new BigDecimal[size]; } - - @Override - public StorageType getType() { - return BigDecimalType.INSTANCE; - } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/BigIntegerStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/BigIntegerStorage.java index 9f94828729c8..638351d2f51a 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/BigIntegerStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/BigIntegerStorage.java @@ -2,6 +2,7 @@ import java.math.BigDecimal; import java.math.BigInteger; +import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.operation.map.MapOperationStorage; import org.enso.table.data.column.operation.map.numeric.arithmetic.AddOp; import org.enso.table.data.column.operation.map.numeric.arithmetic.DivideOp; @@ -17,7 +18,6 @@ import org.enso.table.data.column.operation.map.numeric.comparisons.LessComparison; import org.enso.table.data.column.operation.map.numeric.comparisons.LessOrEqualComparison; import org.enso.table.data.column.operation.map.numeric.isin.BigIntegerIsInOp; -import org.enso.table.data.column.storage.ObjectStorage; import org.enso.table.data.column.storage.SpecializedStorage; import org.enso.table.data.column.storage.type.BigIntegerType; import org.enso.table.data.column.storage.type.IntegerType; @@ -26,15 +26,14 @@ public class BigIntegerStorage extends SpecializedStorage { /** * @param data the underlying data - * @param size the number of items stored */ - public BigIntegerStorage(BigInteger[] data, int size) { - super(data, size, makeOps()); + public BigIntegerStorage(BigInteger[] data) { + super(BigIntegerType.INSTANCE, data, makeOps()); } protected static MapOperationStorage> makeOps() { MapOperationStorage> ops = - ObjectStorage.buildObjectOps(); + new MapOperationStorage<>(); return ops.add(new AddOp<>()) .add(new SubOp<>()) .add(new MulOp<>()) @@ -51,13 +50,14 @@ protected static MapOperationStorage> .add(new BigIntegerIsInOp<>()); } - public static BigIntegerStorage makeEmpty(int size) { - return new BigIntegerStorage(new BigInteger[size], size); + public static BigIntegerStorage makeEmpty(long size) { + int intSize = Builder.checkSize(size); + return new BigIntegerStorage(new BigInteger[intSize]); } @Override - protected SpecializedStorage newInstance(BigInteger[] data, int size) { - return new BigIntegerStorage(data, size); + protected SpecializedStorage newInstance(BigInteger[] data) { + return new BigIntegerStorage(data); } @Override @@ -65,17 +65,12 @@ protected BigInteger[] newUnderlyingArray(int size) { return new BigInteger[size]; } - @Override - public StorageType getType() { - return BigIntegerType.INSTANCE; - } - private long cachedMaxPrecisionStored = -1; public long getMaxPrecisionStored() { if (cachedMaxPrecisionStored < 0) { long maxPrecision = 0; - for (int i = 0; i < size; i++) { + for (int i = 0; i < getSize(); i++) { BigInteger value = data[i]; if (value == null) { continue; @@ -103,7 +98,7 @@ public StorageType inferPreciseType() { boolean allFitInLong = true; int visitedCount = 0; - for (int i = 0; i < size; i++) { + for (int i = 0; i < getSize(); i++) { BigInteger value = data[i]; if (value == null) { continue; @@ -142,10 +137,10 @@ private StorageType findSmallestIntegerTypeThatFits() { // We create a Long storage that gets values by converting our storage. ComputedNullableLongStorage longAdapter = - new ComputedNullableLongStorage(size) { + new ComputedNullableLongStorage((int) getSize()) { @Override protected Long computeItem(int idx) { - BigInteger bigInteger = parent.getItem(idx); + BigInteger bigInteger = parent.getItemBoxed(idx); if (bigInteger == null) { return null; } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/ComputedLongStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/ComputedLongStorage.java index 93593ab0085b..1e489b5395ce 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/ComputedLongStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/ComputedLongStorage.java @@ -1,125 +1,46 @@ package org.enso.table.data.column.storage.numeric; import java.util.BitSet; -import java.util.List; -import org.enso.table.data.column.storage.Storage; +import org.enso.table.data.column.storage.ColumnStorageWithNothingMap; +import org.enso.table.data.column.storage.ValueIsNothingException; import org.enso.table.data.column.storage.type.IntegerType; -import org.enso.table.data.mask.OrderMask; -import org.enso.table.data.mask.SliceRange; -import org.graalvm.polyglot.Context; /** * Implements a storage that computes the ith stored value using some function. * *

This storage assumes that _all_ values are present. */ -public abstract class ComputedLongStorage extends AbstractLongStorage { - protected final int size; +public abstract class ComputedLongStorage extends AbstractLongStorage + implements ColumnStorageWithNothingMap { + private static final BitSet EMPTY = new BitSet(); protected abstract long computeItem(int idx); protected ComputedLongStorage(int size) { - this.size = size; - } - - @Override - public int size() { - return size; - } - - @Override - public IntegerType getType() { - return IntegerType.INT_64; - } - - @Override - public boolean isNothing(long idx) { - return false; - } - - @Override - public Long getItemBoxed(int idx) { - return getItem(idx); - } - - public long getItem(int idx) { - if (idx < 0 || idx >= size) { - throw new IndexOutOfBoundsException( - "Index " + idx + " is out of bounds for range of length " + size + "."); - } - - return computeItem(idx); - } - - @Override - public Storage applyFilter(BitSet filterMask, int newLength) { - BitSet newIsNothing = new BitSet(); - long[] newData = new long[newLength]; - int resIx = 0; - Context context = Context.getCurrent(); - for (int i = 0; i < size; i++) { - if (filterMask.get(i)) { - newData[resIx++] = getItem(i); - } - - context.safepoint(); - } - return new LongStorage(newData, newLength, newIsNothing, getType()); + super(size, IntegerType.INT_64); } @Override - public Storage applyMask(OrderMask mask) { - long[] newData = new long[mask.length()]; - BitSet newIsNothing = new BitSet(); - Context context = Context.getCurrent(); - for (int i = 0; i < mask.length(); i++) { - int position = mask.get(i); - if (position == OrderMask.NOT_FOUND_INDEX) { - newIsNothing.set(i); - } else { - newData[i] = getItem(position); - } - - context.safepoint(); + public long getItemAsLong(long index) throws ValueIsNothingException { + if (index < 0 || index >= getSize()) { + throw new IndexOutOfBoundsException(index); } - return new LongStorage(newData, newData.length, newIsNothing, getType()); + return computeItem((int) index); } @Override - public Storage slice(int offset, int limit) { - int newSize = Math.min(size - offset, limit); - long[] newData = new long[newSize]; - Context context = Context.getCurrent(); - for (int i = 0; i < newSize; i++) { - newData[i] = getItem(offset + i); - context.safepoint(); + public boolean isNothing(long idx) { + if (idx < 0 || idx >= getSize()) { + throw new IndexOutOfBoundsException(idx); } - BitSet newMask = new BitSet(); - return new LongStorage(newData, newSize, newMask, getType()); + return false; } @Override - public Storage slice(List ranges) { - int newSize = SliceRange.totalLength(ranges); - long[] newData = new long[newSize]; - BitSet newIsNothing = new BitSet(newSize); - int offset = 0; - Context context = Context.getCurrent(); - for (SliceRange range : ranges) { - int rangeStart = range.start(); - int length = range.end() - rangeStart; - for (int i = 0; i < length; i++) { - newData[offset + i] = getItem(rangeStart + i); - context.safepoint(); - } - offset += length; - } - - return new LongStorage(newData, newSize, newIsNothing, getType()); + public BitSet getIsNothingMap() { + return EMPTY; } - private static final BitSet EMPTY = new BitSet(); - @Override public AbstractLongStorage widen(IntegerType widerType) { // Currently the implementation only reports 64-bit type so there is no widening to do - we can @@ -127,25 +48,4 @@ public AbstractLongStorage widen(IntegerType widerType) { assert getType().equals(IntegerType.INT_64); return this; } - - @Override - public Storage appendNulls(int count) { - final ComputedLongStorage parent = this; - return new ComputedNullableLongStorage(parent.size + count) { - - @Override - protected Long computeItem(int idx) { - if (idx < parent.size) { - return parent.computeItem(idx); - } else { - return null; - } - } - }; - } - - @Override - public BitSet getIsNothingMap() { - return EMPTY; - } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/ComputedNullableLongStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/ComputedNullableLongStorage.java index 961d82c65e42..69cc52436460 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/ComputedNullableLongStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/ComputedNullableLongStorage.java @@ -1,11 +1,9 @@ package org.enso.table.data.column.storage.numeric; import java.util.BitSet; -import java.util.List; -import org.enso.table.data.column.storage.Storage; +import org.enso.table.data.column.storage.ColumnStorageWithNothingMap; +import org.enso.table.data.column.storage.ValueIsNothingException; import org.enso.table.data.column.storage.type.IntegerType; -import org.enso.table.data.mask.OrderMask; -import org.enso.table.data.mask.SliceRange; import org.graalvm.polyglot.Context; /** @@ -14,49 +12,42 @@ *

This storage allows for missing values. Prefer {@link ComputedLongStorage} for non-nullable * case. */ -public abstract class ComputedNullableLongStorage extends AbstractLongStorage { - protected final int size; - - protected BitSet isNothing = null; - +public abstract class ComputedNullableLongStorage extends AbstractLongStorage + implements ColumnStorageWithNothingMap { protected abstract Long computeItem(int idx); - protected ComputedNullableLongStorage(int size) { - this.size = size; - } + private BitSet isNothing; - @Override - public int size() { - return size; + protected ComputedNullableLongStorage(int size) { + super(size, IntegerType.INT_64); } @Override - public IntegerType getType() { - return IntegerType.INT_64; + public Long getItemBoxed(long idx) { + if (idx < 0 || idx >= getSize()) { + throw new IndexOutOfBoundsException(idx); + } + return computeItem((int) idx); } @Override public boolean isNothing(long idx) { - if (idx < 0 || idx >= size) { - throw new IndexOutOfBoundsException( - "Index " + idx + " is out of bounds for range of length " + size + "."); + if (isNothing != null) { + if (idx < 0 || idx >= getSize()) { + throw new IndexOutOfBoundsException(idx); + } + return isNothing.get((int) idx); } - - return computeItem((int) idx) == null; + return this.getItemBoxed(idx) == null; } @Override - public Long getItemBoxed(int idx) { - if (idx < 0 || idx >= size) { - throw new IndexOutOfBoundsException( - "Index " + idx + " is out of bounds for range of length " + size + "."); + public long getItemAsLong(long idx) throws ValueIsNothingException { + Long result = this.getItemBoxed(idx); + if (result == null) { + throw new ValueIsNothingException(idx); } - - return computeItem(idx); - } - - public long getItem(int idx) { - return getItemBoxed(idx); + return result; } @Override @@ -65,7 +56,7 @@ public BitSet getIsNothingMap() { // Only compute once as needed. BitSet newIsNothing = new BitSet(); Context context = Context.getCurrent(); - for (int i = 0; i < size; i++) { + for (int i = 0; i < getSize(); i++) { if (computeItem(i) == null) { newIsNothing.set(i); } @@ -77,93 +68,6 @@ public BitSet getIsNothingMap() { return isNothing; } - @Override - public Storage applyFilter(BitSet filterMask, int newLength) { - BitSet newIsNothing = new BitSet(); - long[] newData = new long[newLength]; - int resIx = 0; - Context context = Context.getCurrent(); - for (int i = 0; i < size; i++) { - if (filterMask.get(i)) { - Long item = computeItem(i); - if (item == null) { - newIsNothing.set(resIx++); - } else { - newData[resIx++] = item; - } - } - - context.safepoint(); - } - return new LongStorage(newData, newLength, newIsNothing, getType()); - } - - @Override - public Storage applyMask(OrderMask mask) { - long[] newData = new long[mask.length()]; - BitSet newIsNothing = new BitSet(); - Context context = Context.getCurrent(); - for (int i = 0; i < mask.length(); i++) { - int position = mask.get(i); - if (position == OrderMask.NOT_FOUND_INDEX) { - newIsNothing.set(i); - } else { - Long item = computeItem(position); - if (item == null) { - newIsNothing.set(i); - } else { - newData[i] = item; - } - } - - context.safepoint(); - } - return new LongStorage(newData, newData.length, newIsNothing, getType()); - } - - @Override - public Storage slice(int offset, int limit) { - int newSize = Math.min(size - offset, limit); - long[] newData = new long[newSize]; - BitSet newIsNothing = new BitSet(); - Context context = Context.getCurrent(); - for (int i = 0; i < newSize; i++) { - Long item = computeItem(offset + i); - if (item == null) { - newIsNothing.set(i); - } else { - newData[i] = item; - } - context.safepoint(); - } - return new LongStorage(newData, newSize, newIsNothing, getType()); - } - - @Override - public Storage slice(List ranges) { - int newSize = SliceRange.totalLength(ranges); - long[] newData = new long[newSize]; - BitSet newIsNothing = new BitSet(newSize); - int offset = 0; - Context context = Context.getCurrent(); - for (SliceRange range : ranges) { - int rangeStart = range.start(); - int length = range.end() - rangeStart; - for (int i = 0; i < length; i++) { - Long item = computeItem(rangeStart + i); - if (item == null) { - newIsNothing.set(offset + i); - } else { - newData[offset + i] = item; - } - context.safepoint(); - } - offset += length; - } - - return new LongStorage(newData, newSize, newIsNothing, getType()); - } - @Override public AbstractLongStorage widen(IntegerType widerType) { // Currently the implementation only reports 64-bit type so there is no widening to do - we can @@ -171,19 +75,4 @@ public AbstractLongStorage widen(IntegerType widerType) { assert getType().equals(IntegerType.INT_64); return this; } - - @Override - public Storage appendNulls(int count) { - final ComputedNullableLongStorage parent = this; - return new ComputedNullableLongStorage(parent.size + count) { - @Override - protected Long computeItem(int idx) { - if (idx < parent.size) { - return parent.computeItem(idx); - } - - return null; - } - }; - } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/DoubleStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/DoubleStorage.java index b63c8c09613e..583f5fe78157 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/DoubleStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/DoubleStorage.java @@ -32,13 +32,14 @@ import org.enso.table.data.column.storage.type.StorageType; import org.enso.table.data.mask.OrderMask; import org.enso.table.data.mask.SliceRange; +import org.enso.table.problems.BlackholeProblemAggregator; import org.enso.table.problems.ProblemAggregator; import org.enso.table.util.BitSets; import org.graalvm.polyglot.Context; import org.graalvm.polyglot.Value; /** A column containing floating point numbers. */ -public final class DoubleStorage extends NumericStorage +public final class DoubleStorage extends Storage implements DoubleArrayAdapter, ColumnStorageWithNothingMap, ColumnDoubleStorage { private final double[] data; private final BitSet isNothing; @@ -57,52 +58,57 @@ public DoubleStorage(double[] data, int size, BitSet isNothing) { this.size = size; } - public static DoubleStorage makeEmpty(int size) { - BitSet isNothing = new BitSet(size); - isNothing.set(0, size); - return new DoubleStorage(new double[0], size, isNothing); + public static DoubleStorage makeEmpty(long size) { + int intSize = Builder.checkSize(size); + BitSet isNothing = new BitSet(intSize); + isNothing.set(0, intSize); + return new DoubleStorage(new double[0], intSize, isNothing); } - /** - * @inheritDoc - */ @Override - public int size() { + public long getSize() { return size; } - /** - * @param idx an index - * @return the data item contained at the given index. - */ - public double getItem(long idx) { - return data[(int) idx]; + @Override + public Double getItemBoxed(long idx) { + return isNothing(idx) ? null : data[Math.toIntExact(idx)]; } @Override - public Double getItemBoxed(int idx) { - return isNothing.get(idx) ? null : data[idx]; + public BitSet getIsNothingMap() { + return isNothing; + } + + @Override + public double getItemAsDouble(long index) throws ValueIsNothingException { + if (isNothing(index)) { + throw new ValueIsNothingException(index); + } + return data[Math.toIntExact(index)]; } - /** - * @inheritDoc - */ @Override public StorageType getType() { return FloatType.FLOAT_64; } - /** - * @inheritDoc - */ @Override public boolean isNothing(long idx) { + if (idx < 0 || idx >= getSize()) { + throw new IndexOutOfBoundsException(idx); + } return isNothing.get((int) idx); } @Override - public double getItemAsDouble(int i) { - return data[i]; + public long size() { + return getSize(); + } + + /** Used by the DoubleBuilder in appendBulkStorage. */ + public double[] getRawData() { + return data; } @Override @@ -142,15 +148,15 @@ public Storage runVectorizedZip( } private Storage fillMissingDouble(double arg, ProblemAggregator problemAggregator) { - var builder = Builder.getForDouble(FloatType.FLOAT_64, size(), problemAggregator); + long n = getSize(); + var builder = Builder.getForDouble(FloatType.FLOAT_64, n, problemAggregator); Context context = Context.getCurrent(); - for (int i = 0; i < size(); i++) { - if (isNothing.get(i)) { + for (long i = 0; i < getSize(); i++) { + if (isNothing(i)) { builder.appendDouble(arg); } else { - builder.appendDouble(data[i]); + builder.appendDouble(getItemAsDouble(i)); } - context.safepoint(); } return builder.seal(); @@ -158,15 +164,15 @@ private Storage fillMissingDouble(double arg, ProblemAggregator problemAggreg /** Special handling to ensure loss of precision is reported. */ private Storage fillMissingBigInteger(BigInteger arg, ProblemAggregator problemAggregator) { - var builder = Builder.getForDouble(FloatType.FLOAT_64, size(), problemAggregator); + long n = getSize(); + var builder = Builder.getForDouble(FloatType.FLOAT_64, n, problemAggregator); Context context = Context.getCurrent(); - for (int i = 0; i < size(); i++) { - if (isNothing.get(i)) { + for (long i = 0; i < n; i++) { + if (isNothing(i)) { builder.append(arg); } else { - builder.appendDouble(data[i]); + builder.appendDouble(getItemAsDouble(i)); } - context.safepoint(); } return builder.seal(); @@ -174,15 +180,15 @@ private Storage fillMissingBigInteger(BigInteger arg, ProblemAggregator probl /** Special handling to ensure loss of precision is reported. */ private Storage fillMissingLong(long arg, ProblemAggregator problemAggregator) { - var builder = Builder.getForDouble(FloatType.FLOAT_64, size(), problemAggregator); + long n = getSize(); + var builder = Builder.getForDouble(FloatType.FLOAT_64, n, problemAggregator); Context context = Context.getCurrent(); - for (int i = 0; i < size(); i++) { - if (isNothing.get(i)) { + for (long i = 0; i < n; i++) { + if (isNothing(i)) { builder.appendLong(arg); } else { - builder.appendDouble(data[i]); + builder.appendDouble(getItemAsDouble(i)); } - context.safepoint(); } return builder.seal(); @@ -205,57 +211,55 @@ public Storage fillMissing( } @Override - public DoubleStorage fillMissingFromPrevious(BoolStorage missingIndicator) { + public Storage fillMissingFromPrevious(BoolStorage missingIndicator) { if (missingIndicator != null) { throw new IllegalStateException( "Custom missing value semantics are not supported by DoubleStorage."); } - int n = size(); - double[] newData = new double[n]; - BitSet newIsNothing = new BitSet(); + long n = getSize(); + var builder = Builder.getForDouble(FloatType.FLOAT_64, n, BlackholeProblemAggregator.INSTANCE); double previousValue = 0; boolean hasPrevious = false; Context context = Context.getCurrent(); - for (int i = 0; i < n; i++) { + for (long i = 0; i < n; i++) { boolean isCurrentMissing = isNothing(i); if (isCurrentMissing) { if (hasPrevious) { - newData[i] = previousValue; + builder.appendDouble(previousValue); } else { - newIsNothing.set(i); + builder.appendNulls(1); } } else { - newData[i] = data[i]; - previousValue = data[i]; + double value = getItemAsDouble(i); + builder.appendDouble(value); + previousValue = value; hasPrevious = true; } context.safepoint(); } - return new DoubleStorage(newData, n, newIsNothing); + return builder.seal(); } @Override public Storage applyFilter(BitSet filterMask, int newLength) { - BitSet newIsNothing = new BitSet(); - double[] newData = new double[newLength]; - int resIx = 0; + var builder = + Builder.getForDouble(FloatType.FLOAT_64, newLength, BlackholeProblemAggregator.INSTANCE); Context context = Context.getCurrent(); for (int i = 0; i < size; i++) { if (filterMask.get(i)) { if (isNothing.get(i)) { - newIsNothing.set(resIx++); + builder.appendNulls(1); } else { - newData[resIx++] = data[i]; + builder.appendDouble(data[i]); } } - context.safepoint(); } - return new DoubleStorage(newData, newLength, newIsNothing); + return builder.seal(); } @Override @@ -276,10 +280,6 @@ public Storage applyMask(OrderMask mask) { return new DoubleStorage(newData, newData.length, newIsNothing); } - public double[] getRawData() { - return data; - } - private static MapOperationStorage buildOps() { MapOperationStorage ops = new MapOperationStorage<>(); ops.add(new AddOp<>()) @@ -402,7 +402,7 @@ protected Long computeItem(int idx) { return null; } - double value = parent.getItem(idx); + double value = parent.getItemAsDouble(idx); assert value % 1.0 == 0.0 : "The value " + value + " should be a whole number (guaranteed by checks)."; return (long) value; @@ -412,17 +412,4 @@ protected Long computeItem(int idx) { // And rely on its shrinking logic. return longAdapter.inferPreciseTypeShrunk(); } - - @Override - public BitSet getIsNothingMap() { - return isNothing; - } - - @Override - public double get(long index) throws ValueIsNothingException { - if (isNothing(index)) { - throw new ValueIsNothingException(index); - } - return getItem(Math.toIntExact(index)); - } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/LongRangeStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/LongRangeStorage.java index 9dff1bb8c877..3c4135dcb797 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/LongRangeStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/LongRangeStorage.java @@ -17,7 +17,7 @@ public LongRangeStorage(long start, long step, int size) { @SuppressWarnings("unused") private void verifyBounds() throws ArithmeticException { - long lastIdx = size - 1; + long lastIdx = getSize() - 1; // Computing this value will throw an exception if it overflows. long lastValue = Math.addExact(start, Math.multiplyExact(step, lastIdx)); } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/LongStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/LongStorage.java index d4fa776e69c4..62ac152012b1 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/LongStorage.java +++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/LongStorage.java @@ -5,12 +5,12 @@ import java.util.List; import org.enso.base.polyglot.NumericConverter; import org.enso.table.data.column.builder.Builder; +import org.enso.table.data.column.storage.ColumnStorageWithNothingMap; import org.enso.table.data.column.storage.Storage; -import org.enso.table.data.column.storage.type.BigIntegerType; +import org.enso.table.data.column.storage.ValueIsNothingException; import org.enso.table.data.column.storage.type.FloatType; import org.enso.table.data.column.storage.type.IntegerType; import org.enso.table.data.column.storage.type.StorageType; -import org.enso.table.data.mask.OrderMask; import org.enso.table.data.mask.SliceRange; import org.enso.table.problems.ProblemAggregator; import org.enso.table.util.BitSets; @@ -18,15 +18,12 @@ import org.graalvm.polyglot.Value; /** A column storing 64-bit integers. */ -public final class LongStorage extends AbstractLongStorage { +public final class LongStorage extends AbstractLongStorage implements ColumnStorageWithNothingMap { // TODO [RW] at some point we will want to add separate storage classes for byte, short and int, // for more compact storage and more efficient handling of smaller integers; for now we will be // handling this just by checking the bounds private final long[] data; private final BitSet isNothing; - private final int size; - - private final IntegerType type; /** * @param data the underlying data @@ -36,68 +33,51 @@ public final class LongStorage extends AbstractLongStorage { * @param type the type specifying the bit-width of integers that are allowed in this storage */ public LongStorage(long[] data, int size, BitSet isNothing, IntegerType type) { + super(size, type); this.data = data; this.isNothing = isNothing; - this.size = size; - this.type = type; - } - - public static LongStorage fromArray(long[] data) { - return new LongStorage(data, data.length, new BitSet(), IntegerType.INT_64); } - public static LongStorage makeEmpty(int size, IntegerType type) { - BitSet isNothing = new BitSet(size); - isNothing.set(0, size); - return new LongStorage(new long[0], size, isNothing, type); + public static LongStorage makeEmpty(long size, IntegerType type) { + int intSize = Builder.checkSize(size); + BitSet isNothing = new BitSet(intSize); + isNothing.set(0, intSize); + return new LongStorage(new long[0], intSize, isNothing, type); } public LongStorage(long[] data, IntegerType type) { this(data, data.length, new BitSet(), type); } - /** - * @inheritDoc - */ - @Override - public int size() { - return size; - } - /** * @param idx an index * @return the data item contained at the given index. */ - public long getItem(int idx) { - return data[idx]; + public long getItemAsLong(long idx) { + if (isNothing(idx)) { + throw new ValueIsNothingException(idx); + } + return data[Math.toIntExact(idx)]; } @Override - public Long getItemBoxed(int idx) { - return isNothing.get(idx) ? null : data[idx]; - } - - /** - * @inheritDoc - */ - @Override - public IntegerType getType() { - return type; + public boolean isNothing(long idx) { + if (idx < 0 || idx >= getSize()) { + throw new IndexOutOfBoundsException(idx); + } + return isNothing.get(Math.toIntExact(idx)); } - /** - * @inheritDoc - */ @Override - public boolean isNothing(long idx) { - return isNothing.get((int) idx); + public BitSet getIsNothingMap() { + return isNothing; } private Storage fillMissingDouble(double arg, ProblemAggregator problemAggregator) { - var builder = Builder.getForDouble(FloatType.FLOAT_64, size, problemAggregator); + var builder = Builder.getForDouble(FloatType.FLOAT_64, getSize(), problemAggregator); Context context = Context.getCurrent(); - for (int i = 0; i < size(); i++) { - if (isNothing.get(i)) { + for (int i = 0; i < getSize(); i++) { + if (isNothing(i)) { builder.appendDouble(arg); } else { builder.appendLong(data[i]); @@ -110,10 +90,10 @@ private Storage fillMissingDouble(double arg, ProblemAggregator problemAggreg } private Storage fillMissingLong(long arg, ProblemAggregator problemAggregator) { - final var builder = Builder.getForLong(IntegerType.INT_64, size, problemAggregator); + final var builder = Builder.getForLong(IntegerType.INT_64, getSize(), problemAggregator); Context context = Context.getCurrent(); - for (int i = 0; i < size(); i++) { - if (isNothing.get(i)) { + for (int i = 0; i < getSize(); i++) { + if (isNothing(i)) { builder.appendLong(arg); } else { builder.appendLong(data[i]); @@ -127,10 +107,10 @@ private Storage fillMissingLong(long arg, ProblemAggregator problemAggregator private Storage fillMissingBigInteger( BigInteger bigInteger, ProblemAggregator problemAggregator) { - final var builder = Builder.getForType(BigIntegerType.INSTANCE, size, problemAggregator); + var builder = Builder.getForBigInteger(getSize(), problemAggregator); Context context = Context.getCurrent(); - for (int i = 0; i < size(); i++) { - builder.append(isNothing.get(i) ? bigInteger : BigInteger.valueOf(data[i])); + for (int i = 0; i < getSize(); i++) { + builder.append(isNothing(i) ? bigInteger : BigInteger.valueOf(data[i])); context.safepoint(); } return builder.seal(); @@ -152,55 +132,13 @@ public Storage fillMissing( return super.fillMissing(arg, commonType, problemAggregator); } - @Override - public Storage applyFilter(BitSet filterMask, int newLength) { - BitSet newIsNothing = new BitSet(); - long[] newData = new long[newLength]; - int resIx = 0; - Context context = Context.getCurrent(); - for (int i = 0; i < size; i++) { - if (filterMask.get(i)) { - if (isNothing.get(i)) { - newIsNothing.set(resIx++); - } else { - newData[resIx++] = data[i]; - } - } - - context.safepoint(); - } - return new LongStorage(newData, newLength, newIsNothing, type); - } - - @Override - public Storage applyMask(OrderMask mask) { - long[] newData = new long[mask.length()]; - BitSet newIsNothing = new BitSet(); - Context context = Context.getCurrent(); - for (int i = 0; i < mask.length(); i++) { - int position = mask.get(i); - if (position == OrderMask.NOT_FOUND_INDEX || isNothing.get(position)) { - newIsNothing.set(i); - } else { - newData[i] = data[position]; - } - - context.safepoint(); - } - return new LongStorage(newData, newData.length, newIsNothing, type); - } - - @Override - public BitSet getIsNothingMap() { - return isNothing; - } - public long[] getRawData() { return data; } @Override public LongStorage slice(int offset, int limit) { + int size = (int) getSize(); int newSize = Math.min(size - offset, limit); long[] newData; @@ -214,21 +152,28 @@ public LongStorage slice(int offset, int limit) { System.arraycopy(data, offset, newData, 0, newDataSize); } - BitSet newMask = isNothing.get(offset, offset + limit); - return new LongStorage(newData, newSize, newMask, type); + BitSet currentMask = getIsNothingMap(); + BitSet newMask = currentMask.get(offset, offset + limit); + return new LongStorage(newData, newSize, newMask, getType()); } @Override public LongStorage appendNulls(int count) { - BitSet newIsNothing = BitSets.makeDuplicate(isNothing); + int size = (int) getSize(); + if (size + count > Builder.MAX_SIZE) { + throw new IllegalStateException("Cannot append nulls, storage would exceed maximum size."); + } + + BitSet newIsNothing = BitSets.makeDuplicate(getIsNothingMap()); newIsNothing.set(size, size + count); - long[] newData = new long[size + count]; - System.arraycopy(data, 0, newData, 0, size); - return new LongStorage(newData, size + count, newIsNothing, type); + + // No need to copy the data as we are just adding nulls + return new LongStorage(data, size + count, newIsNothing, getType()); } @Override public LongStorage slice(List ranges) { + BitSet currentMask = getIsNothingMap(); int newSize = SliceRange.totalLength(ranges); long[] newData = new long[newSize]; BitSet newIsNothing = new BitSet(newSize); @@ -238,19 +183,19 @@ public LongStorage slice(List ranges) { int length = range.end() - range.start(); System.arraycopy(data, range.start(), newData, offset, length); for (int i = 0; i < length; ++i) { - newIsNothing.set(offset + i, isNothing.get(range.start() + i)); + newIsNothing.set(offset + i, currentMask.get(range.start() + i)); context.safepoint(); } offset += length; } - return new LongStorage(newData, newSize, newIsNothing, type); + return new LongStorage(newData, newSize, newIsNothing, getType()); } /** Widening to a bigger type can be done without copying the data. */ @Override public LongStorage widen(IntegerType widerType) { - assert widerType.fits(type); - return new LongStorage(data, size, isNothing, widerType); + assert widerType.fits(getType()); + return new LongStorage(data, (int) getSize(), getIsNothingMap(), widerType); } } diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/NumericStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/NumericStorage.java deleted file mode 100644 index 168b7bd8e9cf..000000000000 --- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/NumericStorage.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.enso.table.data.column.storage.numeric; - -import org.enso.table.data.column.storage.Storage; - -/** A storage containing numbers. */ -public abstract class NumericStorage extends Storage {} diff --git a/std-bits/table/src/main/java/org/enso/table/data/table/Column.java b/std-bits/table/src/main/java/org/enso/table/data/table/Column.java index 7a4d1e63b60c..4ca332a22c06 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/table/Column.java +++ b/std-bits/table/src/main/java/org/enso/table/data/table/Column.java @@ -76,7 +76,8 @@ public Storage getStorage() { * @return the number of items in this column. */ public int getSize() { - return getStorage().size(); + // ToDo: Work through changing to long. + return Math.toIntExact(getStorage().getSize()); } /** diff --git a/std-bits/table/src/main/java/org/enso/table/data/table/Table.java b/std-bits/table/src/main/java/org/enso/table/data/table/Table.java index 28c53d76fb3f..58e35d3d73d6 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/table/Table.java +++ b/std-bits/table/src/main/java/org/enso/table/data/table/Table.java @@ -437,7 +437,7 @@ public static Table transpose( System.arraycopy(id_columns, 0, newColumns, 0, id_columns.length); int size = id_columns.length == 0 ? 0 : id_columns[0].getSize(); - var builder = Builder.getForType(TextType.VARIABLE_LENGTH, size, problemAggregator); + var builder = Builder.getForText(TextType.VARIABLE_LENGTH, size); builder.appendNulls(size); Storage newStorage = builder.seal(); newColumns[id_columns.length] = new Column(name_field, newStorage); @@ -457,8 +457,7 @@ public static Table transpose( storage[i] = Builder.getForType( id_columns[i].getStorage().getType(), new_count, problemAggregator)); - storage[id_columns.length] = - Builder.getForType(TextType.VARIABLE_LENGTH, new_count, problemAggregator); + storage[id_columns.length] = Builder.getForText(TextType.VARIABLE_LENGTH, new_count); storage[id_columns.length + 1] = Builder.getInferredBuilder(new_count, problemAggregator); // Load Data diff --git a/std-bits/table/src/main/java/org/enso/table/data/table/join/between/SortJoin.java b/std-bits/table/src/main/java/org/enso/table/data/table/join/between/SortJoin.java index 71b3013fffd3..d98ecd710b4d 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/table/join/between/SortJoin.java +++ b/std-bits/table/src/main/java/org/enso/table/data/table/join/between/SortJoin.java @@ -48,8 +48,9 @@ public JoinResult join(ProblemAggregator problemAggregator) { Context context = Context.getCurrent(); JoinResult.Builder resultBuilder = new JoinResult.Builder(); - int leftRowCount = leftStorages[0].size(); - int rightRowCount = lowerStorages[0].size(); + // ToDo: Will need to rework to longs in next step. + int leftRowCount = (int) leftStorages[0].getSize(); + int rightRowCount = (int) lowerStorages[0].getSize(); if (leftRowCount == 0 || rightRowCount == 0) { // if one group is completely empty, there will be no matches to report return resultBuilder.buildAndInvalidate(); diff --git a/std-bits/table/src/main/java/org/enso/table/data/table/join/lookup/LookupJoin.java b/std-bits/table/src/main/java/org/enso/table/data/table/join/lookup/LookupJoin.java index 4fdaf76420e4..719e5a46a18f 100644 --- a/std-bits/table/src/main/java/org/enso/table/data/table/join/lookup/LookupJoin.java +++ b/std-bits/table/src/main/java/org/enso/table/data/table/join/lookup/LookupJoin.java @@ -71,7 +71,8 @@ private LookupJoin( lookupIndex = MultiValueIndex.makeUnorderedIndex( lookupKeyColumns, 0, textFoldingStrategies, problemAggregator); - baseTableRowCount = baseKeyStorages[0].size(); + // ToDo: Will need to rework to longs in next step. + baseTableRowCount = (int) baseKeyStorages[0].getSize(); } private void checkNullsInKey() { diff --git a/std-bits/table/src/main/java/org/enso/table/operations/AddRunning.java b/std-bits/table/src/main/java/org/enso/table/operations/AddRunning.java index 324eacc4d443..f54bb32eaa3f 100644 --- a/std-bits/table/src/main/java/org/enso/table/operations/AddRunning.java +++ b/std-bits/table/src/main/java/org/enso/table/operations/AddRunning.java @@ -3,9 +3,10 @@ import java.util.BitSet; import org.enso.base.polyglot.NumericConverter; import org.enso.base.statistics.Statistic; +import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.storage.Storage; -import org.enso.table.data.column.storage.numeric.DoubleStorage; import org.enso.table.data.column.storage.numeric.LongStorage; +import org.enso.table.data.column.storage.type.FloatType; import org.enso.table.data.column.storage.type.IntegerType; import org.enso.table.data.table.Column; import org.enso.table.data.table.problems.IgnoredNaN; @@ -124,6 +125,11 @@ private interface TypeHandler { } private static class DoubleHandler implements TypeHandler { + private final ProblemAggregator problemAggregator; + + DoubleHandler(ProblemAggregator problemAggregator) { + this.problemAggregator = problemAggregator; + } @Override public Double tryConvertingToType(Object o) { @@ -138,14 +144,17 @@ public long typeToRawLongBits(Double d) { @Override public Storage createStorage(long[] result, int size, BitSet isNothing) { // Have to convert the long[] to double[]. - double[] values = new double[size]; + var builder = Builder.getForDouble(FloatType.FLOAT_64, size, problemAggregator); + for (int i = 0; i < size; i++) { if (!isNothing.get(i)) { - values[i] = Double.longBitsToDouble(result[i]); + builder.append(Double.longBitsToDouble(result[i])); + } else { + builder.appendNulls(1); } } - return new DoubleStorage(values, size, isNothing); + return builder.seal(); } } @@ -256,7 +265,7 @@ protected double getCurrent() { private static class RunningSumStatistic extends RunningStatisticBase { RunningSumStatistic(Column sourceColumn, ProblemAggregator problemAggregator) { - super(sourceColumn, problemAggregator, new DoubleHandler()); + super(sourceColumn, problemAggregator, new DoubleHandler(problemAggregator)); } @Override @@ -268,7 +277,7 @@ public RunningIterator getNewIterator() { private static class RunningMeanStatistic extends RunningStatisticBase { RunningMeanStatistic(Column sourceColumn, ProblemAggregator problemAggregator) { - super(sourceColumn, problemAggregator, new DoubleHandler()); + super(sourceColumn, problemAggregator, new DoubleHandler(problemAggregator)); } @Override @@ -280,7 +289,7 @@ public RunningIterator getNewIterator() { private static class RunningProductStatistic extends RunningStatisticBase { RunningProductStatistic(Column sourceColumn, ProblemAggregator problemAggregator) { - super(sourceColumn, problemAggregator, new DoubleHandler()); + super(sourceColumn, problemAggregator, new DoubleHandler(problemAggregator)); } @Override @@ -295,7 +304,7 @@ private static class RunningVarianceStatistic extends RunningStatisticBase { RunningSkewStatistic( Column sourceColumn, ProblemAggregator problemAggregator, boolean isPopulation) { - super(sourceColumn, problemAggregator, new DoubleHandler()); + super(sourceColumn, problemAggregator, new DoubleHandler(problemAggregator)); this.isPopulation = isPopulation; } @@ -340,7 +349,7 @@ public RunningIterator getNewIterator() { private static class RunningKurtosisStatistic extends RunningStatisticBase { RunningKurtosisStatistic(Column sourceColumn, ProblemAggregator problemAggregator) { - super(sourceColumn, problemAggregator, new DoubleHandler()); + super(sourceColumn, problemAggregator, new DoubleHandler(problemAggregator)); } @Override @@ -474,8 +483,7 @@ public double getCurrent() { : ((double) ((currentCount - 1) * (currentCount - 2)) / (double) currentCount); double scale = 1.0 / (standardDeviation * standardDeviation * standardDeviation) / denominator; - double skew = (sumCubes - 3 * mean * sumSquares + 2 * mean * mean * sum) * scale; - return skew; + return (sumCubes - 3 * mean * sumSquares + 2 * mean * mean * sum) * scale; } } @@ -535,7 +543,7 @@ public double getCurrent() { private static class RunningMinStatistic extends RunningStatisticBase { RunningMinStatistic(Column sourceColumn, ProblemAggregator problemAggregator) { - super(sourceColumn, problemAggregator, new DoubleHandler()); + super(sourceColumn, problemAggregator, new DoubleHandler(problemAggregator)); } @Override @@ -576,7 +584,7 @@ public void increment(long value) { private static class RunningMaxStatistic extends RunningStatisticBase { RunningMaxStatistic(Column sourceColumn, ProblemAggregator problemAggregator) { - super(sourceColumn, problemAggregator, new DoubleHandler()); + super(sourceColumn, problemAggregator, new DoubleHandler(problemAggregator)); } @Override diff --git a/std-bits/table/src/main/java/org/enso/table/parsing/BooleanParser.java b/std-bits/table/src/main/java/org/enso/table/parsing/BooleanParser.java index 3b8553df62f0..47fc03661a0a 100644 --- a/std-bits/table/src/main/java/org/enso/table/parsing/BooleanParser.java +++ b/std-bits/table/src/main/java/org/enso/table/parsing/BooleanParser.java @@ -33,7 +33,7 @@ public Object parseSingleValue(String text, ParseProblemAggregator problemAggreg } @Override - protected Builder makeBuilderWithCapacity(int capacity, ProblemAggregator problemAggregator) { + protected Builder makeBuilderWithCapacity(long capacity, ProblemAggregator problemAggregator) { return Builder.getForBoolean(capacity); } } diff --git a/std-bits/table/src/main/java/org/enso/table/parsing/DatatypeParser.java b/std-bits/table/src/main/java/org/enso/table/parsing/DatatypeParser.java index 600d35248188..0282b8345613 100644 --- a/std-bits/table/src/main/java/org/enso/table/parsing/DatatypeParser.java +++ b/std-bits/table/src/main/java/org/enso/table/parsing/DatatypeParser.java @@ -19,7 +19,7 @@ public abstract class DatatypeParser { public abstract Object parseSingleValue(String text, ParseProblemAggregator problemAggregator); /** - * Parses a column of texts (represented as a {@code StringStorage}) and returns a new storage, + * Parses a column of texts (represented as a {@code Storage}) and returns a new storage, * containing the parsed elements. */ public abstract Storage parseColumn( diff --git a/std-bits/table/src/main/java/org/enso/table/parsing/DateParser.java b/std-bits/table/src/main/java/org/enso/table/parsing/DateParser.java index 0a5aad2b4f6b..8f26a187233b 100644 --- a/std-bits/table/src/main/java/org/enso/table/parsing/DateParser.java +++ b/std-bits/table/src/main/java/org/enso/table/parsing/DateParser.java @@ -2,7 +2,6 @@ import org.enso.base.time.EnsoDateTimeFormatter; import org.enso.table.data.column.builder.Builder; -import org.enso.table.data.column.storage.type.DateType; import org.enso.table.problems.ProblemAggregator; public class DateParser extends BaseTimeParser { @@ -13,7 +12,7 @@ public DateParser(EnsoDateTimeFormatter[] formatters) { } @Override - protected Builder makeBuilderWithCapacity(int capacity, ProblemAggregator problemAggregator) { - return Builder.getForType(DateType.INSTANCE, capacity, problemAggregator); + protected Builder makeBuilderWithCapacity(long capacity, ProblemAggregator problemAggregator) { + return Builder.getForDate(capacity); } } diff --git a/std-bits/table/src/main/java/org/enso/table/parsing/DateTimeParser.java b/std-bits/table/src/main/java/org/enso/table/parsing/DateTimeParser.java index 7934b1329500..0d291b11364d 100644 --- a/std-bits/table/src/main/java/org/enso/table/parsing/DateTimeParser.java +++ b/std-bits/table/src/main/java/org/enso/table/parsing/DateTimeParser.java @@ -2,7 +2,6 @@ import org.enso.base.time.EnsoDateTimeFormatter; import org.enso.table.data.column.builder.Builder; -import org.enso.table.data.column.storage.type.DateTimeType; import org.enso.table.problems.ProblemAggregator; public class DateTimeParser extends BaseTimeParser { @@ -13,7 +12,7 @@ public DateTimeParser(EnsoDateTimeFormatter[] formatters) { } @Override - protected Builder makeBuilderWithCapacity(int capacity, ProblemAggregator problemAggregator) { - return Builder.getForType(DateTimeType.INSTANCE, capacity, problemAggregator); + protected Builder makeBuilderWithCapacity(long capacity, ProblemAggregator problemAggregator) { + return Builder.getForDateTime(capacity); } } diff --git a/std-bits/table/src/main/java/org/enso/table/parsing/IdentityParser.java b/std-bits/table/src/main/java/org/enso/table/parsing/IdentityParser.java index 3f217cf62832..92ef2305890a 100644 --- a/std-bits/table/src/main/java/org/enso/table/parsing/IdentityParser.java +++ b/std-bits/table/src/main/java/org/enso/table/parsing/IdentityParser.java @@ -16,8 +16,8 @@ public Object parseSingleValue(String text, ParseProblemAggregator problemAggreg } @Override - public Builder makeBuilderWithCapacity(int capacity, ProblemAggregator problemAggregator) { - return Builder.getForType(TextType.VARIABLE_LENGTH, capacity, problemAggregator); + public Builder makeBuilderWithCapacity(long capacity, ProblemAggregator problemAggregator) { + return Builder.getForText(TextType.VARIABLE_LENGTH, capacity); } @Override diff --git a/std-bits/table/src/main/java/org/enso/table/parsing/IncrementalDatatypeParser.java b/std-bits/table/src/main/java/org/enso/table/parsing/IncrementalDatatypeParser.java index b03cb55ba103..5ddacf072867 100644 --- a/std-bits/table/src/main/java/org/enso/table/parsing/IncrementalDatatypeParser.java +++ b/std-bits/table/src/main/java/org/enso/table/parsing/IncrementalDatatypeParser.java @@ -24,19 +24,20 @@ public abstract class IncrementalDatatypeParser extends DatatypeParser { * builder. */ protected abstract Builder makeBuilderWithCapacity( - int capacity, ProblemAggregator problemAggregator); + long capacity, ProblemAggregator problemAggregator); /** - * Parses a column of texts (represented as a {@code StringStorage}) and returns a new storage, + * Parses a column of texts (represented as a {@code Storage}) and returns a new storage, * containing the parsed elements. */ @Override public Storage parseColumn( Storage sourceStorage, CommonParseProblemAggregator problemAggregator) { - Builder builder = makeBuilderWithCapacity(sourceStorage.size(), problemAggregator); + long size = sourceStorage.getSize(); + Builder builder = makeBuilderWithCapacity(size, problemAggregator); Context context = Context.getCurrent(); - for (int i = 0; i < sourceStorage.size(); ++i) { + for (long i = 0; i < size; ++i) { String cell = sourceStorage.getItemBoxed(i); if (cell != null) { Object parsed = parseSingleValue(cell, problemAggregator); diff --git a/std-bits/table/src/main/java/org/enso/table/parsing/NumberParser.java b/std-bits/table/src/main/java/org/enso/table/parsing/NumberParser.java index 8c6eca18112b..0d0a2295dc7a 100644 --- a/std-bits/table/src/main/java/org/enso/table/parsing/NumberParser.java +++ b/std-bits/table/src/main/java/org/enso/table/parsing/NumberParser.java @@ -100,7 +100,7 @@ private boolean isInteger() { } @Override - protected Builder makeBuilderWithCapacity(int capacity, ProblemAggregator problemAggregator) { + protected Builder makeBuilderWithCapacity(long capacity, ProblemAggregator problemAggregator) { return isInteger() ? Builder.getForLong(integerTargetType, capacity, problemAggregator) : Builder.getForDouble(FloatType.FLOAT_64, capacity, problemAggregator); @@ -109,11 +109,11 @@ protected Builder makeBuilderWithCapacity(int capacity, ProblemAggregator proble @Override public Storage parseColumn( Storage sourceStorage, CommonParseProblemAggregator problemAggregator) { - Builder builder = - makeBuilderWithCapacity(sourceStorage.size(), problemAggregator.createSimpleChild()); + long size = sourceStorage.getSize(); + Builder builder = makeBuilderWithCapacity(size, problemAggregator.createSimpleChild()); var context = Context.getCurrent(); - for (int i = 0; i < sourceStorage.size(); i++) { + for (long i = 0; i < size; i++) { var text = sourceStorage.getItemBoxed(i); // Check if in unknown state @@ -124,8 +124,7 @@ public Storage parseColumn( // Do we need to rescan? if (mightBeEuropean && parser.numberWithSeparators() != NumberWithSeparators.DOT_COMMA) { - builder = - makeBuilderWithCapacity(sourceStorage.size(), problemAggregator.createSimpleChild()); + builder = makeBuilderWithCapacity(size, problemAggregator.createSimpleChild()); for (int j = 0; j < i; j++) { var subText = sourceStorage.getItemBoxed(j); var subResult = subText == null ? null : parseSingleValue(subText, problemAggregator); diff --git a/std-bits/table/src/main/java/org/enso/table/parsing/TimeOfDayParser.java b/std-bits/table/src/main/java/org/enso/table/parsing/TimeOfDayParser.java index 7384fedecc50..3f68a731dad5 100644 --- a/std-bits/table/src/main/java/org/enso/table/parsing/TimeOfDayParser.java +++ b/std-bits/table/src/main/java/org/enso/table/parsing/TimeOfDayParser.java @@ -2,7 +2,6 @@ import org.enso.base.time.EnsoDateTimeFormatter; import org.enso.table.data.column.builder.Builder; -import org.enso.table.data.column.storage.type.TimeOfDayType; import org.enso.table.problems.ProblemAggregator; public class TimeOfDayParser extends BaseTimeParser { @@ -13,7 +12,7 @@ public TimeOfDayParser(EnsoDateTimeFormatter[] formatters) { } @Override - protected Builder makeBuilderWithCapacity(int capacity, ProblemAggregator problemAggregator) { - return Builder.getForType(TimeOfDayType.INSTANCE, capacity, problemAggregator); + protected Builder makeBuilderWithCapacity(long capacity, ProblemAggregator problemAggregator) { + return Builder.getForTime(capacity); } } diff --git a/std-bits/table/src/main/java/org/enso/table/parsing/TypeInferringParser.java b/std-bits/table/src/main/java/org/enso/table/parsing/TypeInferringParser.java index a02ebd9129dc..6e4a1d5a0f12 100644 --- a/std-bits/table/src/main/java/org/enso/table/parsing/TypeInferringParser.java +++ b/std-bits/table/src/main/java/org/enso/table/parsing/TypeInferringParser.java @@ -43,20 +43,22 @@ public Object parseSingleValue(String text, ParseProblemAggregator problemAggreg @Override public Storage parseColumn( Storage sourceStorage, CommonParseProblemAggregator problemAggregator) { + long size = sourceStorage.getSize(); + // If there are no values, the Auto parser would guess some random type (the first one that is // checked). Instead, we return a Null-type column. - boolean hasNoValues = (sourceStorage.size() == 0) || CountNothing.allNothing(sourceStorage); + boolean hasNoValues = (size == 0) || CountNothing.allNothing(sourceStorage); if (hasNoValues) { - return new NullStorage(sourceStorage.size()); + return new NullStorage(size); } Context context = Context.getCurrent(); parsers: for (IncrementalDatatypeParser parser : baseParsers) { CommonParseProblemAggregator innerAggregator = problemAggregator.createContextAwareChild(); - Builder builder = parser.makeBuilderWithCapacity(sourceStorage.size(), innerAggregator); + Builder builder = parser.makeBuilderWithCapacity(size, innerAggregator); - for (int i = 0; i < sourceStorage.size(); ++i) { + for (long i = 0; i < size; ++i) { String cell = sourceStorage.getItemBoxed(i); if (cell != null) { Object parsed = parser.parseSingleValue(cell, innerAggregator); diff --git a/std-bits/table/src/main/java/org/enso/table/parsing/WhitespaceStrippingParser.java b/std-bits/table/src/main/java/org/enso/table/parsing/WhitespaceStrippingParser.java index cfd31a7c47a2..5e0de0054b09 100644 --- a/std-bits/table/src/main/java/org/enso/table/parsing/WhitespaceStrippingParser.java +++ b/std-bits/table/src/main/java/org/enso/table/parsing/WhitespaceStrippingParser.java @@ -22,7 +22,7 @@ public Object parseSingleValue(String text, ParseProblemAggregator problemAggreg } @Override - protected Builder makeBuilderWithCapacity(int capacity, ProblemAggregator problemAggregator) { + protected Builder makeBuilderWithCapacity(long capacity, ProblemAggregator problemAggregator) { return innerParser.makeBuilderWithCapacity(capacity, problemAggregator); } } diff --git a/std-bits/table/src/main/java/org/enso/table/read/DelimitedReader.java b/std-bits/table/src/main/java/org/enso/table/read/DelimitedReader.java index dffdf4129166..5dd11ff52b72 100644 --- a/std-bits/table/src/main/java/org/enso/table/read/DelimitedReader.java +++ b/std-bits/table/src/main/java/org/enso/table/read/DelimitedReader.java @@ -493,7 +493,7 @@ private void markUsed() { private void initBuilders(int count) { builders = new ArrayList<>(count); for (int i = 0; i < count; i++) { - builders.add(Builder.getForText(INITIAL_ROW_CAPACITY, TextType.VARIABLE_LENGTH)); + builders.add(Builder.getForText(TextType.VARIABLE_LENGTH, INITIAL_ROW_CAPACITY)); } } diff --git a/std-bits/table/src/main/java/org/enso/table/read/ExcelReader.java b/std-bits/table/src/main/java/org/enso/table/read/ExcelReader.java index 2b989c1518fa..31c9880b8418 100644 --- a/std-bits/table/src/main/java/org/enso/table/read/ExcelReader.java +++ b/std-bits/table/src/main/java/org/enso/table/read/ExcelReader.java @@ -312,7 +312,7 @@ private static Table readTable( new Column[] { new Column( CellReference.convertNumToColString(excelRange.getLeftColumn() - 1), - new ObjectStorage(new Object[0], 0)) + ObjectStorage.EMPTY) }); } diff --git a/std-bits/table/src/main/java/org/enso/table/read/QuoteStrippingParser.java b/std-bits/table/src/main/java/org/enso/table/read/QuoteStrippingParser.java index bd67d7e4d872..28e2bec5d96d 100644 --- a/std-bits/table/src/main/java/org/enso/table/read/QuoteStrippingParser.java +++ b/std-bits/table/src/main/java/org/enso/table/read/QuoteStrippingParser.java @@ -35,7 +35,7 @@ public Object parseSingleValue(String text, ParseProblemAggregator problemAggreg } @Override - protected Builder makeBuilderWithCapacity(int capacity, ProblemAggregator problemAggregator) { - return Builder.getForType(TextType.VARIABLE_LENGTH, capacity, problemAggregator); + protected Builder makeBuilderWithCapacity(long capacity, ProblemAggregator problemAggregator) { + return Builder.getForText(TextType.VARIABLE_LENGTH, capacity); } } diff --git a/std-bits/table/src/main/java/org/enso/table/write/ExcelWriter.java b/std-bits/table/src/main/java/org/enso/table/write/ExcelWriter.java index 48dbc780c444..9ef77c4fa6c3 100644 --- a/std-bits/table/src/main/java/org/enso/table/write/ExcelWriter.java +++ b/std-bits/table/src/main/java/org/enso/table/write/ExcelWriter.java @@ -12,10 +12,10 @@ import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; -import org.enso.table.data.column.storage.BoolStorage; +import org.enso.table.data.column.storage.ColumnBooleanStorage; +import org.enso.table.data.column.storage.ColumnDoubleStorage; +import org.enso.table.data.column.storage.ColumnLongStorage; import org.enso.table.data.column.storage.Storage; -import org.enso.table.data.column.storage.numeric.AbstractLongStorage; -import org.enso.table.data.column.storage.numeric.DoubleStorage; import org.enso.table.data.table.Column; import org.enso.table.data.table.Table; import org.enso.table.error.ColumnCountMismatchException; @@ -499,12 +499,12 @@ private static void writeValueToCell( throws IllegalStateException { if (storage.isNothing(j)) { cell.setBlank(); - } else if (storage instanceof DoubleStorage doubleStorage) { + } else if (storage instanceof ColumnDoubleStorage doubleStorage) { cell.setCellValue(doubleStorage.getItemAsDouble(j)); - } else if (storage instanceof AbstractLongStorage longStorage) { - cell.setCellValue(longStorage.getItem(j)); - } else if (storage instanceof BoolStorage boolStorage) { - cell.setCellValue(boolStorage.getItem(j)); + } else if (storage instanceof ColumnLongStorage longStorage) { + cell.setCellValue(longStorage.getItemAsLong(j)); + } else if (storage instanceof ColumnBooleanStorage boolStorage) { + cell.setCellValue(boolStorage.getItemAsBoolean(j)); } else { Object value = storage.getItemBoxed(j); switch (value) { diff --git a/std-bits/tableau/src/main/java/org/enso/tableau/TableColumnBuilder.java b/std-bits/tableau/src/main/java/org/enso/tableau/TableColumnBuilder.java index 8c9673769a74..9939eed5d745 100644 --- a/std-bits/tableau/src/main/java/org/enso/tableau/TableColumnBuilder.java +++ b/std-bits/tableau/src/main/java/org/enso/tableau/TableColumnBuilder.java @@ -8,14 +8,9 @@ import java.util.function.Consumer; import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.storage.Storage; -import org.enso.table.data.column.storage.type.BigDecimalType; -import org.enso.table.data.column.storage.type.BigIntegerType; -import org.enso.table.data.column.storage.type.DateTimeType; -import org.enso.table.data.column.storage.type.DateType; import org.enso.table.data.column.storage.type.FloatType; import org.enso.table.data.column.storage.type.IntegerType; import org.enso.table.data.column.storage.type.TextType; -import org.enso.table.data.column.storage.type.TimeOfDayType; import org.enso.table.problems.ProblemAggregator; /** A builder for a single column of a table. */ @@ -94,8 +89,7 @@ public static TableColumnBuilder create( throw new IllegalArgumentException("NUMERIC column must have a scale."); } if (column.scale().getAsInt() == 0) { - var bigIntBuilder = - Builder.getForType(BigIntegerType.INSTANCE, initialRowCount, problemAggregator); + var bigIntBuilder = Builder.getForBigInteger(initialRowCount, problemAggregator); return new TableColumnBuilder( bigIntBuilder, nullAppender( @@ -103,8 +97,7 @@ public static TableColumnBuilder create( column.index(), r -> bigIntBuilder.append(r.getBigDecimal(column.index()).toBigInteger()))); } else { - var bigDecimalBuilder = - Builder.getForType(BigDecimalType.INSTANCE, initialRowCount, problemAggregator); + var bigDecimalBuilder = Builder.getForBigDecimal(initialRowCount); return new TableColumnBuilder( bigDecimalBuilder, nullAppender( @@ -135,13 +128,13 @@ public static TableColumnBuilder create( column.length().isEmpty() ? new TextType(-1, false) : new TextType(column.length().getAsInt(), column.typeID() == Types.CHAR); - var textBuilder = Builder.getForType(textType, initialRowCount, problemAggregator); + var textBuilder = Builder.getForText(textType, initialRowCount); return new TableColumnBuilder( textBuilder, nullAppender( textBuilder, column.index(), r -> textBuilder.append(r.getString(column.index())))); case Types.DATE: - var dateBuilder = Builder.getForType(DateType.INSTANCE, initialRowCount, problemAggregator); + var dateBuilder = Builder.getForDate(initialRowCount); return new TableColumnBuilder( dateBuilder, nullAppender( @@ -149,8 +142,7 @@ public static TableColumnBuilder create( column.index(), r -> dateBuilder.append(r.getLocalDate(column.index())))); case Types.TIME: - var timeBuilder = - Builder.getForType(TimeOfDayType.INSTANCE, initialRowCount, problemAggregator); + var timeBuilder = Builder.getForTime(initialRowCount); return new TableColumnBuilder( timeBuilder, nullAppender( @@ -158,8 +150,7 @@ public static TableColumnBuilder create( column.index(), r -> timeBuilder.append(r.getLocalTime(column.index())))); case Types.TIMESTAMP: - var dateTimeBuilder = - Builder.getForType(DateTimeType.INSTANCE, initialRowCount, problemAggregator); + var dateTimeBuilder = Builder.getForDateTime(initialRowCount); return new TableColumnBuilder( dateTimeBuilder, nullAppender( @@ -169,8 +160,7 @@ public static TableColumnBuilder create( dateTimeBuilder.append( r.getLocalDateTime(column.index()).atZone(ZoneId.systemDefault())))); case Types.TIMESTAMP_WITH_TIMEZONE: - var dateTimeTzBuilder = - Builder.getForType(DateTimeType.INSTANCE, initialRowCount, problemAggregator); + var dateTimeTzBuilder = Builder.getForDateTime(initialRowCount); return new TableColumnBuilder( dateTimeTzBuilder, nullAppender( diff --git a/test/Base_Tests/polyglot-sources/enso-test-java-helpers/src/main/java/org/enso/table_test_helpers/ExplodingStorage.java b/test/Base_Tests/polyglot-sources/enso-test-java-helpers/src/main/java/org/enso/table_test_helpers/ExplodingStorage.java index 865f111c439c..4ca6609075b8 100644 --- a/test/Base_Tests/polyglot-sources/enso-test-java-helpers/src/main/java/org/enso/table_test_helpers/ExplodingStorage.java +++ b/test/Base_Tests/polyglot-sources/enso-test-java-helpers/src/main/java/org/enso/table_test_helpers/ExplodingStorage.java @@ -30,7 +30,7 @@ private void checkIndex(long idx) { } @Override - public int size() { + public long getSize() { return array.length; } @@ -45,14 +45,10 @@ public boolean isNothing(long idx) { return false; } - public long getItem(int idx) { - checkIndex(idx); - return array[idx]; - } - @Override - public Long getItemBoxed(int idx) { - return getItem(idx); + public Long getItemBoxed(long idx) { + checkIndex(idx); + return array[Math.toIntExact(idx)]; } @Override diff --git a/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/LongNullHandling.java b/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/LongNullHandling.java index 8c820c1bcb6b..1f9f5dc6ade9 100644 --- a/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/LongNullHandling.java +++ b/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/LongNullHandling.java @@ -1,64 +1,70 @@ package org.enso.exploratory_benchmark_helpers; -import java.util.BitSet; +import org.enso.table.data.column.builder.Builder; import org.enso.table.data.column.operation.map.MapOperationProblemAggregator; -import org.enso.table.data.column.storage.numeric.LongStorage; +import org.enso.table.data.column.storage.ColumnLongStorage; +import org.enso.table.data.column.storage.Storage; import org.enso.table.data.column.storage.type.IntegerType; import org.enso.table.problems.BlackholeProblemAggregator; import org.enso.table.problems.ProblemAggregator; public class LongNullHandling { public interface Operation { - LongStorage run( - LongStorage storage, LongStorage arg, MapOperationProblemAggregator problemAggregator); + Storage run( + ColumnLongStorage storage, + ColumnLongStorage arg, + MapOperationProblemAggregator problemAggregator); } public abstract static class NoNulls implements Operation { protected abstract long doLong( - long a, long b, int ix, MapOperationProblemAggregator problemAggregator); + long a, long b, long ix, MapOperationProblemAggregator problemAggregator); @Override - public LongStorage run( - LongStorage storage, LongStorage arg, MapOperationProblemAggregator problemAggregator) { - int n = storage.size(); - long[] newVals = new long[n]; - BitSet isNothing = new BitSet(); - for (int i = 0; i < n; i++) { + public Storage run( + ColumnLongStorage storage, + ColumnLongStorage arg, + MapOperationProblemAggregator problemAggregator) { + long n = storage.getSize(); + var builder = Builder.getForLong(IntegerType.INT_64, n, problemAggregator); + for (long i = 0; i < n; i++) { if (storage.isNothing(i) || arg.isNothing(i)) { - isNothing.set(i); + builder.appendNulls(1); } else { - newVals[i] = doLong(storage.getItem(i), arg.getItem(i), i, problemAggregator); + builder.appendLong( + doLong(storage.getItemAsLong(i), arg.getItemAsLong(i), i, problemAggregator)); } } - return new LongStorage(newVals, n, isNothing, IntegerType.INT_64); + return builder.seal(); } } public abstract static class BoxingNulls implements Operation { protected abstract Long doLong( - long a, long b, int ix, MapOperationProblemAggregator problemAggregator); + long a, long b, long ix, MapOperationProblemAggregator problemAggregator); @Override - public LongStorage run( - LongStorage storage, LongStorage arg, MapOperationProblemAggregator problemAggregator) { - int n = storage.size(); - long[] newVals = new long[n]; - BitSet isNothing = new BitSet(); - for (int i = 0; i < n; i++) { + public Storage run( + ColumnLongStorage storage, + ColumnLongStorage arg, + MapOperationProblemAggregator problemAggregator) { + long n = storage.getSize(); + var builder = Builder.getForLong(IntegerType.INT_64, n, problemAggregator); + for (long i = 0; i < n; i++) { if (storage.isNothing(i) || arg.isNothing(i)) { - isNothing.set(i); + builder.appendNulls(1); } else { - Long x = doLong(storage.getItem(i), arg.getItem(i), i, problemAggregator); + Long x = doLong(storage.getItemAsLong(i), arg.getItemAsLong(i), i, problemAggregator); if (x == null) { - isNothing.set(i); + builder.appendNulls(1); } else { - newVals[i] = x; + builder.appendLong(x); } } } - return new LongStorage(newVals, n, isNothing, IntegerType.INT_64); + return builder.seal(); } } @@ -74,32 +80,38 @@ void willBeNull() { protected abstract long doLong( long a, long b, - int ix, + long ix, MapOperationProblemAggregator problemAggregator, NullityReporter nullityReporter); @Override - public LongStorage run( - LongStorage storage, LongStorage arg, MapOperationProblemAggregator problemAggregator) { - int n = storage.size(); - long[] newVals = new long[n]; - BitSet isNothing = new BitSet(); + public Storage run( + ColumnLongStorage storage, + ColumnLongStorage arg, + MapOperationProblemAggregator problemAggregator) { + long n = storage.getSize(); + var builder = Builder.getForLong(IntegerType.INT_64, n, problemAggregator); NullityReporter nullityReporter = new NullityReporter(); - for (int i = 0; i < n; i++) { + for (long i = 0; i < n; i++) { if (storage.isNothing(i) || arg.isNothing(i)) { - isNothing.set(i); + builder.appendNulls(1); } else { long x = - doLong(storage.getItem(i), arg.getItem(i), i, problemAggregator, nullityReporter); + doLong( + storage.getItemAsLong(i), + arg.getItemAsLong(i), + i, + problemAggregator, + nullityReporter); if (nullityReporter.wasLastNull) { - isNothing.set(i); + builder.appendNulls(1); nullityReporter.wasLastNull = false; } else { - newVals[i] = x; + builder.appendLong(x); } } } - return new LongStorage(newVals, n, isNothing, IntegerType.INT_64); + return builder.seal(); } } @@ -109,16 +121,17 @@ public LongStorage run( private static final ProblemAggregator parentAggregatorForBenchmarks = BlackholeProblemAggregator.INSTANCE; - public static LongStorage runNoNulls(LongStorage arg1, LongStorage arg2) { + public static Storage runNoNulls(ColumnLongStorage arg1, ColumnLongStorage arg2) { MapOperationProblemAggregator problemAggregator = new MapOperationProblemAggregator(parentAggregatorForBenchmarks, null); NoNulls operation = new NoNulls() { @Override protected long doLong( - long a, long b, int ix, MapOperationProblemAggregator problemAggregator) { + long a, long b, long ix, MapOperationProblemAggregator problemAggregator) { if (b == 0) { - problemAggregator.reportDivisionByZero(ix); + // ToDo: ProblemAggregator should accept a long instead of an int. + problemAggregator.reportDivisionByZero((int) ix); return 0; } else { return a / b; @@ -129,16 +142,17 @@ protected long doLong( return operation.run(arg1, arg2, problemAggregator); } - public static LongStorage runBoxingNulls(LongStorage arg1, LongStorage arg2) { + public static Storage runBoxingNulls(ColumnLongStorage arg1, ColumnLongStorage arg2) { MapOperationProblemAggregator problemAggregator = new MapOperationProblemAggregator(parentAggregatorForBenchmarks, null); BoxingNulls operation = new BoxingNulls() { @Override protected Long doLong( - long a, long b, int ix, MapOperationProblemAggregator problemAggregator) { + long a, long b, long ix, MapOperationProblemAggregator problemAggregator) { if (b == 0) { - problemAggregator.reportDivisionByZero(ix); + // ToDo: ProblemAggregator should accept a long instead of an int. + problemAggregator.reportDivisionByZero((int) ix); return null; } else { return a / b; @@ -149,7 +163,7 @@ protected Long doLong( return operation.run(arg1, arg2, problemAggregator); } - public static LongStorage runReportingNulls(LongStorage arg1, LongStorage arg2) { + public static Storage runReportingNulls(ColumnLongStorage arg1, ColumnLongStorage arg2) { MapOperationProblemAggregator problemAggregator = new MapOperationProblemAggregator(parentAggregatorForBenchmarks, null); ReportingNulls operation = @@ -158,11 +172,12 @@ public static LongStorage runReportingNulls(LongStorage arg1, LongStorage arg2) protected long doLong( long a, long b, - int ix, + long ix, MapOperationProblemAggregator problemAggregator, NullityReporter nullityReporter) { if (b == 0) { - problemAggregator.reportDivisionByZero(ix); + // ToDo: ProblemAggregator should accept a long instead of an int. + problemAggregator.reportDivisionByZero((int) ix); nullityReporter.willBeNull(); return 0; } else { diff --git a/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/MapHelpers.java b/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/MapHelpers.java index bc9ace0b6283..be1865373561 100644 --- a/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/MapHelpers.java +++ b/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/MapHelpers.java @@ -1,10 +1,8 @@ package org.enso.exploratory_benchmark_helpers; -import java.util.BitSet; import java.util.function.Function; import org.enso.base.Text_Utils; import org.enso.table.data.column.builder.Builder; -import org.enso.table.data.column.storage.BoolStorage; import org.enso.table.data.column.storage.Storage; import org.enso.table.data.column.storage.StringStorage; import org.enso.table.data.column.storage.datetime.DateStorage; @@ -12,86 +10,81 @@ import org.enso.table.data.column.storage.type.IntegerType; import org.enso.table.data.column.storage.type.StorageType; import org.enso.table.data.column.storage.type.TextType; +import org.enso.table.problems.BlackholeProblemAggregator; import org.enso.table.problems.ProblemAggregator; public class MapHelpers { - public static StringStorage stringConcatBimap(StringStorage storage1, StringStorage storage2) { - if (storage1.size() != storage2.size()) { + public static Storage stringConcatBimap(StringStorage storage1, StringStorage storage2) { + if (storage1.getSize() != storage2.getSize()) { throw new IllegalArgumentException("Storage sizes must match"); } - int n = storage1.size(); - String[] result = new String[n]; - for (int i = 0; i < n; i++) { + long n = storage1.getSize(); + var builder = Builder.getForText(TextType.VARIABLE_LENGTH, n); + for (long i = 0; i < n; i++) { if (!storage1.isNothing(i) && !storage2.isNothing(i)) { - result[i] = storage1.getItem(i) + storage2.getItem(i); + builder.append(storage1.getItemBoxed(i) + storage2.getItemBoxed(i)); } else { - result[i] = null; + builder.appendNulls(1); } } - return new StringStorage(result, n, TextType.VARIABLE_LENGTH); + return builder.seal(); } - public static LongStorage longAddBimap(LongStorage storage1, LongStorage storage2) { - if (storage1.size() != storage2.size()) { + public static Storage longAddBimap(LongStorage storage1, LongStorage storage2) { + if (storage1.getSize() != storage2.getSize()) { throw new IllegalArgumentException("Storage sizes must match"); } - int n = storage1.size(); - long[] result = new long[n]; - BitSet isNothing = new BitSet(); - for (int i = 0; i < n; i++) { + long n = storage1.getSize(); + var builder = Builder.getForLong(IntegerType.INT_64, n, BlackholeProblemAggregator.INSTANCE); + for (long i = 0; i < n; i++) { if (!storage1.isNothing(i) && !storage2.isNothing(i)) { - result[i] = storage1.getItem(i) + storage2.getItem(i); + builder.appendLong(storage1.getItemAsLong(i) + storage2.getItemAsLong(i)); } else { - isNothing.set(i); + builder.appendNulls(1); } } - return new LongStorage(result, n, isNothing, IntegerType.INT_64); + return builder.seal(); } - public static BoolStorage textEndsWith(StringStorage storage, String suffix) { - int n = storage.size(); - BitSet result = new BitSet(); - BitSet isNothing = new BitSet(); - for (int i = 0; i < n; i++) { + public static Storage textEndsWith(StringStorage storage, String suffix) { + long n = storage.getSize(); + var builder = Builder.getForBoolean(n); + for (long i = 0; i < n; i++) { if (storage.isNothing(i)) { - isNothing.set(i); + builder.appendNulls(1); } else { - if (Text_Utils.ends_with(storage.getItem(i), suffix)) { - result.set(i); - } + builder.appendBoolean(Text_Utils.ends_with(storage.getItemBoxed(i), suffix)); } } - return new BoolStorage(result, isNothing, n, false); + return builder.seal(); } - public static LongStorage longAdd(LongStorage storage, long shift) { - int n = storage.size(); - long[] result = new long[n]; - BitSet isNothing = new BitSet(); - for (int i = 0; i < n; i++) { + public static Storage longAdd(LongStorage storage, long shift) { + long n = storage.getSize(); + var builder = Builder.getForLong(IntegerType.INT_64, n, BlackholeProblemAggregator.INSTANCE); + for (long i = 0; i < n; i++) { if (!storage.isNothing(i)) { - result[i] = storage.getItem(i) + shift; + builder.appendLong(storage.getItemAsLong(i) + shift); } else { - isNothing.set(i); + builder.appendNulls(1); } } - return new LongStorage(result, n, isNothing, IntegerType.INT_64); + return builder.seal(); } - public static LongStorage getYear(DateStorage storage) { - int n = storage.size(); - long[] result = new long[n]; - BitSet isNothing = new BitSet(); - for (int i = 0; i < n; i++) { + public static Storage getYear(DateStorage storage) { + long n = storage.getSize(); + var builder = Builder.getForLong(IntegerType.INT_64, n, BlackholeProblemAggregator.INSTANCE); + for (long i = 0; i < n; i++) { if (!storage.isNothing(i)) { - result[i] = storage.getItem(i).getYear(); + builder.appendLong(storage.getItemBoxed(i).getYear()); } else { - isNothing.set(i); + builder.appendNulls(1); } } - return new LongStorage(result, n, isNothing, IntegerType.INT_64); + return builder.seal(); } public static Storage mapCallback( @@ -99,9 +92,9 @@ public static Storage mapCallback( Function fn, StorageType expectedType, ProblemAggregator problemAggregator) { - int n = storage.size(); + long n = storage.getSize(); Builder builder = Builder.getForType(expectedType, n, problemAggregator); - for (int i = 0; i < n; i++) { + for (long i = 0; i < n; i++) { if (!storage.isNothing(i)) { builder.append(fn.apply(storage.getItemBoxed(i))); } else { diff --git a/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/SimpleStorageAggregateHelpers.java b/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/SimpleStorageAggregateHelpers.java index ac070cf0a43c..3cd95ff61cba 100644 --- a/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/SimpleStorageAggregateHelpers.java +++ b/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/SimpleStorageAggregateHelpers.java @@ -9,9 +9,9 @@ public class SimpleStorageAggregateHelpers { public static long sumLongStorage(LongStorage storage) { long sum = 0; - for (int i = 0; i < storage.size(); i++) { + for (long i = 0; i < storage.getSize(); i++) { if (!storage.isNothing(i)) { - sum += storage.getItem(i); + sum += storage.getItemAsLong(i); } } return sum; @@ -30,10 +30,10 @@ public static long sumMonthsOfDateStorage(DateStorage storage) { public static String longestText(StringStorage storage) { long longest = -1; String longestText = null; - int n = storage.size(); - for (int i = 0; i < n; i++) { + long n = storage.getSize(); + for (long i = 0; i < n; i++) { if (!storage.isNothing(i)) { - String text = storage.getItem(i); + String text = storage.getItemBoxed(i); long length = Text_Utils.grapheme_length(text); if (length > longest) { longest = length; diff --git a/test/Exploratory_Benchmarks/src/Table/Column_Aggregate.enso b/test/Exploratory_Benchmarks/src/Table/Column_Aggregate.enso index 14ef144949a2..8d8f5b9334bb 100644 --- a/test/Exploratory_Benchmarks/src/Table/Column_Aggregate.enso +++ b/test/Exploratory_Benchmarks/src/Table/Column_Aggregate.enso @@ -64,7 +64,7 @@ type Primitive_Total_Aggregate storage = get_storage_for_column self.int_column (0.up_to n).fold 0 acc-> ix-> if storage.isNothing ix then acc else - acc + storage.getItem ix + acc + storage.getItemAsLong ix verify_correctness self = Helpers.check_results [self.current_aggregate_implementation, self.java_loop, self.enso_aggregate_vector_proxy, self.enso_aggregate_storage_get_item] diff --git a/test/Exploratory_Benchmarks/src/Table/Column_Bi_Map.enso b/test/Exploratory_Benchmarks/src/Table/Column_Bi_Map.enso index e153a33eb839..bb6c3a7bcdba 100644 --- a/test/Exploratory_Benchmarks/src/Table/Column_Bi_Map.enso +++ b/test/Exploratory_Benchmarks/src/Table/Column_Bi_Map.enso @@ -32,7 +32,7 @@ type Boxed_Bi_Map_Test enso_map_with_builder self = n = self.text_column_1.length if self.text_column_2.length != n then Panic.throw "LENGTH MISMATCH" else - builder = Builder.getForType TextType.VARIABLE_LENGTH n Nothing + builder = Builder.getForText TextType.VARIABLE_LENGTH n storage_1 = get_storage_for_column self.text_column_1 storage_2 = get_storage_for_column self.text_column_2 0.up_to n . each i-> @@ -71,8 +71,8 @@ type Primitive_Bi_Map_Test storage_2 = get_storage_for_column self.int_column_2 0.up_to n . each i-> if storage_1.isNothing i || storage_2.isNothing i then builder.appendNulls 1 else - item_1 = storage_1.getItem i - item_2 = storage_2.getItem i + item_1 = storage_1.getItemAsLong i + item_2 = storage_2.getItemAsLong i res = item_1 + item_2 builder.appendLong res Column.from_storage "result" builder.seal diff --git a/test/Exploratory_Benchmarks/src/Table/Column_Map.enso b/test/Exploratory_Benchmarks/src/Table/Column_Map.enso index 578812b580ce..b5e3628ce2c2 100644 --- a/test/Exploratory_Benchmarks/src/Table/Column_Map.enso +++ b/test/Exploratory_Benchmarks/src/Table/Column_Map.enso @@ -73,13 +73,10 @@ type Primitive_Map_Test builder = Builder.getForLong IntegerType.INT_64 n Nothing storage = get_storage_for_column self.int_column 0.up_to n . each i-> - case storage.isNothing i of - True -> - builder.appendNulls 1 - False -> - item = storage.getItem i - x = item + shift - builder.appendLong x + if storage.isNothing i then builder.appendNulls 1 else + item = storage.getItemAsLong i + x = item + shift + builder.appendLong x Column.from_storage "result" builder.seal verify_correctness self = diff --git a/test/Exploratory_Benchmarks/src/Table/Enso_Callback.enso b/test/Exploratory_Benchmarks/src/Table/Enso_Callback.enso index 5df09fd890b5..63f2753d0ad2 100644 --- a/test/Exploratory_Benchmarks/src/Table/Enso_Callback.enso +++ b/test/Exploratory_Benchmarks/src/Table/Enso_Callback.enso @@ -37,7 +37,7 @@ type Boxed_Enso_Callback_Test enso_map_with_builder self = n = self.text_column.length fn = self.fn - builder = Builder.getForType TextType.VARIABLE_LENGTH n Nothing + builder = Builder.getForText TextType.VARIABLE_LENGTH n storage = Storage.get_storage_for_column self.text_column 0.up_to n . each i-> case storage.getItemBoxed i of @@ -91,12 +91,9 @@ type Primitive_Enso_Callback_Test builder = Builder.getForLong IntegerType.INT_64 n Nothing storage = Storage.get_storage_for_column self.int_column 0.up_to n . each i-> - case storage.isNothing i of - True -> - builder.appendNulls 1 - False -> - item = storage.getItem i - builder.append (fn item) + if storage.isNothing i then builder.appendNulls 1 else + item = storage.getItemAsLong i + builder.append (fn item) Column.from_storage "result" builder.seal enso_map_with_builder_1_call_boxed self = diff --git a/test/Visualization_Tests/src/Table_Spec.enso b/test/Visualization_Tests/src/Table_Spec.enso index 44daa70183ed..a24247eb90da 100644 --- a/test/Visualization_Tests/src/Table_Spec.enso +++ b/test/Visualization_Tests/src/Table_Spec.enso @@ -154,7 +154,7 @@ add_specs suite_builder = space_table = Table.new [["A", space_data]] vis = Visualization.prepare_visualization space_table 1000 value_type_char = JS_Object.from_pairs [["type", "Value_Type"], ["constructor", "Char"], ["display_text", "Char (variable length, max_size=unlimited)"], ["size", Nothing], ["variable_length", True]] - json = make_json header=["A"] data=[space_data.take 1000] all_rows=11000 value_type=[value_type_char] has_index_col=True get_child_node="get_row" number_of_nothing=[0] number_of_whitespace_sampled=[8266] + json = make_json header=["A"] data=[space_data.take 1000] all_rows=11000 value_type=[value_type_char] has_index_col=True get_child_node="get_row" number_of_nothing=[0] number_of_whitespace_sampled=[8267] vis . should_equal json main filter=Nothing =