Skip to content

Commit

Permalink
Improve performance of dateTimeSerialization (#2363)
Browse files Browse the repository at this point in the history
  • Loading branch information
AFine-gs authored Oct 12, 2023
1 parent 3f04b21 commit 02d2dbe
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class RelationalResultToCSVSerializerWithTransformersApplied extends CsvS
{
private final RelationalResult relationalResult;
private final CSVFormat csvFormat;
private final ValueTransformer valueTransformer = new ValueTransformer();

public RelationalResultToCSVSerializerWithTransformersApplied(RelationalResult relationalResult)
{
Expand Down Expand Up @@ -97,7 +98,7 @@ private void printRecords(ResultSet resultSet, CSVPrinter csvPrinter) throws SQL
{
for (int i = 1; i <= columnCount; ++i)
{
csvPrinter.print(transformers.get(i - 1).valueOf(relationalResult.getValue(i)));
csvPrinter.print(valueTransformer.transformRelationalValue(relationalResult.getValue(i), transformers.get(i - 1)));
}
csvPrinter.println();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import io.opentracing.util.GlobalTracer;
import org.eclipse.collections.api.block.function.Function;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.list.MutableList;
import org.eclipse.collections.impl.utility.Iterate;
import org.finos.legend.engine.plan.execution.result.serialization.ExecutionResultObjectMapperFactory;
import org.finos.legend.engine.plan.execution.result.serialization.Serializer;
Expand All @@ -38,7 +37,6 @@
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.List;
import java.util.ServiceLoader;

public class RelationalResultToJsonDefaultSerializer extends Serializer
{
Expand All @@ -55,6 +53,7 @@ public class RelationalResultToJsonDefaultSerializer extends Serializer
private final byte[] b_values = "{\"values\": [".getBytes();
private final byte[] b_end = "]}".getBytes();
private final byte[] b_endResult = "}".getBytes();
private final ValueTransformer transformer = new ValueTransformer();

public RelationalResultToJsonDefaultSerializer(RelationalResult relationalResult)
{
Expand Down Expand Up @@ -127,14 +126,15 @@ private void processRow(OutputStream outputStream) throws IOException, SQLExcept
{
outputStream.write(b_values);

MutableList<Function<Object, Object>> transformers = relationalResult.getTransformers();

for (int i = 1; i <= relationalResult.columnCount - 1; i++)
{
outputStream.write(purePrimitiveToJsonConverter.apply(transformers.get(i - 1).valueOf(relationalResult.getValue(i))).getBytes());
Object value = relationalResult.getValue(i);

outputStream.write(((String) transformer.transformWrappedRelationalValue(value, relationalResult.getTransformers().get(i - 1).andThen(purePrimitiveToJsonConverter))).getBytes());
outputStream.write(b_comma);
}
outputStream.write(purePrimitiveToJsonConverter.apply(transformers.get(relationalResult.columnCount - 1).valueOf(relationalResult.getValue(relationalResult.columnCount))).getBytes());
outputStream.write(((String) transformer.transformWrappedRelationalValue(relationalResult.getValue(relationalResult.columnCount), relationalResult.getTransformers().get(relationalResult.columnCount - 1).andThen(purePrimitiveToJsonConverter))).getBytes());
outputStream.write(b_end);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ public class RelationalResultToPureFormatSerializer extends Serializer
protected final ObjectMapper objectMapper = ExecutionResultObjectMapperFactory.getNewObjectMapper();
private final byte[] start_token;
private final byte[] end_token;

protected RelationalResult relationalResult;

public RelationalResultToPureFormatSerializer(RelationalResult relationalResult, byte[] start_token, byte[] end_token)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

public class RelationalResultToPureTDSSerializer extends RelationalResultToPureFormatSerializer
{
private final ValueTransformer valueTransformer = new ValueTransformer();

public RelationalResultToPureTDSSerializer(RelationalResult relationalResult)
{
super(relationalResult, object_start, object_end);
Expand Down Expand Up @@ -85,11 +87,11 @@ public void processRow(OutputStream outputStream) throws IOException, SQLExcepti

for (int i = 1; i <= relationalResult.columnCount - 1; i++)
{
objectMapper.writeValue(outputStream, transformers.get(i - 1).valueOf(relationalResult.getValue(i)));
objectMapper.writeValue(outputStream, valueTransformer.transformRelationalValue(relationalResult.getValue(i), transformers.get(i - 1)));
outputStream.write(b_comma);
}

objectMapper.writeValue(outputStream, transformers.get(relationalResult.columnCount - 1).valueOf(relationalResult.getValue(relationalResult.columnCount)));
objectMapper.writeValue(outputStream, valueTransformer.transformRelationalValue(relationalResult.getValue(relationalResult.columnCount), transformers.get(relationalResult.columnCount - 1)));

outputStream.write(b_array_close);
outputStream.write(object_end);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

public class RelationalResultToPureTDSToObjectSerializer extends RelationalResultToPureFormatSerializer
{
private final ValueTransformer valueTransformer = new ValueTransformer();

public RelationalResultToPureTDSToObjectSerializer(RelationalResult relationalResult)
{
super(relationalResult, b_array_open, b_array_close);
Expand All @@ -45,13 +47,13 @@ public void processRow(OutputStream outputStream) throws IOException, SQLExcepti
{
objectMapper.writeValue(outputStream, ((TDSBuilder) relationalResult.builder).columns.get(i - 1).name);
outputStream.write(b_colon);
objectMapper.writeValue(outputStream, transformers.get(i - 1).valueOf(relationalResult.getValue(i)));
objectMapper.writeValue(outputStream, valueTransformer.transformRelationalValue(relationalResult.getValue(i), transformers.get(i - 1)));
outputStream.write(b_comma);
}

objectMapper.writeValue(outputStream, ((TDSBuilder) relationalResult.builder).columns.get(relationalResult.columnCount - 1).name);
outputStream.write(b_colon);
objectMapper.writeValue(outputStream, transformers.get(relationalResult.columnCount - 1).valueOf(relationalResult.getValue(relationalResult.columnCount)));
objectMapper.writeValue(outputStream, valueTransformer.transformRelationalValue(relationalResult.getValue(relationalResult.columnCount), transformers.get(relationalResult.columnCount - 1)));

outputStream.write(object_end);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2023 Goldman Sachs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package org.finos.legend.engine.plan.execution.stores.relational.serialization;

import java.sql.Timestamp;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.function.Function;

class ValueTransformer
{
private final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private final DateTimeFormatter timeFormatterWithZ = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.nnnnnnnnnZ");
private final ZoneOffset offset = ZoneOffset.UTC;

protected ValueTransformer()
{

}

protected Object transformWrappedRelationalValue(Object relationalValue, Function<Object, ?> transformer)
{
if (relationalValue instanceof Timestamp)
{
return "\"" + timeFormatterWithZ.format(((Timestamp) relationalValue).toInstant().atOffset(offset)) + "\"";

}
else if (relationalValue instanceof java.sql.Date)
{
return "\"" + ((java.sql.Date) relationalValue).toLocalDate().format(dateFormat) + "\"";
}
else
{
return transformer.apply(relationalValue);
}

}

protected Object transformRelationalValue(Object relationalValue, Function<Object, ?> transformer)
{
if (relationalValue instanceof Timestamp)
{
return timeFormatterWithZ.format(((Timestamp) relationalValue).toInstant().atOffset(offset));

}
else if (relationalValue instanceof java.sql.Date)
{
return ((java.sql.Date) relationalValue).toLocalDate().format(dateFormat);
}
else
{
return transformer.apply(relationalValue);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2023 Goldman Sachs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package org.finos.legend.engine.plan.execution.stores.relational.serialization;

import org.junit.Assert;
import org.junit.Test;

import java.sql.Date;
import java.sql.Timestamp;

public class TestValueTransformer
{
@Test
public void testValueTransformer()
{
ValueTransformer valueTransformer = new ValueTransformer();
Timestamp time = new Timestamp(1696532242123L);
Date date = new Date(1696532242123L);


org.eclipse.collections.api.block.function.Function<Object, Object> transform = value -> value + "Transformed";
Assert.assertEquals("2023-10-05T18:57:22.123000000+0000", valueTransformer.transformRelationalValue(time, transform));
Assert.assertEquals("2023-10-05", valueTransformer.transformRelationalValue(date, transform));
Assert.assertEquals("otherTransformed", valueTransformer.transformRelationalValue("other", transform));

Assert.assertEquals("\"2023-10-05T18:57:22.123000000+0000\"", valueTransformer.transformWrappedRelationalValue(time, transform));
Assert.assertEquals("\"2023-10-05\"", valueTransformer.transformWrappedRelationalValue(date, transform));
Assert.assertEquals("otherTransformed", valueTransformer.transformWrappedRelationalValue("other", transform));

}

}

0 comments on commit 02d2dbe

Please sign in to comment.