Compare commits
16 Commits
master
...
karm_varch
| Author | SHA1 | Date |
|---|---|---|
|
|
192c653064 | |
|
|
18f62408b4 | |
|
|
060d9aa8fb | |
|
|
2e664319d0 | |
|
|
403db25390 | |
|
|
f21318dfce | |
|
|
944d9b359b | |
|
|
5db57ae57a | |
|
|
5319205e30 | |
|
|
cc4130fc0d | |
|
|
20236a7771 | |
|
|
70ca802271 | |
|
|
bad3f729aa | |
|
|
7266a1e2ec | |
|
|
55722a5cba | |
|
|
173e5bbd2a |
|
|
@ -48,7 +48,7 @@
|
|||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.2.5-og1.0.1</version>
|
||||
<version>42.2.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
|
|
|||
6
pom.xml
6
pom.xml
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
<properties>
|
||||
<air.main.basedir>${project.basedir}</air.main.basedir>
|
||||
|
||||
<air.check.skip-all>true</air.check.skip-all>
|
||||
<air.check.skip-spotbugs>true</air.check.skip-spotbugs>
|
||||
<air.check.skip-pmd>true</air.check.skip-pmd>
|
||||
<air.check.skip-jacoco>true</air.check.skip-jacoco>
|
||||
|
|
@ -140,7 +140,7 @@
|
|||
<module>hetu-sql-migration-tool</module>
|
||||
<module>hetu-transport</module>
|
||||
<module>hetu-server</module>
|
||||
<module>hetu-server-rpm</module>
|
||||
<!-- <module>hetu-server-rpm</module>-->
|
||||
<module>hetu-common</module>
|
||||
<module>hetu-hazelcast</module>
|
||||
</modules>
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ public abstract class AbstractBenchmark
|
|||
}
|
||||
for (int i = 0; i < measuredIterations; i++) {
|
||||
Map<String, Long> results = runOnce();
|
||||
System.out.println("output_rows: " + results.get("output_rows") + " | output_bytes: " + results.get("output_bytes"));
|
||||
if (benchmarkResultHook != null) {
|
||||
benchmarkResultHook.addResults(results);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,6 +128,11 @@ public abstract class AbstractOperatorBenchmark
|
|||
new AllowAllAccessControl());
|
||||
}
|
||||
|
||||
private static List<Split> getNextBatch(SplitSource splitSource)
|
||||
{
|
||||
return getFutureValue(splitSource.getNextBatch(NOT_PARTITIONED, Lifespan.taskWide(), 1000)).getSplits();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown()
|
||||
{
|
||||
|
|
@ -200,7 +205,7 @@ public abstract class AbstractOperatorBenchmark
|
|||
};
|
||||
}
|
||||
|
||||
private Split getLocalQuerySplit(Session session, TableHandle handle)
|
||||
Split getLocalQuerySplit(Session session, TableHandle handle)
|
||||
{
|
||||
SplitSource splitSource = localQueryRunner.getSplitManager().getSplits(session, handle, UNGROUPED_SCHEDULING, null, Optional.empty(), Collections.emptyMap(), ImmutableSet.of(), false);
|
||||
List<Split> splits = new ArrayList<>();
|
||||
|
|
@ -211,11 +216,6 @@ public abstract class AbstractOperatorBenchmark
|
|||
return splits.get(0);
|
||||
}
|
||||
|
||||
private static List<Split> getNextBatch(SplitSource splitSource)
|
||||
{
|
||||
return getFutureValue(splitSource.getNextBatch(NOT_PARTITIONED, Lifespan.taskWide(), 1000)).getSplits();
|
||||
}
|
||||
|
||||
protected final OperatorFactory createHashProjectOperator(int operatorId, PlanNodeId planNodeId, List<Type> types)
|
||||
{
|
||||
SymbolAllocator symbolAllocator = new SymbolAllocator();
|
||||
|
|
@ -256,14 +256,17 @@ public abstract class AbstractOperatorBenchmark
|
|||
protected Map<String, Long> execute(TaskContext taskContext)
|
||||
{
|
||||
List<Driver> drivers = createDrivers(taskContext);
|
||||
|
||||
long peakMemory = 0;
|
||||
boolean done = false;
|
||||
|
||||
while (!done) {
|
||||
boolean processed = false;
|
||||
for (Driver driver : drivers) {
|
||||
if (!driver.isFinished()) {
|
||||
long start1 = System.currentTimeMillis();
|
||||
driver.process();
|
||||
long end1 = System.currentTimeMillis();
|
||||
System.out.println("driver ID: "+driver.getDriverContext().getDriverId()+" execute time: " + (end1 - start1));
|
||||
long lastPeakMemory = peakMemory;
|
||||
peakMemory = (long) taskContext.getTaskStats().getUserMemoryReservation().getValue(BYTE);
|
||||
if (peakMemory <= lastPeakMemory) {
|
||||
|
|
@ -274,6 +277,7 @@ public abstract class AbstractOperatorBenchmark
|
|||
}
|
||||
done = !processed;
|
||||
}
|
||||
|
||||
return ImmutableMap.of("peak_memory", peakMemory);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
* 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 io.prestosql.benchmark;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import io.prestosql.operator.DriverContext;
|
||||
import io.prestosql.operator.HashAggregationOmniOperator;
|
||||
import io.prestosql.operator.Operator;
|
||||
import io.prestosql.operator.OperatorContext;
|
||||
import io.prestosql.operator.OperatorFactory;
|
||||
import io.prestosql.operator.PageSourceOperator;
|
||||
import io.prestosql.operator.aggregation.InternalAggregationFunction;
|
||||
import io.prestosql.spi.Page;
|
||||
import io.prestosql.spi.PageBuilder;
|
||||
import io.prestosql.spi.block.BlockBuilder;
|
||||
import io.prestosql.spi.connector.ConnectorPageSource;
|
||||
import io.prestosql.spi.function.Signature;
|
||||
import io.prestosql.spi.type.Type;
|
||||
import io.prestosql.sql.planner.plan.PlanNodeId;
|
||||
import io.prestosql.testing.LocalQueryRunner;
|
||||
import nova.hetu.omnicache.runtime.OmniRuntime;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static io.prestosql.benchmark.BenchmarkQueryRunner.createLocalQueryRunner;
|
||||
import static io.prestosql.spi.function.FunctionKind.AGGREGATE;
|
||||
import static io.prestosql.spi.type.BigintType.BIGINT;
|
||||
|
||||
public class HashAggregationOmniBenchmark
|
||||
extends AbstractSimpleOperatorBenchmark
|
||||
{
|
||||
public static Page inputPage;
|
||||
public static Iterator<Page> inputPagesIterator;
|
||||
private final InternalAggregationFunction longSum;
|
||||
|
||||
public HashAggregationOmniBenchmark(LocalQueryRunner localQueryRunner)
|
||||
{
|
||||
super(localQueryRunner, "hash_agg", 0, 1);
|
||||
|
||||
longSum = localQueryRunner.getMetadata().getAggregateFunctionImplementation(
|
||||
new Signature("sum", AGGREGATE, BIGINT.getTypeSignature(), BIGINT.getTypeSignature()));
|
||||
}
|
||||
|
||||
public static void builderPage()
|
||||
{
|
||||
List<Type> dataTypes = new ArrayList<>();
|
||||
dataTypes.add(BIGINT);
|
||||
dataTypes.add(BIGINT);
|
||||
dataTypes.add(BIGINT);
|
||||
dataTypes.add(BIGINT);
|
||||
PageBuilder pb = PageBuilder.withMaxPageSize(Integer.MAX_VALUE, dataTypes);
|
||||
BlockBuilder group1 = pb.getBlockBuilder(0);
|
||||
BlockBuilder group2 = pb.getBlockBuilder(1);
|
||||
BlockBuilder sum1 = pb.getBlockBuilder(2);
|
||||
BlockBuilder sum2 = pb.getBlockBuilder(3);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
group1.writeLong(i);
|
||||
group2.writeLong(j);
|
||||
sum1.writeLong(i);
|
||||
sum2.writeLong(j);
|
||||
pb.declarePosition();
|
||||
}
|
||||
}
|
||||
inputPage = pb.build();
|
||||
|
||||
List<Page> inputPages = new ArrayList<>();
|
||||
for (int i = 0; i < 3; i++) {
|
||||
inputPages.add(inputPage);
|
||||
}
|
||||
inputPagesIterator = inputPages.iterator();
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
|
||||
builderPage();
|
||||
LocalQueryRunner localQueryRunner = createLocalQueryRunner();
|
||||
|
||||
new HashAggregationOmniBenchmark(localQueryRunner).runBenchmark(new SimpleLineBenchmarkResultWriter(System.out));
|
||||
}
|
||||
|
||||
OperatorFactory createOmniCacheTableScanOperator(int operatorId, PlanNodeId planNodeId, String tableName, String... columnNames)
|
||||
{
|
||||
checkArgument(session.getCatalog().isPresent(), "catalog not set");
|
||||
checkArgument(session.getSchema().isPresent(), "schema not set");
|
||||
// // look up the table
|
||||
// Metadata metadata = localQueryRunner.getMetadata();
|
||||
// QualifiedObjectName qualifiedTableName = new QualifiedObjectName(session.getCatalog().get(), session.getSchema().get(), tableName);
|
||||
// TableHandle tableHandle = metadata.getTableHandle(session, qualifiedTableName).orElse(null);
|
||||
// checkArgument(tableHandle != null, "Table %s does not exist", qualifiedTableName);
|
||||
//
|
||||
// // lookup the columns
|
||||
// Map<String, ColumnHandle> allColumnHandles = metadata.getColumnHandles(session, tableHandle);
|
||||
// ImmutableList.Builder<ColumnHandle> columnHandlesBuilder = ImmutableList.builder();
|
||||
// for (String columnName : columnNames) {
|
||||
// ColumnHandle columnHandle = allColumnHandles.get(columnName);
|
||||
// checkArgument(columnHandle != null, "Table %s does not have a column %s", tableName, columnName);
|
||||
// columnHandlesBuilder.add(columnHandle);
|
||||
// }
|
||||
// List<ColumnHandle> columnHandles = columnHandlesBuilder.build();
|
||||
//
|
||||
// // get the split for this table
|
||||
// Split split = getLocalQuerySplit(session, tableHandle);
|
||||
return new OperatorFactory()
|
||||
{
|
||||
@Override
|
||||
public Operator createOperator(DriverContext driverContext)
|
||||
{
|
||||
OperatorContext operatorContext = driverContext.addOperatorContext(operatorId, planNodeId, "BenchmarkSource");
|
||||
ConnectorPageSource pageSource = createOmniCachePageSource();//localQueryRunner.getPageSourceManager().createPageSource(session, split, tableHandle, columnHandles, Optional.empty());
|
||||
|
||||
return new PageSourceOperator(pageSource, operatorContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noMoreOperators()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperatorFactory duplicate()
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private ConnectorPageSource createOmniCachePageSource()
|
||||
{
|
||||
return new ConnectorPageSource()
|
||||
{
|
||||
boolean isFinished = false;
|
||||
|
||||
@Override
|
||||
public long getCompletedBytes()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getReadTimeNanos()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished()
|
||||
{
|
||||
return isFinished;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page getNextPage()
|
||||
{
|
||||
if (inputPagesIterator.hasNext()) {
|
||||
Page next = inputPagesIterator.next();
|
||||
return next;
|
||||
}
|
||||
isFinished = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSystemMemoryUsage()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
throws IOException
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<? extends OperatorFactory> createOperatorFactories()
|
||||
{
|
||||
OperatorFactory tableScanOperator = createOmniCacheTableScanOperator(0, new PlanNodeId("test"), "orders", "orderstatus", "totalprice");
|
||||
|
||||
String compileID;
|
||||
OmniRuntime omniRuntime;
|
||||
//omni
|
||||
long start = System.currentTimeMillis();
|
||||
omniRuntime = new OmniRuntime();
|
||||
// String code = "|k:vec[i64],v:vec[i64]|" +
|
||||
// "let rs = tovec(result(for(zip(k,v),dictmerger[i64,i64,+],|b,i,n| merge(b,{n.$0,n.$1}))));" +
|
||||
// "let k = result(for(rs,appender[i64],|b,i,n| merge(b,n.$0)));" +
|
||||
// "let v = result(for(rs,appender[i64],|b,i,n| merge(b,n.$1)));" +
|
||||
//// "{k,v}";
|
||||
// String code = "|v0 :vec[vec[i64]], v1: vec[vec[i64]], v2: vec[vec[f64]], v3: vec[vec[f64]]|let sum_dict_ = for(zip(v0, v1, v2, v3), dictmerger[{i64,i64}, {f64, f64},+], |b,i,n|for(zip(n.0,n.1, n.2,n.3), b, |b_, i_, m|merge(b, {{m.0,m.1}, {m.2,m.3}})));let dict_0_1 = tovec(result(sum_dict_));let k0 = result(for(dict_0_1, appender[i64], |b, i, n| merge(b, n.0.0)));let k1 = result(for(dict_0_1, appender[i64], |b, i, n| merge(b, n.0.1)));let sum_1 = result(for(dict_0_1, appender[f64], |b, i, n| merge(b, n.1.0)));let sum_2 = result(for(dict_0_1, appender[f64], |b, i, n| merge(b, n.1.1)));{k0, k1, sum_1, sum_2}";
|
||||
|
||||
String code = "|v0 :vec[vec[i64]], v1: vec[vec[i64]], v2: vec[vec[f64]], v3: vec[vec[f64]]|" +
|
||||
"let sum_dict_ = for(zip(v0, v1, v2, v3), dictmerger[{i64,i64}, {f64, f64},+], |b,i,n| " +
|
||||
"for(zip(n.$0, n.$1, n.$2, n.$3), b, |b_, i_, m|" +
|
||||
"merge(b, {{m.$0, m.$1}, {m.$2, m.$3}})));" +
|
||||
"let dict_0_1 = tovec(result(sum_dict_));" +
|
||||
"let k0 = result( for (dict_0_1, appender[i64], |b, i, n | merge(b, n.$0.$0)));" +
|
||||
"let k1 = result( for (dict_0_1, appender[i64], |b, i, n | merge(b, n.$0.$1)));" +
|
||||
"let sum_1 = result( for (dict_0_1, appender[f64], |b, i, n | merge(b, n.$1.$0)));" +
|
||||
"let sum_2 = result( for (dict_0_1, appender[f64], |b, i, n | merge(b, n.$1.$1)));" +
|
||||
"{k0, k1, sum_1, sum_2}";
|
||||
compileID = omniRuntime.compile(code);
|
||||
long end = System.currentTimeMillis();
|
||||
System.out.println("omni compile time: " + (end - start));
|
||||
|
||||
HashAggregationOmniOperator.HashAggregationOmniOperatorFactory aggregationOperator = new HashAggregationOmniOperator.HashAggregationOmniOperatorFactory(1, new PlanNodeId("1"), omniRuntime, Collections.singletonList(compileID));
|
||||
System.out.println("create hash op fac execute time: " + (System.currentTimeMillis() - start));
|
||||
|
||||
return ImmutableList.of(tableScanOperator, aggregationOperator);
|
||||
}
|
||||
}
|
||||
|
|
@ -68,7 +68,7 @@ import static java.util.Objects.requireNonNull;
|
|||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
|
||||
@ThreadSafe
|
||||
class StatementClientV1
|
||||
public class StatementClientV1
|
||||
implements StatementClient
|
||||
{
|
||||
private static final MediaType MEDIA_TYPE_TEXT = MediaType.parse("text/plain; charset=utf-8");
|
||||
|
|
@ -123,6 +123,26 @@ class StatementClientV1
|
|||
processResponse(response.getHeaders(), response.getValue());
|
||||
}
|
||||
|
||||
private static String urlEncode(String value)
|
||||
{
|
||||
try {
|
||||
return URLEncoder.encode(value, "UTF-8");
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String urlDecode(String value)
|
||||
{
|
||||
try {
|
||||
return URLDecoder.decode(value, "UTF-8");
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private Request buildQueryRequest(ClientSession session, String query)
|
||||
{
|
||||
HttpUrl url = HttpUrl.get(session.getServer());
|
||||
|
|
@ -515,26 +535,6 @@ class StatementClientV1
|
|||
}
|
||||
}
|
||||
|
||||
private static String urlEncode(String value)
|
||||
{
|
||||
try {
|
||||
return URLEncoder.encode(value, "UTF-8");
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String urlDecode(String value)
|
||||
{
|
||||
try {
|
||||
return URLDecoder.decode(value, "UTF-8");
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private enum State
|
||||
{
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import io.prestosql.spi.block.BlockEncoding;
|
|||
import io.prestosql.spi.block.BlockEncodingSerde;
|
||||
import io.prestosql.spi.block.ByteArrayBlockEncoding;
|
||||
import io.prestosql.spi.block.DictionaryBlockEncoding;
|
||||
import io.prestosql.spi.block.DoubleArrayBlockEncoding;
|
||||
import io.prestosql.spi.block.Int128ArrayBlockEncoding;
|
||||
import io.prestosql.spi.block.IntArrayBlockEncoding;
|
||||
import io.prestosql.spi.block.LazyBlockEncoding;
|
||||
|
|
@ -53,6 +54,7 @@ public final class ExternalBlockEncodingSerde
|
|||
.put(ByteArrayBlockEncoding.NAME, new ByteArrayBlockEncoding())
|
||||
.put(ShortArrayBlockEncoding.NAME, new ShortArrayBlockEncoding())
|
||||
.put(IntArrayBlockEncoding.NAME, new IntArrayBlockEncoding())
|
||||
.put(DoubleArrayBlockEncoding.NAME, new DoubleArrayBlockEncoding())
|
||||
.put(LongArrayBlockEncoding.NAME, new LongArrayBlockEncoding())
|
||||
.put(Int128ArrayBlockEncoding.NAME, new Int128ArrayBlockEncoding())
|
||||
.put(DictionaryBlockEncoding.NAME, new DictionaryBlockEncoding())
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
connector.name=dc
|
||||
connection-url=http://localhost:8090
|
||||
connection-user=root
|
||||
connection-password=
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
#
|
||||
# WARNING
|
||||
# ^^^^^^^
|
||||
# This configuration file is for development only and should NOT be used
|
||||
# in production. For example configuration, see the Presto documentation.
|
||||
#
|
||||
|
||||
connector.name=hive-hadoop2
|
||||
hive.metastore.uri=thrift://localhost:9083
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
#
|
||||
# WARNING
|
||||
# ^^^^^^^
|
||||
# This configuration file is for development only and should NOT be used
|
||||
# in production. For example configuration, see the Presto documentation.
|
||||
#
|
||||
|
||||
connector.name=jmx
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
#
|
||||
# WARNING
|
||||
# ^^^^^^^
|
||||
# This configuration file is for development only and should NOT be used
|
||||
# in production. For example configuration, see the Presto documentation.
|
||||
#
|
||||
|
||||
connector.name=localfile
|
||||
presto-logs.http-request-log.pattern=http-request.log*
|
||||
|
|
@ -1 +1,2 @@
|
|||
connector.name=memory
|
||||
memory.max-data-per-node=4GB
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
connector.name=postgresql
|
||||
connection-url=jdbc:postgresql://postgres:15432/test
|
||||
connection-user=swarm
|
||||
connection-password=swarm
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
connector.name=sqlserver
|
||||
connection-url=jdbc:sqlserver://localhost:1433
|
||||
connection-user=sa
|
||||
connection-password=sa
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
#
|
||||
# WARNING
|
||||
# ^^^^^^^
|
||||
# This configuration file is for development only and should NOT be used
|
||||
# in production. For example configuration, see the Presto documentation.
|
||||
#
|
||||
|
||||
connector.name=presto-thrift
|
||||
presto.thrift.client.addresses=127.0.0.1:1234
|
||||
|
|
@ -12,6 +12,8 @@ http-server.http.port=8080
|
|||
http-server.max-request-header-size=64kB
|
||||
http-server.max-response-header-size=64kB
|
||||
|
||||
#omnicache
|
||||
stack-trace-visible=true
|
||||
|
||||
#To enable SSL
|
||||
#http-server.https.enabled=true
|
||||
|
|
@ -51,17 +53,15 @@ query.client.timeout=5m
|
|||
query.min-expire-age=30m
|
||||
|
||||
plugin.bundles=\
|
||||
../presto-tpch/pom.xml, \
|
||||
../presto-resource-group-managers/pom.xml,\
|
||||
../presto-memory/pom.xml,\
|
||||
../presto-jmx/pom.xml,\
|
||||
../presto-hive-hadoop2/pom.xml,\
|
||||
../presto-example-http/pom.xml,\
|
||||
../presto-kafka/pom.xml, \
|
||||
../presto-tpch/pom.xml, \
|
||||
../presto-local-file/pom.xml, \
|
||||
../presto-mysql/pom.xml,\
|
||||
../hetu-datacenter/pom.xml,\
|
||||
../hetu-oracle/pom.xml, \
|
||||
../presto-sqlserver/pom.xml, \
|
||||
../presto-postgresql/pom.xml, \
|
||||
../presto-thrift/pom.xml, \
|
||||
|
|
@ -70,7 +70,11 @@ plugin.bundles=\
|
|||
../hetu-seed-store/pom.xml,\
|
||||
../hetu-listener/pom.xml,\
|
||||
../hetu-filesystem-client/pom.xml,\
|
||||
../hetu-heuristic-index/pom.xml
|
||||
|
||||
# ../hetu-oracle/pom.xml, \
|
||||
# ../hetu-datacenter/pom.xml,\
|
||||
# ../hetu-heuristic-index/pom.xml
|
||||
|
||||
presto.version=testversion
|
||||
node-scheduler.include-coordinator=true
|
||||
shuffle-service.host=192.168.0.202
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
|
|
@ -16,6 +16,13 @@
|
|||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- https://mvnrepository.com/artifact/com.ning/async-http-client -->
|
||||
<dependency>
|
||||
<groupId>com.ning</groupId>
|
||||
<artifactId>async-http-client</artifactId>
|
||||
<version>1.8.8</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.locationtech.jts</groupId>
|
||||
<artifactId>jts-core</artifactId>
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ public final class SystemSessionProperties
|
|||
public static final String REUSE_TABLE_SCAN = "reuse_table_scan";
|
||||
public static final String SPILL_REUSE_TABLESCAN = "spill_reuse_tablescan";
|
||||
public static final String SPILL_THRESHOLD_REUSE_TABLESCAN = "spill_threshold_reuse_tablescan";
|
||||
public static final String OMNI_CACHE_ENABLED = "omni_cache_enabled";
|
||||
|
||||
private final List<PropertyMetadata<?>> sessionProperties;
|
||||
|
||||
|
|
@ -166,6 +167,11 @@ public final class SystemSessionProperties
|
|||
HetuConfig hetuConfig)
|
||||
{
|
||||
sessionProperties = ImmutableList.of(
|
||||
booleanProperty(
|
||||
"omni_cache_enabled",
|
||||
"omni cache enabled",
|
||||
true,
|
||||
false),
|
||||
stringProperty(
|
||||
EXECUTION_POLICY,
|
||||
"Policy used for scheduling query tasks",
|
||||
|
|
@ -687,11 +693,6 @@ public final class SystemSessionProperties
|
|||
false));
|
||||
}
|
||||
|
||||
public List<PropertyMetadata<?>> getSessionProperties()
|
||||
{
|
||||
return sessionProperties;
|
||||
}
|
||||
|
||||
public static boolean isCrossRegionDynamicFilterEnabled(Session session)
|
||||
{
|
||||
return session.getSystemProperty(ENABLE_CROSS_REGION_DYNAMIC_FILTER, Boolean.class);
|
||||
|
|
@ -1207,4 +1208,14 @@ public final class SystemSessionProperties
|
|||
{
|
||||
return session.getSystemProperty(SPILL_THRESHOLD_REUSE_TABLESCAN, Integer.class);
|
||||
}
|
||||
|
||||
public static Boolean getOmniCacheEnabled(Session session)
|
||||
{
|
||||
return session.getSystemProperty(OMNI_CACHE_ENABLED, Boolean.class);
|
||||
}
|
||||
|
||||
public List<PropertyMetadata<?>> getSessionProperties()
|
||||
{
|
||||
return sessionProperties;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,10 @@ public class TaskId
|
|||
this.fullId = fullId;
|
||||
}
|
||||
|
||||
public String getFullId(){
|
||||
return fullId;
|
||||
}
|
||||
|
||||
public QueryId getQueryId()
|
||||
{
|
||||
return new QueryId(QueryId.parseDottedId(fullId, 3, "taskId").get(0));
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import io.prestosql.spi.block.BlockEncoding;
|
|||
import io.prestosql.spi.block.BlockEncodingSerde;
|
||||
import io.prestosql.spi.block.ByteArrayBlockEncoding;
|
||||
import io.prestosql.spi.block.DictionaryBlockEncoding;
|
||||
import io.prestosql.spi.block.DoubleArrayBlockEncoding;
|
||||
import io.prestosql.spi.block.Int128ArrayBlockEncoding;
|
||||
import io.prestosql.spi.block.IntArrayBlockEncoding;
|
||||
import io.prestosql.spi.block.LazyBlockEncoding;
|
||||
|
|
@ -189,6 +190,7 @@ public final class MetadataManager
|
|||
addBlockEncoding(new ByteArrayBlockEncoding());
|
||||
addBlockEncoding(new ShortArrayBlockEncoding());
|
||||
addBlockEncoding(new IntArrayBlockEncoding());
|
||||
addBlockEncoding(new DoubleArrayBlockEncoding());
|
||||
addBlockEncoding(new LongArrayBlockEncoding());
|
||||
addBlockEncoding(new Int128ArrayBlockEncoding());
|
||||
addBlockEncoding(new DictionaryBlockEncoding());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* 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 io.prestosql.operator;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import io.prestosql.execution.Lifespan;
|
||||
import io.prestosql.spi.Page;
|
||||
import io.prestosql.sql.planner.plan.PlanNodeId;
|
||||
import nova.hetu.omnicache.runtime.OmniRuntime;
|
||||
import nova.hetu.omnicache.vector.LongVec;
|
||||
import nova.hetu.omnicache.vector.Vec;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public class HashAggregationOmniOperator
|
||||
implements Operator
|
||||
{
|
||||
OperatorContext operatorContext;
|
||||
//omni
|
||||
List<String> compileID;
|
||||
OmniRuntime omniRuntime;
|
||||
|
||||
private boolean finishing;
|
||||
private boolean finished;
|
||||
// for yield when memory is not available
|
||||
// private Work<?> unfinishedWork;
|
||||
|
||||
HashAggregationOmniWork<Object> omniWork;
|
||||
private String omniKey;
|
||||
|
||||
public HashAggregationOmniOperator(OperatorContext operatorContext, OmniRuntime omniRuntime, List<String> compileID)
|
||||
{
|
||||
this.operatorContext = operatorContext;
|
||||
this.omniKey= UUID.randomUUID().toString()+"-"+operatorContext.getDriverContext().getPipelineContext().getTaskId();
|
||||
this.omniRuntime = omniRuntime;
|
||||
this.compileID = compileID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperatorContext getOperatorContext()
|
||||
{
|
||||
return this.operatorContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish()
|
||||
{
|
||||
finishing = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished()
|
||||
{
|
||||
return finished;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
throws Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsInput()
|
||||
{
|
||||
if (finishing) {
|
||||
return false;
|
||||
}
|
||||
if (omniWork != null && !omniWork.isFinished()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInput(Page page)
|
||||
{
|
||||
checkState(!finishing, "Operator is already finishing");
|
||||
requireNonNull(page, "page is null");
|
||||
|
||||
if (omniWork == null) {
|
||||
omniWork = new HashAggregationOmniWork(page, omniRuntime, compileID, omniKey);
|
||||
}
|
||||
else {
|
||||
omniWork.updatePages(page);
|
||||
}
|
||||
omniWork.process();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page getOutput()
|
||||
{
|
||||
if (finished) {
|
||||
return null;
|
||||
}
|
||||
if (finishing) {
|
||||
if (omniWork == null) {
|
||||
finished = true;
|
||||
return null;
|
||||
}
|
||||
if (omniWork != null && omniWork.isFinished()) {
|
||||
finished = true;
|
||||
return omniWork.getResult();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<?> startMemoryRevoke()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishMemoryRevoke()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static class HashAggregationOmniOperatorFactory
|
||||
implements OperatorFactory
|
||||
{
|
||||
OmniRuntime omniRuntime;
|
||||
List<String> compileID;
|
||||
int operatorId;
|
||||
PlanNodeId planNodeId;
|
||||
|
||||
public HashAggregationOmniOperatorFactory(int operatorId, PlanNodeId planNodeId, OmniRuntime omniRuntime, List<String> compileID)
|
||||
{
|
||||
this.operatorId = operatorId;
|
||||
this.planNodeId = planNodeId;
|
||||
this.omniRuntime = omniRuntime;
|
||||
this.compileID = compileID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Operator createOperator(DriverContext driverContext)
|
||||
{
|
||||
OperatorContext operatorContext = driverContext.addOperatorContext(operatorId, planNodeId, HashAggregationOmniOperator.class.getSimpleName());
|
||||
HashAggregationOmniOperator hashAggregationOperator = new HashAggregationOmniOperator(operatorContext, omniRuntime, compileID);
|
||||
return hashAggregationOperator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noMoreOperators()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noMoreOperators(Lifespan lifespan)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperatorFactory duplicate()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* 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 io.prestosql.operator;
|
||||
|
||||
import io.prestosql.spi.Page;
|
||||
import io.prestosql.spi.block.Block;
|
||||
import io.prestosql.spi.block.DoubleArrayBlock;
|
||||
import io.prestosql.spi.block.LongArrayBlock;
|
||||
import io.prestosql.spi.type.BigintType;
|
||||
import io.prestosql.spi.type.DoubleType;
|
||||
import io.prestosql.spi.type.Type;
|
||||
import nova.hetu.omnicache.runtime.OmniOpStep;
|
||||
import nova.hetu.omnicache.runtime.OmniRuntime;
|
||||
import nova.hetu.omnicache.vector.DoubleVec;
|
||||
import nova.hetu.omnicache.vector.IntVec;
|
||||
import nova.hetu.omnicache.vector.LongVec;
|
||||
import nova.hetu.omnicache.vector.Vec;
|
||||
import nova.hetu.omnicache.vector.VecType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
public final class HashAggregationOmniWork<O>
|
||||
implements Work<Page>
|
||||
{
|
||||
|
||||
OmniRuntime omniRuntime;
|
||||
List<String> compileID;
|
||||
private boolean finished;
|
||||
private Vec[] result;
|
||||
private Page page;
|
||||
String omniKey;
|
||||
VecType[] outTypes;
|
||||
|
||||
public HashAggregationOmniWork(Page page, OmniRuntime omniRuntime, List<String> compileID, String omniKey)
|
||||
{
|
||||
this.page = page;
|
||||
this.omniRuntime = omniRuntime;
|
||||
this.compileID = compileID;
|
||||
this.omniKey = omniKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean process()
|
||||
{
|
||||
int channelCount = page.getChannelCount();
|
||||
Vec[] inputData = new Vec[channelCount];
|
||||
for (int i = 0; i < channelCount; i++) {
|
||||
inputData[i] = page.getBlock(i).getValues();
|
||||
}
|
||||
// LongVec
|
||||
//
|
||||
int rowNum = page.getPositionCount();
|
||||
|
||||
outTypes = new VecType[] {VecType.LONG, VecType.LONG, VecType.LONG, VecType.LONG};
|
||||
|
||||
if (inputData[channelCount - 1] instanceof LongVec) {
|
||||
omniRuntime.execute(compileID.get(0), omniKey, inputData, rowNum, outTypes, OmniOpStep.INTERMEDIATE);
|
||||
}
|
||||
else {
|
||||
omniRuntime.execute(compileID.get(1), omniKey, inputData, rowNum, outTypes, OmniOpStep.INTERMEDIATE);
|
||||
}
|
||||
|
||||
finished = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page getResult()
|
||||
{
|
||||
checkState(finished, "process has not finished");
|
||||
|
||||
result = (Vec[]) omniRuntime.getResults(omniKey, outTypes);
|
||||
|
||||
return toResult(result);
|
||||
}
|
||||
|
||||
public Page toResult(Vec[] omniExecutionResult)
|
||||
{
|
||||
int positionCount = omniExecutionResult[0].size();
|
||||
int chanelCount = omniExecutionResult.length;
|
||||
|
||||
boolean[] valueIsNull = new boolean[positionCount];
|
||||
for (int i = 0; i < positionCount; i++) {
|
||||
valueIsNull[i] = false;
|
||||
}
|
||||
Block[] blocks = new Block[chanelCount];
|
||||
for (int i = 0; i < chanelCount; i++) {
|
||||
if (omniExecutionResult[i] instanceof DoubleVec) {
|
||||
blocks[i] = new DoubleArrayBlock(positionCount, Optional.of(valueIsNull), ((DoubleVec) omniExecutionResult[i]));
|
||||
}
|
||||
else {
|
||||
blocks[i] = new LongArrayBlock(positionCount, Optional.of(valueIsNull), (LongVec) omniExecutionResult[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Page page = new Page(blocks);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
public boolean isFinished()
|
||||
{
|
||||
return finished;
|
||||
}
|
||||
|
||||
public void updatePages(Page page)
|
||||
{
|
||||
this.page = page;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
///*
|
||||
// * 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 io.prestosql.operator;
|
||||
//
|
||||
//import com.google.common.util.concurrent.ListenableFuture;
|
||||
//import io.prestosql.spi.Page;
|
||||
//import nova.hetu.omnicache.runtime.OmniRuntime;
|
||||
//import nova.hetu.omnicache.vector.Vec;
|
||||
//import nova.hetu.omnicache.vector.VecType;
|
||||
//
|
||||
//import static com.google.common.base.Preconditions.checkState;
|
||||
//
|
||||
//public final class HashAggregationOmniWorkProcessor<T>
|
||||
// implements WorkProcessor<T>
|
||||
//{
|
||||
//
|
||||
// OmniRuntime omniRuntime;
|
||||
// String compileID;
|
||||
// private boolean finished;
|
||||
// private Vec<?>[] result;
|
||||
// private Page page;
|
||||
//
|
||||
// public HashAggregationOmniWorkProcessor(Page page,OmniRuntime omniRuntime, String compileID)
|
||||
// {
|
||||
// this.page=page;
|
||||
// this.omniRuntime = omniRuntime;
|
||||
// this.compileID = compileID;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean process()
|
||||
// {
|
||||
// Vec[] inputData = new Vec[2];
|
||||
//// inputData[0] = (LongVec) page.getBlock(0).getValuesVec();
|
||||
//// inputData[1] = (LongVec) page.getBlock(1).getValuesVec();
|
||||
//
|
||||
// for (int i = 0; i < inputData[0].size(); i++) {
|
||||
// System.out.println("block0 before omni:" + inputData[0].get(i));
|
||||
// System.out.println("block1 before omni:" + inputData[1].get(i));
|
||||
// }
|
||||
//
|
||||
// int rowNum = page.getPositionCount();
|
||||
//
|
||||
// VecType[] outTypes = {VecType.LONG, VecType.LONG};
|
||||
// long start1 = System.currentTimeMillis();
|
||||
//
|
||||
// result = omniRuntime.execute(compileID, inputData, rowNum, outTypes);
|
||||
// Vec<?>[] vecs = (Vec<?>[]) result;
|
||||
//
|
||||
// for (int i = 0; i < vecs[0].size(); i++) {
|
||||
// System.out.println("block0 after omni:" + vecs[0].get(i));
|
||||
// System.out.println("block1 after omni:" + vecs[1].get(i));
|
||||
// }
|
||||
//
|
||||
// long end1 = System.currentTimeMillis();
|
||||
// System.out.println("omni execute time: " + (end1 - start1));
|
||||
// finished = true;
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isBlocked()
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public ListenableFuture<?> getBlockedFuture()
|
||||
// {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public T getResult()
|
||||
// {
|
||||
// checkState(finished, "process has not finished");
|
||||
// return result;
|
||||
// }
|
||||
//
|
||||
// public boolean isFinished(){
|
||||
// return finished;
|
||||
// }
|
||||
//}
|
||||
|
|
@ -19,6 +19,8 @@ import io.prestosql.operator.Work;
|
|||
import io.prestosql.operator.WorkProcessor;
|
||||
import io.prestosql.spi.Page;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface HashAggregationBuilder
|
||||
extends AutoCloseable
|
||||
{
|
||||
|
|
@ -38,4 +40,8 @@ public interface HashAggregationBuilder
|
|||
ListenableFuture<?> startMemoryRevoke();
|
||||
|
||||
void finishMemoryRevoke();
|
||||
|
||||
default WorkProcessor<Page> getOmniExecuteResult() {return null;}
|
||||
|
||||
default void setOmniExecuteResult(Optional<Object> o) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,6 +143,15 @@ public class InMemoryHashAggregationBuilder
|
|||
for (Aggregator aggregator : aggregators) {
|
||||
aggregator.processPage(groupByIdBlock, page);
|
||||
}
|
||||
long l = 20000L;
|
||||
for (long i = 1; i < l; i++) {
|
||||
if (i % 5000==0) {
|
||||
System.out.println(i);
|
||||
}
|
||||
for (long i1 = 1; i1 < l; i1++) {
|
||||
long x = i / i1;
|
||||
}
|
||||
}
|
||||
// we do not need any output from TransformWork for this case
|
||||
return null;
|
||||
});
|
||||
|
|
@ -274,6 +283,16 @@ public class InMemoryHashAggregationBuilder
|
|||
|
||||
pageBuilder.reset();
|
||||
|
||||
// long l = 20000L;
|
||||
// for (long i = 1; i < l; i++) {
|
||||
// if (i % 4000==0) {
|
||||
// System.out.println(i);
|
||||
// }
|
||||
// for (long i1 = 1; i1 < l; i1++) {
|
||||
// long x = i / i1;
|
||||
// }
|
||||
// }
|
||||
|
||||
List<Type> types = groupByHash.getTypes();
|
||||
while (!pageBuilder.isFull() && groupIds.hasNext()) {
|
||||
int groupId = groupIds.nextInt();
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ import static java.lang.Math.max;
|
|||
public class SpillableHashAggregationBuilder
|
||||
implements HashAggregationBuilder
|
||||
{
|
||||
private InMemoryHashAggregationBuilder hashAggregationBuilder;
|
||||
private final SpillerFactory spillerFactory;
|
||||
private final List<AccumulatorFactory> accumulatorFactories;
|
||||
private final AggregationNode.Step step;
|
||||
|
|
@ -59,12 +58,12 @@ public class SpillableHashAggregationBuilder
|
|||
private final LocalMemoryContext localRevocableMemoryContext;
|
||||
private final long memoryLimitForMerge;
|
||||
private final long memoryLimitForMergeWithMemory;
|
||||
private final JoinCompiler joinCompiler;
|
||||
private InMemoryHashAggregationBuilder hashAggregationBuilder;
|
||||
private Optional<Spiller> spiller = Optional.empty();
|
||||
private Optional<MergingHashAggregationBuilder> merger = Optional.empty();
|
||||
private Optional<MergeHashSort> mergeHashSort = Optional.empty();
|
||||
private ListenableFuture<?> spillInProgress = immediateFuture(null);
|
||||
private final JoinCompiler joinCompiler;
|
||||
|
||||
// todo get rid of that and only use revocable memory
|
||||
private long emptyHashAggregationBuilderSize;
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ public class PluginManager
|
|||
.add("io.hete.core.type.")
|
||||
.add("io.hete.core.util.")
|
||||
.add("io.prestosql.sql.tree.")
|
||||
.add("nova.hetu.omnicache.vector.")
|
||||
.build();
|
||||
|
||||
private static final Logger log = Logger.get(PluginManager.class);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ import io.prestosql.operator.ExchangeOperator.ExchangeOperatorFactory;
|
|||
import io.prestosql.operator.ExplainAnalyzeOperator.ExplainAnalyzeOperatorFactory;
|
||||
import io.prestosql.operator.FilterAndProjectOperator;
|
||||
import io.prestosql.operator.GroupIdOperator;
|
||||
import io.prestosql.operator.HashAggregationOmniOperator;
|
||||
import io.prestosql.operator.HashAggregationOperator.HashAggregationOperatorFactory;
|
||||
import io.prestosql.operator.HashBuilderOperator.HashBuilderOperatorFactory;
|
||||
import io.prestosql.operator.HashSemiJoinOperator.HashSemiJoinOperatorFactory;
|
||||
|
|
@ -206,6 +207,7 @@ import io.prestosql.sql.tree.SymbolReference;
|
|||
import io.prestosql.statestore.StateStoreProvider;
|
||||
import io.prestosql.statestore.listener.StateStoreListenerManager;
|
||||
import io.prestosql.type.FunctionType;
|
||||
import nova.hetu.omnicache.runtime.OmniRuntime;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
|
@ -244,6 +246,7 @@ import static io.prestosql.SystemSessionProperties.getDynamicFilteringMaxPerDriv
|
|||
import static io.prestosql.SystemSessionProperties.getDynamicFilteringWaitTime;
|
||||
import static io.prestosql.SystemSessionProperties.getFilterAndProjectMinOutputPageRowCount;
|
||||
import static io.prestosql.SystemSessionProperties.getFilterAndProjectMinOutputPageSize;
|
||||
import static io.prestosql.SystemSessionProperties.getOmniCacheEnabled;
|
||||
import static io.prestosql.SystemSessionProperties.getSpillOperatorThresholdReuseExchange;
|
||||
import static io.prestosql.SystemSessionProperties.getTaskConcurrency;
|
||||
import static io.prestosql.SystemSessionProperties.getTaskWriterCount;
|
||||
|
|
@ -2969,6 +2972,7 @@ public class LocalExecutionPlanner
|
|||
Optional<DataSize> maxPartialAggregationMemorySize,
|
||||
boolean useSystemMemory)
|
||||
{
|
||||
|
||||
List<Symbol> aggregationOutputSymbols = new ArrayList<>();
|
||||
List<AccumulatorFactory> accumulatorFactories = new ArrayList<>();
|
||||
for (Map.Entry<Symbol, Aggregation> entry : aggregations.entrySet()) {
|
||||
|
|
@ -3019,6 +3023,59 @@ public class LocalExecutionPlanner
|
|||
}
|
||||
else {
|
||||
Optional<Integer> hashChannel = hashSymbol.map(channelGetter(source));
|
||||
if (getOmniCacheEnabled(session)) {
|
||||
List<String> compileID = new ArrayList<>();
|
||||
OmniRuntime omniRuntime;
|
||||
long start = System.currentTimeMillis();
|
||||
omniRuntime = new OmniRuntime();
|
||||
ArrayList<String> codes = new ArrayList<>();
|
||||
|
||||
//two group by and two sum
|
||||
codes.add("|v0 :vec[vec[i64]], v1: vec[vec[i64]], v2: vec[vec[i64]], v3: vec[vec[i64]]|" +
|
||||
"let sum_dict_ = for(zip(v0, v1, v2, v3), dictmerger[{i64,i64}, {i64, i64},+], |b,i,n| " +
|
||||
"for(zip(n.$0, n.$1, n.$2, n.$3), b, |b_, i_, m|" +
|
||||
"merge(b, {{m.$0, m.$1}, {m.$2, m.$3}})));" +
|
||||
"let dict_0_1 = tovec(result(sum_dict_));" +
|
||||
"let k0 = result( for (dict_0_1, appender[i64], |b, i, n | merge(b, n.$0.$0)));" +
|
||||
"let k1 = result( for (dict_0_1, appender[i64], |b, i, n | merge(b, n.$0.$1)));" +
|
||||
"let sum_1 = result( for (dict_0_1, appender[i64], |b, i, n | merge(b, n.$1.$0)));" +
|
||||
"let sum_2 = result( for (dict_0_1, appender[i64], |b, i, n | merge(b, n.$1.$1)));" +
|
||||
"{k0, k1, sum_1, sum_2}");
|
||||
|
||||
// sum and avg--using DoubleArrayBlock
|
||||
// codes.add("|v0 :vec[vec[i64]], v1: vec[vec[i64]], v2: vec[vec[i64]], v3: vec[vec[i64]]|" +
|
||||
// "let sum_dict_2 = for(zip(v0, v1, v2), dictmerger[{i64,i64}, i64,+], |b,i,n| " +
|
||||
// "for(zip(n.$0, n.$1, n.$2), b, |b_, i_, m|" +
|
||||
// "merge(b, {{m.$0, m.$1}, m.$2})));" +
|
||||
// "let dict_0_1 = tovec(result(sum_dict_2));" +
|
||||
// "let k0 = result(for(dict_0_1, appender[i64], |b, i, n| merge(b, n.$0.$0)));" +
|
||||
// "let k1 = result(for(dict_0_1, appender[i64], |b, i, n| merge(b, n.$0.$1)));" +
|
||||
// "let sum_2 = result(for(dict_0_1, appender[i64], |b, i, n| merge(b, n.$1)));" +
|
||||
// "let avg_sum_3 = for(zip(v0, v1, v3), dictmerger[{i64,i64}, {i64, i64}, +], |b,i,n| " +
|
||||
// "for(zip(n.$0, n.$1, n.$2), b, |b_, i_, m|" +
|
||||
// "merge(b, {{m.$0, m.$1}, {m.$2, i64(1)}})));" +
|
||||
// "let avg_3 = result(for(tovec(result(avg_sum_3)), appender[f64], |b, i, n| merge(b, f64(n.$1.$0) / f64(n.$1.$1))));" +
|
||||
// "{k0, k1, sum_2, avg_3}");
|
||||
// codes.add("|v0 :vec[vec[i64]], v1: vec[vec[i64]], v2: vec[vec[i64]], v3: vec[vec[f64]]|" +
|
||||
// "let sum_dict_2 = for(zip(v0, v1, v2), dictmerger[{i64,i64}, i64,+], |b,i,n| " +
|
||||
// "for(zip(n.$0, n.$1, n.$2), b, |b_, i_, m|" +
|
||||
// "merge(b, {{m.$0, m.$1}, m.$2})));" +
|
||||
// "let dict_0_1 = tovec(result(sum_dict_2));" +
|
||||
// "let k0 = result(for(dict_0_1, appender[i64], |b, i, n| merge(b, n.$0.$0)));" +
|
||||
// "let k1 = result(for(dict_0_1, appender[i64], |b, i, n| merge(b, n.$0.$1)));" +
|
||||
// "let sum_2 = result(for(dict_0_1, appender[i64], |b, i, n| merge(b, n.$1)));" +
|
||||
// "let avg_sum_3 = for(zip(v0, v1, v3), dictmerger[{i64,i64}, {f64, f64}, +], |b,i,n| " +
|
||||
// "for(zip(n.$0, n.$1, n.$2), b, |b_, i_, m|" +
|
||||
// "merge(b, {{m.$0, m.$1}, {m.$2, 1.0}})));" +
|
||||
// "let avg_3 = result(for(tovec(result(avg_sum_3)), appender[f64], |b, i, n| merge(b, f64(n.$1.$0) / f64(n.$1.$1))));" +
|
||||
// "{k0, k1, sum_2, avg_3}");
|
||||
|
||||
for (String code : codes) {
|
||||
compileID.add(omniRuntime.compile(code));
|
||||
}
|
||||
log.info("omni compile time: %s",System.currentTimeMillis()-start);
|
||||
return new HashAggregationOmniOperator.HashAggregationOmniOperatorFactory(context.getNextOperatorId(), planNodeId, omniRuntime, compileID);
|
||||
}
|
||||
return new HashAggregationOperatorFactory(
|
||||
context.getNextOperatorId(),
|
||||
planNodeId,
|
||||
|
|
|
|||
|
|
@ -126,6 +126,37 @@ public class TestAggregationOperator
|
|||
assertEquals(driverContext.getMemoryUsage(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAggregation1()
|
||||
{
|
||||
List<Page> input = rowPagesBuilder(VARCHAR, BIGINT, VARCHAR, BIGINT, REAL, DOUBLE, VARCHAR)
|
||||
.addSequencePage(100000000, 0, 0, 300, 500, 400, 500, 500)
|
||||
.build();
|
||||
long start = System.currentTimeMillis();
|
||||
OperatorFactory operatorFactory = new AggregationOperatorFactory(
|
||||
0,
|
||||
new PlanNodeId("test"),
|
||||
Step.SINGLE,
|
||||
ImmutableList.of(
|
||||
LONG_SUM.bind(ImmutableList.of(1), Optional.empty())
|
||||
),
|
||||
false);
|
||||
|
||||
DriverContext driverContext = createTaskContext(executor, scheduledExecutor, TEST_SESSION)
|
||||
.addPipelineContext(0, true, true, false)
|
||||
.addDriverContext();
|
||||
|
||||
MaterializedResult expected = resultBuilder(driverContext.getSession(), BIGINT)
|
||||
.row(4999999950000000L)
|
||||
.build();
|
||||
|
||||
assertOperatorEquals(operatorFactory, driverContext, input, expected);
|
||||
long end = System.currentTimeMillis() - start;
|
||||
System.out.println("presto takes: " + end + " ms");
|
||||
assertEquals(driverContext.getSystemMemoryUsage(), 0);
|
||||
assertEquals(driverContext.getMemoryUsage(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMemoryTracking()
|
||||
throws Exception
|
||||
|
|
|
|||
|
|
@ -0,0 +1,282 @@
|
|||
/*
|
||||
* 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 io.prestosql.operator;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import io.prestosql.memory.context.AggregatedMemoryContext;
|
||||
import io.prestosql.metadata.Metadata;
|
||||
import io.prestosql.operator.aggregation.InternalAggregationFunction;
|
||||
import io.prestosql.operator.aggregation.builder.HashAggregationBuilder;
|
||||
import io.prestosql.operator.aggregation.builder.InMemoryHashAggregationBuilder;
|
||||
import io.prestosql.spi.Page;
|
||||
import io.prestosql.spi.PageBuilder;
|
||||
import io.prestosql.spi.block.BlockBuilder;
|
||||
import io.prestosql.spi.function.Signature;
|
||||
import io.prestosql.spi.type.Type;
|
||||
import io.prestosql.spiller.Spiller;
|
||||
import io.prestosql.spiller.SpillerFactory;
|
||||
import io.prestosql.sql.gen.JoinCompiler;
|
||||
import io.prestosql.sql.planner.plan.PlanNodeId;
|
||||
import io.prestosql.testing.MaterializedResult;
|
||||
import io.prestosql.testing.TestingTaskContext;
|
||||
import nova.hetu.omnicache.runtime.OmniRuntime;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
|
||||
import static io.airlift.concurrent.Threads.daemonThreadsNamed;
|
||||
import static io.airlift.units.DataSize.succinctBytes;
|
||||
import static io.prestosql.SessionTestUtils.TEST_SESSION;
|
||||
import static io.prestosql.metadata.MetadataManager.createTestMetadataManager;
|
||||
import static io.prestosql.operator.OperatorAssertion.assertPagesEqualIgnoreOrder;
|
||||
import static io.prestosql.operator.OperatorAssertion.toPages;
|
||||
import static io.prestosql.spi.function.FunctionKind.AGGREGATE;
|
||||
import static io.prestosql.spi.type.BigintType.BIGINT;
|
||||
import static io.prestosql.spi.type.DoubleType.DOUBLE;
|
||||
import static io.prestosql.spi.type.VarcharType.VARCHAR;
|
||||
import static io.prestosql.testing.MaterializedResult.resultBuilder;
|
||||
import static java.util.concurrent.Executors.newCachedThreadPool;
|
||||
import static java.util.concurrent.Executors.newScheduledThreadPool;
|
||||
import static org.testng.Assert.assertNotEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
@Test(singleThreaded = true)
|
||||
public class TestHashAggregationOmniOperator
|
||||
{
|
||||
private static final Metadata metadata = createTestMetadataManager();
|
||||
|
||||
private static final InternalAggregationFunction LONG_AVERAGE = metadata.getAggregateFunctionImplementation(
|
||||
new Signature("avg", AGGREGATE, DOUBLE.getTypeSignature(), BIGINT.getTypeSignature()));
|
||||
private static final InternalAggregationFunction LONG_SUM = metadata.getAggregateFunctionImplementation(
|
||||
new Signature("sum", AGGREGATE, BIGINT.getTypeSignature(), BIGINT.getTypeSignature()));
|
||||
private static final InternalAggregationFunction COUNT = metadata.getAggregateFunctionImplementation(
|
||||
new Signature("count", AGGREGATE, BIGINT.getTypeSignature()));
|
||||
|
||||
private static final int MAX_BLOCK_SIZE_IN_BYTES = 64 * 1024;
|
||||
|
||||
private ExecutorService executor;
|
||||
private ScheduledExecutorService scheduledExecutor;
|
||||
private JoinCompiler joinCompiler = new JoinCompiler(createTestMetadataManager());
|
||||
private DummySpillerFactory spillerFactory;
|
||||
String weldIR = "|v0 :vec[vec[i64]], v1: vec[vec[i64]], v2: vec[vec[f64]], v3: vec[vec[f64]]|" +
|
||||
"let sum_dict_ = for(zip(v0, v1, v2, v3), dictmerger[{i64,i64}, {f64, f64},+], |b,i,n| " +
|
||||
"for(zip(n.$0, n.$1, n.$2, n.$3), b, |b_, i_, m|" +
|
||||
"merge(b, {{m.$0, m.$1}, {m.$2, m.$3}})));" +
|
||||
"let dict_0_1 = tovec(result(sum_dict_));" +
|
||||
"let k0 = result( for (dict_0_1, appender[i64], |b, i, n | merge(b, n.$0.$0)));" +
|
||||
"let k1 = result( for (dict_0_1, appender[i64], |b, i, n | merge(b, n.$0.$1)));" +
|
||||
"let sum_1 = result( for (dict_0_1, appender[f64], |b, i, n | merge(b, n.$1.$0)));" +
|
||||
"let sum_2 = result( for (dict_0_1, appender[f64], |b, i, n | merge(b, n.$1.$1)));" +
|
||||
"{k0, k1, sum_1, sum_2}";
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp()
|
||||
{
|
||||
executor = newCachedThreadPool(daemonThreadsNamed("test-executor-%s"));
|
||||
scheduledExecutor = newScheduledThreadPool(2, daemonThreadsNamed("test-scheduledExecutor-%s"));
|
||||
spillerFactory = new DummySpillerFactory();
|
||||
}
|
||||
|
||||
@DataProvider(name = "hashEnabled")
|
||||
public static Object[][] hashEnabled()
|
||||
{
|
||||
return new Object[][] {{true}, {false}};
|
||||
}
|
||||
|
||||
@DataProvider(name = "hashEnabledAndMemoryLimitForMergeValues")
|
||||
public static Object[][] hashEnabledAndMemoryLimitForMergeValuesProvider()
|
||||
{
|
||||
return new Object[][] {
|
||||
{true, true, true, 8, Integer.MAX_VALUE},
|
||||
{true, true, false, 8, Integer.MAX_VALUE},
|
||||
{false, false, false, 0, 0},
|
||||
{false, true, true, 0, 0},
|
||||
{false, true, false, 0, 0},
|
||||
{false, true, true, 8, 0},
|
||||
{false, true, false, 8, 0},
|
||||
{false, true, true, 8, Integer.MAX_VALUE},
|
||||
{false, true, false, 8, Integer.MAX_VALUE}};
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] dataType()
|
||||
{
|
||||
return new Object[][] {{VARCHAR}, {BIGINT}};
|
||||
}
|
||||
|
||||
@AfterMethod(alwaysRun = true)
|
||||
public void tearDown()
|
||||
{
|
||||
spillerFactory = null;
|
||||
executor.shutdownNow();
|
||||
scheduledExecutor.shutdownNow();
|
||||
}
|
||||
|
||||
private List<Page> builderPage()
|
||||
{
|
||||
List<Type> dataTypes = new ArrayList<>();
|
||||
dataTypes.add(BIGINT);
|
||||
dataTypes.add(BIGINT);
|
||||
dataTypes.add(BIGINT);
|
||||
dataTypes.add(BIGINT);
|
||||
PageBuilder pb = PageBuilder.withMaxPageSize(Integer.MAX_VALUE, dataTypes);
|
||||
BlockBuilder group1 = pb.getBlockBuilder(0);
|
||||
BlockBuilder group2 = pb.getBlockBuilder(1);
|
||||
BlockBuilder sum1 = pb.getBlockBuilder(2);
|
||||
BlockBuilder sum2 = pb.getBlockBuilder(3);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int j = 0; j < pageRows; j++) {
|
||||
group1.writeLong(i);
|
||||
group2.writeLong(i);
|
||||
sum1.writeLong(1);
|
||||
sum2.writeLong(1);
|
||||
pb.declarePosition();
|
||||
}
|
||||
}
|
||||
Page build = pb.build();
|
||||
|
||||
List<Page> inputPages = new ArrayList<>();
|
||||
for (int i = 0; i < totalPageCount; i++) {
|
||||
inputPages.add(build);
|
||||
}
|
||||
return inputPages;
|
||||
}
|
||||
|
||||
int pageRows = 10;
|
||||
int totalPageCount = 1000;
|
||||
|
||||
@Test(invocationCount = 20)
|
||||
public void testHashAggregation()
|
||||
{
|
||||
|
||||
int threadNum = 100;
|
||||
List<Page> input = builderPage();
|
||||
OmniRuntime omniRuntime = new OmniRuntime();
|
||||
String compileID = omniRuntime.compile(weldIR);
|
||||
|
||||
DriverContext driverContext = createDriverContext(Integer.MAX_VALUE);
|
||||
|
||||
MaterializedResult.Builder expectedBuilder = resultBuilder(driverContext.getSession(), BIGINT, BIGINT, BIGINT, BIGINT);
|
||||
|
||||
long sum = totalPageCount * pageRows;
|
||||
expectedBuilder.row(0L, 0L, sum, sum);
|
||||
expectedBuilder.row(1L, 1L, sum, sum);
|
||||
MaterializedResult expected = expectedBuilder.build();
|
||||
|
||||
ExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(threadNum));
|
||||
ArrayList<ListenableFuture<List<Page>>> futureArrayList = new ArrayList<>();
|
||||
List<List<Page>> pagesList = new ArrayList<>();
|
||||
for (int i = 0; i < threadNum; i++) {
|
||||
final int x = i;
|
||||
ListenableFuture<List<Page>> submit = (ListenableFuture<List<Page>>) service.submit(() -> toPages(new HashAggregationOmniOperator.HashAggregationOmniOperatorFactory(x, new PlanNodeId(String.valueOf(x)), omniRuntime, Collections.singletonList(compileID)), driverContext, input, false));
|
||||
submit.addListener(() -> {
|
||||
List<Page> pages = null;
|
||||
try {
|
||||
pages = submit.get();
|
||||
}
|
||||
catch (InterruptedException|ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
pagesList.add(pages);
|
||||
}, MoreExecutors.directExecutor());
|
||||
futureArrayList.add(submit);
|
||||
}
|
||||
|
||||
while (!futureArrayList.isEmpty()) {
|
||||
Iterator<ListenableFuture<List<Page>>> iterator = futureArrayList.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
ListenableFuture<List<Page>> next = iterator.next();
|
||||
if (next.isDone()) {
|
||||
if (futureArrayList.size()%10==0) {
|
||||
System.out.println("thread i finsished: " + futureArrayList.size());
|
||||
}
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
assertNotEquals(0, pagesList.size());
|
||||
for (int i = 0; i < pagesList.size(); i++) {
|
||||
assertPagesEqualIgnoreOrder(driverContext, pagesList.get(i), expected, false, Optional.empty());
|
||||
}
|
||||
}
|
||||
|
||||
private DriverContext createDriverContext()
|
||||
{
|
||||
return createDriverContext(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
private DriverContext createDriverContext(long memoryLimit)
|
||||
{
|
||||
return TestingTaskContext.builder(executor, scheduledExecutor, TEST_SESSION)
|
||||
.setMemoryPoolSize(succinctBytes(memoryLimit))
|
||||
.build()
|
||||
.addPipelineContext(0, true, true, false)
|
||||
.addDriverContext();
|
||||
}
|
||||
|
||||
private int getHashCapacity(Operator operator)
|
||||
{
|
||||
assertTrue(operator instanceof HashAggregationOperator);
|
||||
HashAggregationBuilder aggregationBuilder = ((HashAggregationOperator) operator).getAggregationBuilder();
|
||||
if (aggregationBuilder == null) {
|
||||
return 0;
|
||||
}
|
||||
assertTrue(aggregationBuilder instanceof InMemoryHashAggregationBuilder);
|
||||
return ((InMemoryHashAggregationBuilder) aggregationBuilder).getCapacity();
|
||||
}
|
||||
|
||||
private static class FailingSpillerFactory
|
||||
implements SpillerFactory
|
||||
{
|
||||
@Override
|
||||
public Spiller create(List<Type> types, SpillContext spillContext, AggregatedMemoryContext memoryContext)
|
||||
{
|
||||
return new Spiller()
|
||||
{
|
||||
@Override
|
||||
public ListenableFuture<?> spill(Iterator<Page> pageIterator)
|
||||
{
|
||||
return immediateFailedFuture(new IOException("Failed to spill"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Iterator<Page>> getSpills()
|
||||
{
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -108,17 +108,9 @@ public class TestHashAggregationOperator
|
|||
|
||||
private ExecutorService executor;
|
||||
private ScheduledExecutorService scheduledExecutor;
|
||||
private JoinCompiler joinCompiler = new JoinCompiler(createTestMetadataManager());
|
||||
private final JoinCompiler joinCompiler = new JoinCompiler(createTestMetadataManager());
|
||||
private DummySpillerFactory spillerFactory;
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp()
|
||||
{
|
||||
executor = newCachedThreadPool(daemonThreadsNamed("test-executor-%s"));
|
||||
scheduledExecutor = newScheduledThreadPool(2, daemonThreadsNamed("test-scheduledExecutor-%s"));
|
||||
spillerFactory = new DummySpillerFactory();
|
||||
}
|
||||
|
||||
@DataProvider(name = "hashEnabled")
|
||||
public static Object[][] hashEnabled()
|
||||
{
|
||||
|
|
@ -140,6 +132,21 @@ public class TestHashAggregationOperator
|
|||
{false, true, false, 8, Integer.MAX_VALUE}};
|
||||
}
|
||||
|
||||
@DataProvider(name = "hashEnabledAndMemoryLimitForMergeValues1")
|
||||
public static Object[][] hashEnabledAndMemoryLimitForMergeValuesProvider1()
|
||||
{
|
||||
return new Object[][] {
|
||||
{true, true, true, 8, Integer.MAX_VALUE}};
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp()
|
||||
{
|
||||
executor = newCachedThreadPool(daemonThreadsNamed("test-executor-%s"));
|
||||
scheduledExecutor = newScheduledThreadPool(2, daemonThreadsNamed("test-scheduledExecutor-%s"));
|
||||
spillerFactory = new DummySpillerFactory();
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] dataType()
|
||||
{
|
||||
|
|
@ -158,7 +165,7 @@ public class TestHashAggregationOperator
|
|||
public void testHashAggregation(boolean hashEnabled, boolean spillEnabled, boolean revokeMemoryWhenAddingPages, long memoryLimitForMerge, long memoryLimitForMergeWithMemory)
|
||||
{
|
||||
// make operator produce multiple pages during finish phase
|
||||
int numberOfRows = 40_000;
|
||||
int numberOfRows = 10;
|
||||
Metadata metadata = createTestMetadataManager();
|
||||
InternalAggregationFunction countVarcharColumn = metadata.getAggregateFunctionImplementation(
|
||||
new Signature("count", AGGREGATE, parseTypeSignature(StandardTypes.BIGINT), parseTypeSignature(StandardTypes.VARCHAR)));
|
||||
|
|
@ -170,8 +177,8 @@ public class TestHashAggregationOperator
|
|||
RowPagesBuilder rowPagesBuilder = rowPagesBuilder(hashEnabled, hashChannels, VARCHAR, VARCHAR, VARCHAR, BIGINT, BOOLEAN);
|
||||
List<Page> input = rowPagesBuilder
|
||||
.addSequencePage(numberOfRows, 100, 0, 100_000, 0, 500)
|
||||
.addSequencePage(numberOfRows, 100, 0, 200_000, 0, 500)
|
||||
.addSequencePage(numberOfRows, 100, 0, 300_000, 0, 500)
|
||||
// .addSequencePage(numberOfRows, 100, 0, 200_000, 0, 500)
|
||||
// .addSequencePage(numberOfRows, 100, 0, 300_000, 0, 500)
|
||||
.build();
|
||||
|
||||
HashAggregationOperatorFactory operatorFactory = new HashAggregationOperatorFactory(
|
||||
|
|
@ -190,7 +197,7 @@ public class TestHashAggregationOperator
|
|||
countBooleanColumn.bind(ImmutableList.of(4), Optional.empty())),
|
||||
rowPagesBuilder.getHashChannel(),
|
||||
Optional.empty(),
|
||||
100_000,
|
||||
2,
|
||||
Optional.of(new DataSize(16, MEGABYTE)),
|
||||
spillEnabled,
|
||||
succinctBytes(memoryLimitForMerge),
|
||||
|
|
@ -208,12 +215,64 @@ public class TestHashAggregationOperator
|
|||
MaterializedResult expected = expectedBuilder.build();
|
||||
|
||||
List<Page> pages = toPages(operatorFactory, driverContext, input, revokeMemoryWhenAddingPages);
|
||||
assertGreaterThan(pages.size(), 1, "Expected more than one output page");
|
||||
// assertGreaterThan(pages.size(), 1, "Expected more than one output page");
|
||||
assertPagesEqualIgnoreOrder(driverContext, pages, expected, hashEnabled, Optional.of(hashChannels.size()));
|
||||
|
||||
assertTrue(spillEnabled == (spillerFactory.getSpillsCount() > 0), format("Spill state mismatch. Expected spill: %s, spill count: %s", spillEnabled, spillerFactory.getSpillsCount()));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "hashEnabledAndMemoryLimitForMergeValues1")
|
||||
public void testHashAggregation1(boolean hashEnabled, boolean spillEnabled, boolean revokeMemoryWhenAddingPages, long memoryLimitForMerge, long memoryLimitForMergeWithMemory)
|
||||
{
|
||||
// make operator produce multiple pages during finish phase
|
||||
int numberOfRows = 100000000;
|
||||
Metadata metadata = createTestMetadataManager();
|
||||
List<Integer> hashChannels = Ints.asList(0);
|
||||
RowPagesBuilder rowPagesBuilder = rowPagesBuilder(hashEnabled, hashChannels, VARCHAR, BIGINT);
|
||||
List<Page> input = rowPagesBuilder
|
||||
.addSequencePage(numberOfRows, 0, 0)
|
||||
// .addSequencePage(numberOfRows, 0)
|
||||
// .addSequencePage(numberOfRows, 0)
|
||||
.build();
|
||||
DriverContext driverContext = createDriverContext(memoryLimitForMerge);
|
||||
MaterializedResult.Builder expectedBuilder = resultBuilder(driverContext.getSession(), VARCHAR, BIGINT);
|
||||
|
||||
for (int i = 0; i < numberOfRows; ++i) {
|
||||
expectedBuilder.row(Integer.toString(i), (long) i);
|
||||
}
|
||||
MaterializedResult expected = expectedBuilder.build();
|
||||
long start = System.currentTimeMillis();
|
||||
HashAggregationOperatorFactory operatorFactory = new HashAggregationOperatorFactory(
|
||||
0,
|
||||
new PlanNodeId("test"),
|
||||
ImmutableList.of(VARCHAR),
|
||||
hashChannels,
|
||||
ImmutableList.of(),
|
||||
Step.SINGLE,
|
||||
false,
|
||||
ImmutableList.of(
|
||||
LONG_SUM.bind(ImmutableList.of(1), Optional.empty())
|
||||
),
|
||||
rowPagesBuilder.getHashChannel(),
|
||||
Optional.empty(),
|
||||
1,
|
||||
Optional.of(new DataSize(16, MEGABYTE)),
|
||||
spillEnabled,
|
||||
succinctBytes(memoryLimitForMerge),
|
||||
succinctBytes(memoryLimitForMergeWithMemory),
|
||||
spillerFactory,
|
||||
joinCompiler,
|
||||
false);
|
||||
|
||||
List<Page> pages = toPages(operatorFactory, driverContext, input, revokeMemoryWhenAddingPages);
|
||||
long end = System.currentTimeMillis() - start;
|
||||
System.out.println("presto takes: " + end + " ms");
|
||||
// assertGreaterThan(pages.size(), 1, "Expected more than one output page");
|
||||
assertPagesEqualIgnoreOrder(driverContext, pages, expected, hashEnabled, Optional.of(hashChannels.size()));
|
||||
|
||||
// assertTrue(spillEnabled == (spillerFactory.getSpillsCount() > 0), format("Spill state mismatch. Expected spill: %s, spill count: %s", spillEnabled, spillerFactory.getSpillsCount()));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "hashEnabledAndMemoryLimitForMergeValues")
|
||||
public void testHashAggregationWithGlobals(boolean hashEnabled, boolean spillEnabled, boolean revokeMemoryWhenAddingPages, long memoryLimitForMerge, long memoryLimitForMergeWithMemory)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -188,6 +188,18 @@
|
|||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.hetu.core</groupId>
|
||||
<artifactId>omni-cache</artifactId>
|
||||
<version>1.2.0-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
|||
|
|
@ -365,7 +365,6 @@ public class OrcWriteValidation
|
|||
requireNonNull(name, "name is null");
|
||||
requireNonNull(actualColumnStatistics, "actualColumnStatistics is null");
|
||||
requireNonNull(expectedColumnStatistics, "expectedColumnStatistics is null");
|
||||
|
||||
if (actualColumnStatistics.getNumberOfValues() != expectedColumnStatistics.getNumberOfValues()) {
|
||||
throw new OrcCorruptionException(orcDataSourceId, "Write validation failed: unexpected number of values in %s statistics", name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,10 +24,11 @@ import io.prestosql.orc.stream.DoubleInputStream;
|
|||
import io.prestosql.orc.stream.InputStreamSource;
|
||||
import io.prestosql.orc.stream.InputStreamSources;
|
||||
import io.prestosql.spi.block.Block;
|
||||
import io.prestosql.spi.block.LongArrayBlock;
|
||||
import io.prestosql.spi.block.DoubleArrayBlock;
|
||||
import io.prestosql.spi.block.RunLengthEncodedBlock;
|
||||
import io.prestosql.spi.type.DoubleType;
|
||||
import io.prestosql.spi.type.Type;
|
||||
import nova.hetu.omnicache.vector.DoubleVec;
|
||||
import org.openjdk.jol.info.ClassLayout;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
|
@ -42,14 +43,14 @@ import static io.airlift.slice.SizeOf.sizeOf;
|
|||
import static io.prestosql.orc.metadata.Stream.StreamKind.DATA;
|
||||
import static io.prestosql.orc.metadata.Stream.StreamKind.PRESENT;
|
||||
import static io.prestosql.orc.reader.ReaderUtils.minNonNullValueSize;
|
||||
import static io.prestosql.orc.reader.ReaderUtils.unpackLongNulls;
|
||||
import static io.prestosql.orc.reader.ReaderUtils.unpackDoubleNulls;
|
||||
import static io.prestosql.orc.reader.ReaderUtils.verifyStreamType;
|
||||
import static io.prestosql.orc.stream.MissingInputStreamSource.missingStreamSource;
|
||||
import static io.prestosql.spi.type.DoubleType.DOUBLE;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public class DoubleColumnReader
|
||||
implements ColumnReader<Long>
|
||||
implements ColumnReader<Double>
|
||||
{
|
||||
private static final int INSTANCE_SIZE = ClassLayout.parseClass(DoubleColumnReader.class).instanceSize();
|
||||
|
||||
|
|
@ -69,7 +70,7 @@ public class DoubleColumnReader
|
|||
|
||||
private boolean rowGroupOpen;
|
||||
|
||||
private long[] nonNullValueTemp = new long[0];
|
||||
private double[] nonNullValueTemp = new double[0];
|
||||
|
||||
private final LocalMemoryContext systemMemoryContext;
|
||||
|
||||
|
|
@ -147,9 +148,9 @@ public class DoubleColumnReader
|
|||
throws IOException
|
||||
{
|
||||
verify(dataStream != null);
|
||||
long[] values = new long[nextBatchSize];
|
||||
dataStream.next(values, nextBatchSize);
|
||||
return new LongArrayBlock(nextBatchSize, Optional.empty(), values);
|
||||
DoubleVec doubleVec = new DoubleVec(nextBatchSize);
|
||||
dataStream.next(doubleVec, nextBatchSize);
|
||||
return new DoubleArrayBlock(nextBatchSize, Optional.empty(), doubleVec);
|
||||
}
|
||||
|
||||
private Block readNullBlock(boolean[] isNull, int nonNullCount)
|
||||
|
|
@ -158,15 +159,15 @@ public class DoubleColumnReader
|
|||
verify(dataStream != null);
|
||||
int minNonNullValueSize = minNonNullValueSize(nonNullCount);
|
||||
if (nonNullValueTemp.length < minNonNullValueSize) {
|
||||
nonNullValueTemp = new long[minNonNullValueSize];
|
||||
nonNullValueTemp = new double[minNonNullValueSize];
|
||||
systemMemoryContext.setBytes(sizeOf(nonNullValueTemp));
|
||||
}
|
||||
|
||||
dataStream.next(nonNullValueTemp, nonNullCount);
|
||||
|
||||
long[] result = unpackLongNulls(nonNullValueTemp, isNull);
|
||||
DoubleVec result = unpackDoubleNulls(nonNullValueTemp, isNull);
|
||||
|
||||
return new LongArrayBlock(isNull.length, Optional.of(isNull), result);
|
||||
return new DoubleArrayBlock(isNull.length, Optional.of(isNull), result);
|
||||
}
|
||||
|
||||
private void openRowGroup()
|
||||
|
|
@ -230,12 +231,12 @@ public class DoubleColumnReader
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean filterTest(TupleDomainFilter filter, Long value)
|
||||
public boolean filterTest(TupleDomainFilter filter, Double value)
|
||||
{
|
||||
if (value == null) {
|
||||
return filter.testNull();
|
||||
}
|
||||
|
||||
return filter.testDouble(Double.longBitsToDouble(value));
|
||||
return filter.testDouble(value);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import io.prestosql.spi.block.IntArrayBlock;
|
|||
import io.prestosql.spi.block.RunLengthEncodedBlock;
|
||||
import io.prestosql.spi.type.RealType;
|
||||
import io.prestosql.spi.type.Type;
|
||||
import nova.hetu.omnicache.vector.IntVec;
|
||||
import org.openjdk.jol.info.ClassLayout;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
|
@ -146,9 +147,9 @@ public class FloatColumnReader
|
|||
throws IOException
|
||||
{
|
||||
verify(dataStream != null);
|
||||
int[] values = new int[nextBatchSize];
|
||||
dataStream.next(values, nextBatchSize);
|
||||
return new IntArrayBlock(nextBatchSize, Optional.empty(), values);
|
||||
IntVec intVec = new IntVec(nextBatchSize);
|
||||
dataStream.next(intVec, nextBatchSize);
|
||||
return new IntArrayBlock(nextBatchSize, Optional.empty(), intVec);
|
||||
}
|
||||
|
||||
private Block readNullBlock(boolean[] isNull, int nonNullCount)
|
||||
|
|
@ -163,7 +164,7 @@ public class FloatColumnReader
|
|||
|
||||
dataStream.next(nonNullValueTemp, nonNullCount);
|
||||
|
||||
int[] result = ReaderUtils.unpackIntNulls(nonNullValueTemp, isNull);
|
||||
IntVec result = ReaderUtils.unpackIntNulls(nonNullValueTemp, isNull);
|
||||
|
||||
return new IntArrayBlock(isNull.length, Optional.of(isNull), result);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import io.prestosql.spi.block.IntArrayBlock;
|
|||
import io.prestosql.spi.block.RunLengthEncodedBlock;
|
||||
import io.prestosql.spi.type.IntegerType;
|
||||
import io.prestosql.spi.type.Type;
|
||||
import nova.hetu.omnicache.vector.IntVec;
|
||||
import org.openjdk.jol.info.ClassLayout;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
@ -41,6 +42,7 @@ public class IntegerColumnReader
|
|||
|
||||
/**
|
||||
* FIXME: KEN: why do we need to pass in type? isn't it implied already?
|
||||
*
|
||||
* @param column
|
||||
* @param systemMemoryContext
|
||||
* @throws OrcCorruptionException
|
||||
|
|
@ -108,9 +110,9 @@ public class IntegerColumnReader
|
|||
throws IOException
|
||||
{
|
||||
verify(dataStream != null);
|
||||
int[] values = new int[nextBatchSize];
|
||||
dataStream.next(values, nextBatchSize);
|
||||
return new IntArrayBlock(nextBatchSize, Optional.empty(), values);
|
||||
IntVec intVec = new IntVec(nextBatchSize);
|
||||
dataStream.next(intVec, nextBatchSize);
|
||||
return new IntArrayBlock(nextBatchSize, Optional.empty(), intVec);
|
||||
}
|
||||
|
||||
protected Block readNullBlock(boolean[] isNull, int nonNullCount)
|
||||
|
|
@ -131,7 +133,7 @@ public class IntegerColumnReader
|
|||
|
||||
dataStream.next(intNonNullValueTemp, nonNullCount);
|
||||
|
||||
int[] result = unpackIntNulls(intNonNullValueTemp, isNull);
|
||||
IntVec result = unpackIntNulls(intNonNullValueTemp, isNull);
|
||||
|
||||
return new IntArrayBlock(nextBatchSize, Optional.of(isNull), result);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import io.prestosql.spi.block.LongArrayBlock;
|
|||
import io.prestosql.spi.block.RunLengthEncodedBlock;
|
||||
import io.prestosql.spi.type.BigintType;
|
||||
import io.prestosql.spi.type.Type;
|
||||
import nova.hetu.omnicache.vector.LongVec;
|
||||
import org.openjdk.jol.info.ClassLayout;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
@ -30,7 +31,7 @@ import java.util.Optional;
|
|||
import static com.google.common.base.Verify.verify;
|
||||
import static io.airlift.slice.SizeOf.sizeOf;
|
||||
import static io.prestosql.orc.reader.ReaderUtils.minNonNullValueSize;
|
||||
import static io.prestosql.orc.reader.ReaderUtils.unpackLongNulls;
|
||||
import static io.prestosql.orc.reader.ReaderUtils.unpackLongNullsVec;
|
||||
|
||||
public class LongColumnReader
|
||||
extends AbstractNumericColumnReader<Long>
|
||||
|
|
@ -107,9 +108,10 @@ public class LongColumnReader
|
|||
throws IOException
|
||||
{
|
||||
verify(dataStream != null);
|
||||
long[] values = new long[nextBatchSize];
|
||||
dataStream.next(values, nextBatchSize);
|
||||
return new LongArrayBlock(nextBatchSize, Optional.empty(), values);
|
||||
// long[] values = new long[nextBatchSize];
|
||||
LongVec longVec = new LongVec(nextBatchSize);
|
||||
dataStream.next(longVec, nextBatchSize);
|
||||
return new LongArrayBlock(nextBatchSize, Optional.empty(), longVec);
|
||||
}
|
||||
|
||||
private Block readNullBlock(boolean[] isNull, int nonNullCount)
|
||||
|
|
@ -130,7 +132,7 @@ public class LongColumnReader
|
|||
|
||||
dataStream.next(longNonNullValueTemp, nonNullCount);
|
||||
|
||||
long[] result = unpackLongNulls(longNonNullValueTemp, isNull);
|
||||
LongVec result = unpackLongNullsVec(longNonNullValueTemp, isNull);
|
||||
|
||||
return new LongArrayBlock(nextBatchSize, Optional.of(isNull), result);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ package io.prestosql.orc.reader;
|
|||
import io.prestosql.orc.OrcColumn;
|
||||
import io.prestosql.orc.OrcCorruptionException;
|
||||
import io.prestosql.spi.type.Type;
|
||||
import nova.hetu.omnicache.vector.DoubleVec;
|
||||
import nova.hetu.omnicache.vector.IntVec;
|
||||
import nova.hetu.omnicache.vector.LongVec;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
|
|
@ -73,13 +76,13 @@ final class ReaderUtils
|
|||
return result;
|
||||
}
|
||||
|
||||
public static int[] unpackIntNulls(int[] values, boolean[] isNull)
|
||||
public static IntVec unpackIntNulls(int[] values, boolean[] isNull)
|
||||
{
|
||||
int[] result = new int[isNull.length];
|
||||
IntVec result = new IntVec(isNull.length);
|
||||
|
||||
int position = 0;
|
||||
for (int i = 0; i < isNull.length; i++) {
|
||||
result[i] = values[position];
|
||||
result.set(i, values[position]);
|
||||
if (!isNull[i]) {
|
||||
position++;
|
||||
}
|
||||
|
|
@ -101,6 +104,34 @@ final class ReaderUtils
|
|||
return result;
|
||||
}
|
||||
|
||||
public static LongVec unpackLongNullsVec(long[] values, boolean[] isNull)
|
||||
{
|
||||
LongVec result = new LongVec(isNull.length);
|
||||
|
||||
int position = 0;
|
||||
for (int i = 0; i < isNull.length; i++) {
|
||||
result.set(i, values[position]);
|
||||
if (!isNull[i]) {
|
||||
position++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static DoubleVec unpackDoubleNulls(double[] values, boolean[] isNull)
|
||||
{
|
||||
DoubleVec result = new DoubleVec(isNull.length);
|
||||
|
||||
int position = 0;
|
||||
for (int i = 0; i < isNull.length; i++) {
|
||||
result.set(i, values[position]);
|
||||
if (!isNull[i]) {
|
||||
position++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static long[] unpackInt128Nulls(long[] values, boolean[] isNull)
|
||||
{
|
||||
long[] result = new long[isNull.length * 2];
|
||||
|
|
|
|||
|
|
@ -297,4 +297,4 @@ public class SliceDirectColumnReader
|
|||
{
|
||||
return INSTANCE_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ package io.prestosql.orc.stream;
|
|||
import io.airlift.slice.Slice;
|
||||
import io.airlift.slice.Slices;
|
||||
import io.prestosql.orc.checkpoint.DoubleStreamCheckpoint;
|
||||
import nova.hetu.omnicache.vector.DoubleVec;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
|
@ -62,9 +63,19 @@ public class DoubleInputStream
|
|||
return slice.getDouble(0);
|
||||
}
|
||||
|
||||
public void next(long[] values, int items)
|
||||
public void next(double[] values, int items)
|
||||
throws IOException
|
||||
{
|
||||
input.readFully(Slices.wrappedLongArray(values), 0, items * SIZE_OF_DOUBLE);
|
||||
input.readFully(Slices.wrappedDoubleArray(values), 0, items * SIZE_OF_DOUBLE);
|
||||
}
|
||||
|
||||
public void next(DoubleVec values, int items)
|
||||
throws IOException
|
||||
{
|
||||
double[] buffer = new double[values.size()];
|
||||
input.readFully(Slices.wrappedDoubleArray(buffer), 0, items * SIZE_OF_DOUBLE);
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
values.set(i, buffer[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ package io.prestosql.orc.stream;
|
|||
import io.airlift.slice.Slice;
|
||||
import io.airlift.slice.Slices;
|
||||
import io.prestosql.orc.checkpoint.FloatStreamCheckpoint;
|
||||
import nova.hetu.omnicache.vector.IntVec;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
|
@ -67,4 +68,14 @@ public class FloatInputStream
|
|||
{
|
||||
input.readFully(Slices.wrappedIntArray(values), 0, items * SIZE_OF_FLOAT);
|
||||
}
|
||||
|
||||
public void next(IntVec values, int items)
|
||||
throws IOException
|
||||
{
|
||||
int[] buffer = new int[values.size()];
|
||||
input.readFully(Slices.wrappedIntArray(buffer), 0, items * SIZE_OF_FLOAT);
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
values.set(i, buffer[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
package io.prestosql.orc.stream;
|
||||
|
||||
import io.prestosql.orc.checkpoint.LongStreamCheckpoint;
|
||||
import nova.hetu.omnicache.vector.IntVec;
|
||||
import nova.hetu.omnicache.vector.LongVec;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
|
@ -26,6 +28,12 @@ public interface LongInputStream
|
|||
long next()
|
||||
throws IOException;
|
||||
|
||||
void next(LongVec longVec, int items)
|
||||
throws IOException;
|
||||
|
||||
void next(IntVec longVec, int items)
|
||||
throws IOException;
|
||||
|
||||
void next(long[] values, int items)
|
||||
throws IOException;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ package io.prestosql.orc.stream;
|
|||
import io.prestosql.orc.OrcCorruptionException;
|
||||
import io.prestosql.orc.checkpoint.LongStreamCheckpoint;
|
||||
import io.prestosql.orc.checkpoint.LongStreamV1Checkpoint;
|
||||
import nova.hetu.omnicache.vector.IntVec;
|
||||
import nova.hetu.omnicache.vector.LongVec;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
|
@ -122,6 +124,35 @@ public class LongInputStreamV1
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void next(LongVec values, int items)
|
||||
throws IOException
|
||||
{
|
||||
int offset = 0;
|
||||
while (items > 0) {
|
||||
if (used == numLiterals) {
|
||||
numLiterals = 0;
|
||||
used = 0;
|
||||
readValues();
|
||||
}
|
||||
|
||||
int chunkSize = min(numLiterals - used, items);
|
||||
if (repeat) {
|
||||
for (int i = 0; i < chunkSize; i++) {
|
||||
values.set(offset + i, literals[0] + ((used + i) * delta));
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < chunkSize; i++) {
|
||||
values.set(offset + i, literals[used + i]);
|
||||
}
|
||||
}
|
||||
used += chunkSize;
|
||||
offset += chunkSize;
|
||||
items -= chunkSize;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void next(int[] values, int items)
|
||||
throws IOException
|
||||
|
|
@ -161,6 +192,45 @@ public class LongInputStreamV1
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void next(IntVec values, int items)
|
||||
throws IOException
|
||||
{
|
||||
int offset = 0;
|
||||
while (items > 0) {
|
||||
if (used == numLiterals) {
|
||||
numLiterals = 0;
|
||||
used = 0;
|
||||
readValues();
|
||||
}
|
||||
|
||||
int chunkSize = min(numLiterals - used, items);
|
||||
if (repeat) {
|
||||
for (int i = 0; i < chunkSize; i++) {
|
||||
long literal = literals[0] + ((used + i) * delta);
|
||||
int value = (int) literal;
|
||||
if (literal != value) {
|
||||
throw new OrcCorruptionException(input.getOrcDataSourceId(), "Decoded value out of range for a 32bit number");
|
||||
}
|
||||
values.set(offset + i, value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < chunkSize; i++) {
|
||||
long literal = literals[used + i];
|
||||
int value = (int) literal;
|
||||
if (literal != value) {
|
||||
throw new OrcCorruptionException(input.getOrcDataSourceId(), "Decoded value out of range for a 32bit number");
|
||||
}
|
||||
values.set(offset + i, value);
|
||||
}
|
||||
}
|
||||
used += chunkSize;
|
||||
offset += chunkSize;
|
||||
items -= chunkSize;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void next(short[] values, int items)
|
||||
throws IOException
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ package io.prestosql.orc.stream;
|
|||
import io.prestosql.orc.OrcCorruptionException;
|
||||
import io.prestosql.orc.checkpoint.LongStreamCheckpoint;
|
||||
import io.prestosql.orc.checkpoint.LongStreamV2Checkpoint;
|
||||
import nova.hetu.omnicache.vector.IntVec;
|
||||
import nova.hetu.omnicache.vector.LongVec;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
|
@ -334,6 +336,29 @@ public class LongInputStreamV2
|
|||
return literals[used++];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void next(LongVec longVec, int items)
|
||||
throws IOException
|
||||
{
|
||||
int offset = 0;
|
||||
while (items > 0) {
|
||||
if (used == numLiterals) {
|
||||
numLiterals = 0;
|
||||
used = 0;
|
||||
readValues();
|
||||
}
|
||||
|
||||
int chunkSize = min(numLiterals - used, items);
|
||||
for (int i = 0; i < chunkSize; i++) {
|
||||
longVec.set(offset + i, literals[used + i]);
|
||||
}
|
||||
// System.arraycopy(literals, used, values, offset, chunkSize);
|
||||
used += chunkSize;
|
||||
offset += chunkSize;
|
||||
items -= chunkSize;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void next(long[] values, int items)
|
||||
throws IOException
|
||||
|
|
@ -354,6 +379,33 @@ public class LongInputStreamV2
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void next(IntVec values, int items)
|
||||
throws IOException
|
||||
{
|
||||
int offset = 0;
|
||||
while (items > 0) {
|
||||
if (used == numLiterals) {
|
||||
numLiterals = 0;
|
||||
used = 0;
|
||||
readValues();
|
||||
}
|
||||
|
||||
int chunkSize = min(numLiterals - used, items);
|
||||
for (int i = 0; i < chunkSize; i++) {
|
||||
long literal = literals[used + i];
|
||||
int value = (int) literal;
|
||||
if (literal != value) {
|
||||
throw new OrcCorruptionException(input.getOrcDataSourceId(), "Decoded value out of range for a 32bit number");
|
||||
}
|
||||
values.set(offset + i, value);
|
||||
}
|
||||
used += chunkSize;
|
||||
offset += chunkSize;
|
||||
items -= chunkSize;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void next(int[] values, int items)
|
||||
throws IOException
|
||||
|
|
|
|||
|
|
@ -1094,7 +1094,7 @@ public class BenchmarkColumnReaders
|
|||
{
|
||||
Options options = new OptionsBuilder()
|
||||
.verbosity(VerboseMode.NORMAL)
|
||||
.include(".*" + BenchmarkColumnReaders.class.getSimpleName() + ".*")
|
||||
.include(".*" + BenchmarkColumnReaders.class.getSimpleName() + ".readSliceDirectNoNull")
|
||||
.build();
|
||||
|
||||
new Runner(options).run();
|
||||
|
|
|
|||
|
|
@ -120,5 +120,16 @@
|
|||
<artifactId>log</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.hetu.core</groupId>
|
||||
<artifactId>omni-cache</artifactId>
|
||||
<version>1.2.0-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -63,6 +63,13 @@ public abstract class AbstractSingleRowBlock<T>
|
|||
return getRawFieldBlock(position).getInt(rowIndex, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(int position, int offset)
|
||||
{
|
||||
checkFieldIndex(position);
|
||||
return getRawFieldBlock(position).getDouble(rowIndex, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(int position, int offset)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ package io.prestosql.spi.block;
|
|||
|
||||
import io.airlift.slice.Slice;
|
||||
import io.prestosql.spi.util.BloomFilter;
|
||||
import nova.hetu.omnicache.vector.Vec;
|
||||
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
|
@ -25,6 +26,16 @@ import static io.prestosql.spi.block.DictionaryId.randomDictionaryId;
|
|||
|
||||
public interface Block<T>
|
||||
{
|
||||
default Vec getValues()
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
default Object setValues()
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the length of the value at the {@code position}.
|
||||
* This method must be implemented if @{code getSlice} is implemented.
|
||||
|
|
@ -58,6 +69,14 @@ public interface Block<T>
|
|||
throw new UnsupportedOperationException(getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a little endian double at {@code offset} in the value at {@code position}.
|
||||
*/
|
||||
default double getDouble(int position, int offset)
|
||||
{
|
||||
throw new UnsupportedOperationException(getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a little endian long at {@code offset} in the value at {@code position}.
|
||||
* <p>
|
||||
|
|
|
|||
|
|
@ -42,6 +42,14 @@ public interface BlockBuilder<T>
|
|||
throw new UnsupportedOperationException(getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a double to the current entry;
|
||||
*/
|
||||
default BlockBuilder writeDouble(double value)
|
||||
{
|
||||
throw new UnsupportedOperationException(getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a long to the current entry;
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,284 @@
|
|||
/*
|
||||
* Copyright (C) 2018-2020. Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* 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 io.prestosql.spi.block;
|
||||
|
||||
import nova.hetu.omnicache.vector.DoubleVec;
|
||||
import org.openjdk.jol.info.ClassLayout;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static io.airlift.slice.SizeOf.sizeOf;
|
||||
import static io.prestosql.spi.block.BlockUtil.checkArrayRange;
|
||||
import static io.prestosql.spi.block.BlockUtil.checkValidRegion;
|
||||
import static io.prestosql.spi.block.BlockUtil.compactArray;
|
||||
import static io.prestosql.spi.block.BlockUtil.countUsedPositions;
|
||||
|
||||
public class DoubleArrayBlock
|
||||
implements Block<Double>
|
||||
{
|
||||
private static final int INSTANCE_SIZE = ClassLayout.parseClass(DoubleArrayBlock.class).instanceSize();
|
||||
|
||||
private final int arrayOffset;
|
||||
private final int positionCount;
|
||||
@Nullable
|
||||
private final boolean[] valueIsNull;
|
||||
private final DoubleVec values;
|
||||
|
||||
private final long sizeInBytes;
|
||||
private final long retainedSizeInBytes;
|
||||
|
||||
public DoubleArrayBlock(int positionCount, Optional<boolean[]> valueIsNull, double[] values)
|
||||
{
|
||||
this(0, positionCount, valueIsNull.orElse(null), values);
|
||||
}
|
||||
|
||||
public DoubleArrayBlock(int positionCount, Optional<boolean[]> valueIsNull, DoubleVec values)
|
||||
{
|
||||
this(0, positionCount, valueIsNull.orElse(null), values);
|
||||
}
|
||||
|
||||
DoubleArrayBlock(int arrayOffset, int positionCount, boolean[] valueIsNull, double[] values)
|
||||
{
|
||||
if (arrayOffset < 0) {
|
||||
throw new IllegalArgumentException("arrayOffset is negative");
|
||||
}
|
||||
this.arrayOffset = arrayOffset;
|
||||
if (positionCount < 0) {
|
||||
throw new IllegalArgumentException("positionCount is negative");
|
||||
}
|
||||
this.positionCount = positionCount;
|
||||
|
||||
if (values.length - arrayOffset < positionCount) {
|
||||
throw new IllegalArgumentException("values length is less than positionCount");
|
||||
}
|
||||
this.values = new DoubleVec(values.length);
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
this.values.set(i, values[i]);
|
||||
}
|
||||
|
||||
if (valueIsNull != null && valueIsNull.length - arrayOffset < positionCount) {
|
||||
throw new IllegalArgumentException("isNull length is less than positionCount");
|
||||
}
|
||||
this.valueIsNull = valueIsNull;
|
||||
|
||||
sizeInBytes = (Double.BYTES + Byte.BYTES) * (long) positionCount;
|
||||
retainedSizeInBytes = INSTANCE_SIZE + sizeOf(valueIsNull) + sizeOf(values);
|
||||
}
|
||||
|
||||
DoubleArrayBlock(int arrayOffset, int positionCount, boolean[] valueIsNull, DoubleVec values)
|
||||
{
|
||||
if (arrayOffset < 0) {
|
||||
throw new IllegalArgumentException("arrayOffset is negative");
|
||||
}
|
||||
this.arrayOffset = arrayOffset;
|
||||
if (positionCount < 0) {
|
||||
throw new IllegalArgumentException("positionCount is negative");
|
||||
}
|
||||
this.positionCount = positionCount;
|
||||
|
||||
if (values.size() - arrayOffset < positionCount) {
|
||||
throw new IllegalArgumentException("values length is less than positionCount");
|
||||
}
|
||||
this.values = values;
|
||||
|
||||
if (valueIsNull != null && valueIsNull.length - arrayOffset < positionCount) {
|
||||
throw new IllegalArgumentException("isNull length is less than positionCount");
|
||||
}
|
||||
this.valueIsNull = valueIsNull;
|
||||
|
||||
sizeInBytes = (Double.BYTES + Byte.BYTES) * (long) positionCount;
|
||||
retainedSizeInBytes = INSTANCE_SIZE + sizeOf(valueIsNull) + values.capacity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DoubleVec getValues(){
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSizeInBytes()
|
||||
{
|
||||
return sizeInBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRegionSizeInBytes(int position, int length)
|
||||
{
|
||||
return (Double.BYTES + Byte.BYTES) * (long) length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getPositionsSizeInBytes(boolean[] positions)
|
||||
{
|
||||
return (Double.BYTES + Byte.BYTES) * (long) countUsedPositions(positions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRetainedSizeInBytes()
|
||||
{
|
||||
return retainedSizeInBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEstimatedDataSizeForStats(int position)
|
||||
{
|
||||
return isNull(position) ? 0 : Double.BYTES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void retainedBytesForEachPart(BiConsumer<Object, Long> consumer)
|
||||
{
|
||||
// TODO: try to avoid copy here
|
||||
double[] valuesArray = new double[values.size()];
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
valuesArray[i] = values.get(i);
|
||||
}
|
||||
consumer.accept(valuesArray, sizeOf(valuesArray));
|
||||
if (valueIsNull != null) {
|
||||
consumer.accept(valueIsNull, sizeOf(valueIsNull));
|
||||
}
|
||||
consumer.accept(this, (long) INSTANCE_SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPositionCount()
|
||||
{
|
||||
return positionCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(int position, int offset)
|
||||
{
|
||||
checkReadablePosition(position);
|
||||
if (offset != 0) {
|
||||
throw new IllegalArgumentException("offset must be zero");
|
||||
}
|
||||
return values.get(position + arrayOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayHaveNull()
|
||||
{
|
||||
return valueIsNull != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNull(int position)
|
||||
{
|
||||
checkReadablePosition(position);
|
||||
return valueIsNull != null && valueIsNull[position + arrayOffset];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePositionTo(int position, BlockBuilder blockBuilder)
|
||||
{
|
||||
checkReadablePosition(position);
|
||||
blockBuilder.writeDouble(values.get(position + arrayOffset));
|
||||
blockBuilder.closeEntry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getSingleValueBlock(int position)
|
||||
{
|
||||
checkReadablePosition(position);
|
||||
return new DoubleArrayBlock(
|
||||
0,
|
||||
1,
|
||||
isNull(position) ? new boolean[] {true} : null,
|
||||
new double[] {values.get(position + arrayOffset)});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block copyPositions(int[] positions, int offset, int length)
|
||||
{
|
||||
checkArrayRange(positions, offset, length);
|
||||
|
||||
boolean[] newValueIsNull = null;
|
||||
if (valueIsNull != null) {
|
||||
newValueIsNull = new boolean[length];
|
||||
}
|
||||
double[] newValues = new double[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
int position = positions[offset + i];
|
||||
checkReadablePosition(position);
|
||||
if (valueIsNull != null) {
|
||||
newValueIsNull[i] = valueIsNull[position + arrayOffset];
|
||||
}
|
||||
newValues[i] = values.get(position + arrayOffset);
|
||||
}
|
||||
return new DoubleArrayBlock(0, length, newValueIsNull, newValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block<Double> getRegion(int positionOffset, int length)
|
||||
{
|
||||
checkValidRegion(getPositionCount(), positionOffset, length);
|
||||
|
||||
return new DoubleArrayBlock(positionOffset + arrayOffset, length, valueIsNull, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block<Double> copyRegion(int positionOffset, int length)
|
||||
{
|
||||
checkValidRegion(getPositionCount(), positionOffset, length);
|
||||
positionOffset += arrayOffset;
|
||||
|
||||
DoubleVec newValues = new DoubleVec(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
newValues.set(i, this.values.get(positionOffset + i));
|
||||
}
|
||||
boolean[] newValueIsNull = valueIsNull == null ? null : compactArray(valueIsNull, positionOffset, length);
|
||||
|
||||
if (newValueIsNull == valueIsNull && newValues == values) {
|
||||
return this;
|
||||
}
|
||||
return new DoubleArrayBlock(0, length, newValueIsNull, newValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEncodingName()
|
||||
{
|
||||
return DoubleArrayBlockEncoding.NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder("DoubleArrayBlock{");
|
||||
sb.append("positionCount=").append(getPositionCount());
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void checkReadablePosition(int position)
|
||||
{
|
||||
if (position < 0 || position >= getPositionCount()) {
|
||||
throw new IllegalArgumentException("position is not valid");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double get(int position)
|
||||
{
|
||||
if (valueIsNull != null && valueIsNull[position + arrayOffset]) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return values.get(position + arrayOffset);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
* Copyright (C) 2018-2020. Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* 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 io.prestosql.spi.block;
|
||||
|
||||
import org.openjdk.jol.info.ClassLayout;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static io.airlift.slice.SizeOf.sizeOf;
|
||||
import static io.prestosql.spi.block.BlockUtil.calculateBlockResetSize;
|
||||
import static io.prestosql.spi.block.BlockUtil.checkArrayRange;
|
||||
import static io.prestosql.spi.block.BlockUtil.checkValidRegion;
|
||||
import static io.prestosql.spi.block.BlockUtil.countUsedPositions;
|
||||
import static java.lang.Math.max;
|
||||
|
||||
public class DoubleArrayBlockBuilder
|
||||
implements BlockBuilder<Double>
|
||||
{
|
||||
private static final int INSTANCE_SIZE = ClassLayout.parseClass(DoubleArrayBlockBuilder.class).instanceSize();
|
||||
private static final Block NULL_VALUE_BLOCK = new DoubleArrayBlock(0, 1, new boolean[] {true}, new double[1]);
|
||||
|
||||
@Nullable
|
||||
private BlockBuilderStatus blockBuilderStatus;
|
||||
private boolean initialized;
|
||||
private int initialEntryCount;
|
||||
|
||||
private int positionCount;
|
||||
private boolean hasNullValue;
|
||||
private boolean hasNonNullValue;
|
||||
|
||||
// it is assumed that these arrays are the same length
|
||||
private boolean[] valueIsNull = new boolean[0];
|
||||
private double[] values = new double[0];
|
||||
|
||||
private long retainedSizeInBytes;
|
||||
|
||||
public DoubleArrayBlockBuilder(@Nullable BlockBuilderStatus blockBuilderStatus, int expectedEntries)
|
||||
{
|
||||
this.blockBuilderStatus = blockBuilderStatus;
|
||||
this.initialEntryCount = max(expectedEntries, 1);
|
||||
|
||||
updateDataSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockBuilder writeDouble(double value)
|
||||
{
|
||||
if (values.length <= positionCount) {
|
||||
growCapacity();
|
||||
}
|
||||
|
||||
values[positionCount] = value;
|
||||
|
||||
hasNonNullValue = true;
|
||||
positionCount++;
|
||||
if (blockBuilderStatus != null) {
|
||||
blockBuilderStatus.addBytes(Byte.BYTES + Double.BYTES);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockBuilder closeEntry()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockBuilder appendNull()
|
||||
{
|
||||
if (values.length <= positionCount) {
|
||||
growCapacity();
|
||||
}
|
||||
|
||||
valueIsNull[positionCount] = true;
|
||||
|
||||
hasNullValue = true;
|
||||
positionCount++;
|
||||
if (blockBuilderStatus != null) {
|
||||
blockBuilderStatus.addBytes(Byte.BYTES + Double.BYTES);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block build()
|
||||
{
|
||||
if (!hasNonNullValue) {
|
||||
return new RunLengthEncodedBlock(NULL_VALUE_BLOCK, positionCount);
|
||||
}
|
||||
return new DoubleArrayBlock(0, positionCount, hasNullValue ? valueIsNull : null, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockBuilder newBlockBuilderLike(BlockBuilderStatus blockBuilderStatus)
|
||||
{
|
||||
return new DoubleArrayBlockBuilder(blockBuilderStatus, calculateBlockResetSize(positionCount));
|
||||
}
|
||||
|
||||
private void growCapacity()
|
||||
{
|
||||
int newSize;
|
||||
if (initialized) {
|
||||
newSize = BlockUtil.calculateNewArraySize(values.length);
|
||||
}
|
||||
else {
|
||||
newSize = initialEntryCount;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
valueIsNull = Arrays.copyOf(valueIsNull, newSize);
|
||||
values = Arrays.copyOf(values, newSize);
|
||||
updateDataSize();
|
||||
}
|
||||
|
||||
private void updateDataSize()
|
||||
{
|
||||
retainedSizeInBytes = INSTANCE_SIZE + sizeOf(valueIsNull) + sizeOf(values);
|
||||
if (blockBuilderStatus != null) {
|
||||
retainedSizeInBytes += BlockBuilderStatus.INSTANCE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSizeInBytes()
|
||||
{
|
||||
return (Double.BYTES + Byte.BYTES) * (long) positionCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRegionSizeInBytes(int position, int length)
|
||||
{
|
||||
return (Double.BYTES + Byte.BYTES) * (long) length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getPositionsSizeInBytes(boolean[] positions)
|
||||
{
|
||||
return (Double.BYTES + Byte.BYTES) * (long) countUsedPositions(positions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRetainedSizeInBytes()
|
||||
{
|
||||
return retainedSizeInBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEstimatedDataSizeForStats(int position)
|
||||
{
|
||||
return isNull(position) ? 0 : Double.BYTES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void retainedBytesForEachPart(BiConsumer<Object, Long> consumer)
|
||||
{
|
||||
consumer.accept(values, sizeOf(values));
|
||||
consumer.accept(valueIsNull, sizeOf(valueIsNull));
|
||||
consumer.accept(this, (long) INSTANCE_SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPositionCount()
|
||||
{
|
||||
return positionCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(int position, int offset)
|
||||
{
|
||||
checkReadablePosition(position);
|
||||
if (offset != 0) {
|
||||
throw new IllegalArgumentException("offset must be zero");
|
||||
}
|
||||
return values[position];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayHaveNull()
|
||||
{
|
||||
return hasNullValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNull(int position)
|
||||
{
|
||||
checkReadablePosition(position);
|
||||
return valueIsNull[position];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePositionTo(int position, BlockBuilder blockBuilder)
|
||||
{
|
||||
checkReadablePosition(position);
|
||||
blockBuilder.writeDouble(values[position]);
|
||||
blockBuilder.closeEntry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getSingleValueBlock(int position)
|
||||
{
|
||||
checkReadablePosition(position);
|
||||
return new DoubleArrayBlock(
|
||||
0,
|
||||
1,
|
||||
valueIsNull[position] ? new boolean[] {true} : null,
|
||||
new double[] {values[position]});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block copyPositions(int[] positions, int offset, int length)
|
||||
{
|
||||
checkArrayRange(positions, offset, length);
|
||||
|
||||
if (!hasNonNullValue) {
|
||||
return new RunLengthEncodedBlock(NULL_VALUE_BLOCK, length);
|
||||
}
|
||||
boolean[] newValueIsNull = null;
|
||||
if (hasNullValue) {
|
||||
newValueIsNull = new boolean[length];
|
||||
}
|
||||
double[] newValues = new double[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
int position = positions[offset + i];
|
||||
checkReadablePosition(position);
|
||||
if (hasNullValue) {
|
||||
newValueIsNull[i] = valueIsNull[position];
|
||||
}
|
||||
newValues[i] = values[position];
|
||||
}
|
||||
return new DoubleArrayBlock(0, length, newValueIsNull, newValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getRegion(int positionOffset, int length)
|
||||
{
|
||||
checkValidRegion(getPositionCount(), positionOffset, length);
|
||||
|
||||
if (!hasNonNullValue) {
|
||||
return new RunLengthEncodedBlock(NULL_VALUE_BLOCK, length);
|
||||
}
|
||||
return new DoubleArrayBlock(positionOffset, length, hasNullValue ? valueIsNull : null, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block copyRegion(int positionOffset, int length)
|
||||
{
|
||||
checkValidRegion(getPositionCount(), positionOffset, length);
|
||||
|
||||
if (!hasNonNullValue) {
|
||||
return new RunLengthEncodedBlock(NULL_VALUE_BLOCK, length);
|
||||
}
|
||||
boolean[] newValueIsNull = null;
|
||||
if (hasNullValue) {
|
||||
newValueIsNull = Arrays.copyOfRange(valueIsNull, positionOffset, positionOffset + length);
|
||||
}
|
||||
double[] newValues = Arrays.copyOfRange(values, positionOffset, positionOffset + length);
|
||||
return new DoubleArrayBlock(0, length, newValueIsNull, newValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEncodingName()
|
||||
{
|
||||
return DoubleArrayBlockEncoding.NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder("DoubleArrayBlockBuilder{");
|
||||
sb.append("positionCount=").append(getPositionCount());
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void checkReadablePosition(int position)
|
||||
{
|
||||
if (position < 0 || position >= getPositionCount()) {
|
||||
throw new IllegalArgumentException("position is not valid");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (C) 2018-2020. Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* 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 io.prestosql.spi.block;
|
||||
|
||||
import io.airlift.slice.SliceInput;
|
||||
import io.airlift.slice.SliceOutput;
|
||||
|
||||
import static io.prestosql.spi.block.EncoderUtil.decodeNullBits;
|
||||
import static io.prestosql.spi.block.EncoderUtil.encodeNullsAsBits;
|
||||
|
||||
public class DoubleArrayBlockEncoding
|
||||
implements BlockEncoding
|
||||
{
|
||||
public static final String NAME = "DOUBLE_ARRAY";
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBlock(BlockEncodingSerde blockEncodingSerde, SliceOutput sliceOutput, Block block)
|
||||
{
|
||||
int positionCount = block.getPositionCount();
|
||||
sliceOutput.appendInt(positionCount);
|
||||
|
||||
encodeNullsAsBits(sliceOutput, block);
|
||||
|
||||
for (int position = 0; position < positionCount; position++) {
|
||||
if (!block.isNull(position)) {
|
||||
sliceOutput.writeDouble(block.getDouble(position, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block readBlock(BlockEncodingSerde blockEncodingSerde, SliceInput sliceInput)
|
||||
{
|
||||
int positionCount = sliceInput.readInt();
|
||||
|
||||
boolean[] valueIsNull = decodeNullBits(sliceInput, positionCount).orElse(null);
|
||||
|
||||
double[] values = new double[positionCount];
|
||||
for (int position = 0; position < positionCount; position++) {
|
||||
if (valueIsNull == null || !valueIsNull[position]) {
|
||||
values[position] = sliceInput.readDouble();
|
||||
}
|
||||
}
|
||||
|
||||
return new DoubleArrayBlock(0, positionCount, valueIsNull, values);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ package io.prestosql.spi.block;
|
|||
import io.airlift.slice.Slice;
|
||||
import io.airlift.slice.Slices;
|
||||
import io.prestosql.spi.util.BloomFilter;
|
||||
import nova.hetu.omnicache.vector.LongVec;
|
||||
import org.openjdk.jol.info.ClassLayout;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
|
@ -40,7 +41,7 @@ public class Int128ArrayBlock
|
|||
private final int positionCount;
|
||||
@Nullable
|
||||
private final boolean[] valueIsNull;
|
||||
private final long[] values;
|
||||
private final LongVec values;
|
||||
|
||||
private final long sizeInBytes;
|
||||
private final long retainedSizeInBytes;
|
||||
|
|
@ -50,6 +51,11 @@ public class Int128ArrayBlock
|
|||
this(0, positionCount, valueIsNull.orElse(null), values);
|
||||
}
|
||||
|
||||
public Int128ArrayBlock(int positionCount, Optional<boolean[]> valueIsNull, LongVec values)
|
||||
{
|
||||
this(0, positionCount, valueIsNull.orElse(null), values);
|
||||
}
|
||||
|
||||
Int128ArrayBlock(int positionOffset, int positionCount, boolean[] valueIsNull, long[] values)
|
||||
{
|
||||
if (positionOffset < 0) {
|
||||
|
|
@ -64,6 +70,34 @@ public class Int128ArrayBlock
|
|||
if (values.length - (positionOffset * 2) < positionCount * 2) {
|
||||
throw new IllegalArgumentException("values length is less than positionCount");
|
||||
}
|
||||
this.values = new LongVec(values.length);
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
this.values.set(i, values[i]);
|
||||
}
|
||||
|
||||
if (valueIsNull != null && valueIsNull.length - positionOffset < positionCount) {
|
||||
throw new IllegalArgumentException("isNull length is less than positionCount");
|
||||
}
|
||||
this.valueIsNull = valueIsNull;
|
||||
|
||||
sizeInBytes = (INT128_BYTES + Byte.BYTES) * (long) positionCount;
|
||||
retainedSizeInBytes = INSTANCE_SIZE + sizeOf(valueIsNull) + this.values.capacity();
|
||||
}
|
||||
|
||||
Int128ArrayBlock(int positionOffset, int positionCount, boolean[] valueIsNull, LongVec values)
|
||||
{
|
||||
if (positionOffset < 0) {
|
||||
throw new IllegalArgumentException("positionOffset is negative");
|
||||
}
|
||||
this.positionOffset = positionOffset;
|
||||
if (positionCount < 0) {
|
||||
throw new IllegalArgumentException("positionCount is negative");
|
||||
}
|
||||
this.positionCount = positionCount;
|
||||
|
||||
if (values.size() - (positionOffset * 2) < positionCount * 2) {
|
||||
throw new IllegalArgumentException("values length is less than positionCount");
|
||||
}
|
||||
this.values = values;
|
||||
|
||||
if (valueIsNull != null && valueIsNull.length - positionOffset < positionCount) {
|
||||
|
|
@ -72,7 +106,7 @@ public class Int128ArrayBlock
|
|||
this.valueIsNull = valueIsNull;
|
||||
|
||||
sizeInBytes = (INT128_BYTES + Byte.BYTES) * (long) positionCount;
|
||||
retainedSizeInBytes = INSTANCE_SIZE + sizeOf(valueIsNull) + sizeOf(values);
|
||||
retainedSizeInBytes = INSTANCE_SIZE + sizeOf(valueIsNull) + this.values.capacity();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -108,7 +142,12 @@ public class Int128ArrayBlock
|
|||
@Override
|
||||
public void retainedBytesForEachPart(BiConsumer<Object, Long> consumer)
|
||||
{
|
||||
consumer.accept(values, sizeOf(values));
|
||||
// TODO: try to avoid copy here
|
||||
long[] valuesArray = new long[values.size()];
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
valuesArray[i] = values.get(i);
|
||||
}
|
||||
consumer.accept(valuesArray, sizeOf(valuesArray));
|
||||
if (valueIsNull != null) {
|
||||
consumer.accept(valueIsNull, sizeOf(valueIsNull));
|
||||
}
|
||||
|
|
@ -126,10 +165,10 @@ public class Int128ArrayBlock
|
|||
{
|
||||
checkReadablePosition(position);
|
||||
if (offset == 0) {
|
||||
return values[(position + positionOffset) * 2];
|
||||
return values.get((position + positionOffset) * 2);
|
||||
}
|
||||
if (offset == 8) {
|
||||
return values[((position + positionOffset) * 2) + 1];
|
||||
return values.get(((position + positionOffset) * 2) + 1);
|
||||
}
|
||||
throw new IllegalArgumentException("offset must be 0 or 8");
|
||||
}
|
||||
|
|
@ -151,8 +190,8 @@ public class Int128ArrayBlock
|
|||
public void writePositionTo(int position, BlockBuilder blockBuilder)
|
||||
{
|
||||
checkReadablePosition(position);
|
||||
blockBuilder.writeLong(values[(position + positionOffset) * 2]);
|
||||
blockBuilder.writeLong(values[((position + positionOffset) * 2) + 1]);
|
||||
blockBuilder.writeLong(values.get((position + positionOffset) * 2));
|
||||
blockBuilder.writeLong(values.get(((position + positionOffset) * 2) + 1));
|
||||
blockBuilder.closeEntry();
|
||||
}
|
||||
|
||||
|
|
@ -165,8 +204,8 @@ public class Int128ArrayBlock
|
|||
1,
|
||||
isNull(position) ? new boolean[] {true} : null,
|
||||
new long[] {
|
||||
values[(position + positionOffset) * 2],
|
||||
values[((position + positionOffset) * 2) + 1]});
|
||||
values.get((position + positionOffset) * 2),
|
||||
values.get(((position + positionOffset) * 2) + 1)});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -185,8 +224,8 @@ public class Int128ArrayBlock
|
|||
if (valueIsNull != null) {
|
||||
newValueIsNull[i] = valueIsNull[position + positionOffset];
|
||||
}
|
||||
newValues[i * 2] = values[(position + positionOffset) * 2];
|
||||
newValues[(i * 2) + 1] = values[((position + positionOffset) * 2) + 1];
|
||||
newValues[i * 2] = values.get((position + positionOffset) * 2);
|
||||
newValues[(i * 2) + 1] = values.get(((position + positionOffset) * 2) + 1);
|
||||
}
|
||||
return new Int128ArrayBlock(0, length, newValueIsNull, newValues);
|
||||
}
|
||||
|
|
@ -203,10 +242,13 @@ public class Int128ArrayBlock
|
|||
public Block copyRegion(int positionOffset, int length)
|
||||
{
|
||||
checkValidRegion(getPositionCount(), positionOffset, length);
|
||||
|
||||
positionOffset += this.positionOffset;
|
||||
|
||||
LongVec newValues = new LongVec(length * 2);
|
||||
for (int i = 0; i < length * 2; i++) {
|
||||
newValues.set(i, this.values.get(positionOffset * 2 + i));
|
||||
}
|
||||
boolean[] newValueIsNull = valueIsNull == null ? null : compactArray(valueIsNull, positionOffset, length);
|
||||
long[] newValues = compactArray(values, positionOffset * 2, length * 2);
|
||||
|
||||
if (newValueIsNull == valueIsNull && newValues == values) {
|
||||
return this;
|
||||
|
|
@ -239,8 +281,8 @@ public class Int128ArrayBlock
|
|||
@Override
|
||||
public boolean[] filter(BloomFilter filter, boolean[] validPositions)
|
||||
{
|
||||
for (int i = 0; i < values.length / 2; i++) {
|
||||
Slice value = Slices.wrappedLongArray(values[i * 2], values[i * 2 + 1]);
|
||||
for (int i = 0; i < values.size() / 2; i++) {
|
||||
Slice value = Slices.wrappedLongArray(values.get(i * 2), values.get(i * 2 + 1));
|
||||
validPositions[i] = validPositions[i] && filter.test(value);
|
||||
}
|
||||
return validPositions;
|
||||
|
|
@ -258,8 +300,8 @@ public class Int128ArrayBlock
|
|||
}
|
||||
}
|
||||
else {
|
||||
val[0] = values[(positions[i] + positionOffset) * 2];
|
||||
val[1] = values[((positions[i] + positionOffset) * 2) + 1];
|
||||
val[0] = values.get((positions[i] + positionOffset) * 2);
|
||||
val[1] = values.get(((positions[i] + positionOffset) * 2) + 1);
|
||||
if (test.apply(val)) {
|
||||
matchedPositions[matchCount++] = positions[i];
|
||||
}
|
||||
|
|
@ -276,8 +318,8 @@ public class Int128ArrayBlock
|
|||
if (valueIsNull != null && valueIsNull[position + positionOffset]) {
|
||||
return null;
|
||||
}
|
||||
val[0] = values[(position + positionOffset) * 2];
|
||||
val[1] = values[((position + positionOffset) * 2) + 1];
|
||||
val[0] = values.get((position + positionOffset) * 2);
|
||||
val[1] = values.get(((position + positionOffset) * 2) + 1);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
package io.prestosql.spi.block;
|
||||
|
||||
import io.prestosql.spi.util.BloomFilter;
|
||||
import nova.hetu.omnicache.vector.IntVec;
|
||||
import org.openjdk.jol.info.ClassLayout;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
|
@ -37,7 +38,7 @@ public class IntArrayBlock
|
|||
private final int positionCount;
|
||||
@Nullable
|
||||
private final boolean[] valueIsNull;
|
||||
private final int[] values;
|
||||
private final IntVec values;
|
||||
|
||||
private final long sizeInBytes;
|
||||
private final long retainedSizeInBytes;
|
||||
|
|
@ -47,6 +48,11 @@ public class IntArrayBlock
|
|||
this(0, positionCount, valueIsNull.orElse(null), values);
|
||||
}
|
||||
|
||||
public IntArrayBlock(int positionCount, Optional<boolean[]> valueIsNull, IntVec values)
|
||||
{
|
||||
this(0, positionCount, valueIsNull.orElse(null), values);
|
||||
}
|
||||
|
||||
IntArrayBlock(int arrayOffset, int positionCount, boolean[] valueIsNull, int[] values)
|
||||
{
|
||||
if (arrayOffset < 0) {
|
||||
|
|
@ -61,7 +67,10 @@ public class IntArrayBlock
|
|||
if (values.length - arrayOffset < positionCount) {
|
||||
throw new IllegalArgumentException("values length is less than positionCount");
|
||||
}
|
||||
this.values = values;
|
||||
this.values = new IntVec(values.length);
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
this.values.set(i, values[i]);
|
||||
}
|
||||
|
||||
if (valueIsNull != null && valueIsNull.length - arrayOffset < positionCount) {
|
||||
throw new IllegalArgumentException("isNull length is less than positionCount");
|
||||
|
|
@ -72,6 +81,36 @@ public class IntArrayBlock
|
|||
retainedSizeInBytes = INSTANCE_SIZE + sizeOf(valueIsNull) + sizeOf(values);
|
||||
}
|
||||
|
||||
IntArrayBlock(int arrayOffset, int positionCount, boolean[] valueIsNull, IntVec values)
|
||||
{
|
||||
if (arrayOffset < 0) {
|
||||
throw new IllegalArgumentException("arrayOffset is negative");
|
||||
}
|
||||
this.arrayOffset = arrayOffset;
|
||||
if (positionCount < 0) {
|
||||
throw new IllegalArgumentException("positionCount is negative");
|
||||
}
|
||||
this.positionCount = positionCount;
|
||||
|
||||
if (values.size() - arrayOffset < positionCount) {
|
||||
throw new IllegalArgumentException("values length is less than positionCount");
|
||||
}
|
||||
this.values = values;
|
||||
|
||||
if (valueIsNull != null && valueIsNull.length - arrayOffset < positionCount) {
|
||||
throw new IllegalArgumentException("isNull length is less than positionCount");
|
||||
}
|
||||
this.valueIsNull = valueIsNull;
|
||||
|
||||
sizeInBytes = (Integer.BYTES + Byte.BYTES) * (long) positionCount;
|
||||
retainedSizeInBytes = INSTANCE_SIZE + sizeOf(valueIsNull) + values.capacity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntVec getValues(){
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSizeInBytes()
|
||||
{
|
||||
|
|
@ -105,7 +144,12 @@ public class IntArrayBlock
|
|||
@Override
|
||||
public void retainedBytesForEachPart(BiConsumer<Object, Long> consumer)
|
||||
{
|
||||
consumer.accept(values, sizeOf(values));
|
||||
// TODO: try to avoid copy here
|
||||
int[] valuesArray = new int[values.size()];
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
valuesArray[i] = values.get(i);
|
||||
}
|
||||
consumer.accept(valuesArray, sizeOf(valuesArray));
|
||||
if (valueIsNull != null) {
|
||||
consumer.accept(valueIsNull, sizeOf(valueIsNull));
|
||||
}
|
||||
|
|
@ -125,7 +169,7 @@ public class IntArrayBlock
|
|||
if (offset != 0) {
|
||||
throw new IllegalArgumentException("offset must be zero");
|
||||
}
|
||||
return values[position + arrayOffset];
|
||||
return values.get(position + arrayOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -151,7 +195,7 @@ public class IntArrayBlock
|
|||
public void writePositionTo(int position, BlockBuilder blockBuilder)
|
||||
{
|
||||
checkReadablePosition(position);
|
||||
blockBuilder.writeInt(values[position + arrayOffset]);
|
||||
blockBuilder.writeInt(values.get(position + arrayOffset));
|
||||
blockBuilder.closeEntry();
|
||||
}
|
||||
|
||||
|
|
@ -163,7 +207,7 @@ public class IntArrayBlock
|
|||
0,
|
||||
1,
|
||||
isNull(position) ? new boolean[] {true} : null,
|
||||
new int[] {values[position + arrayOffset]});
|
||||
new int[] {values.get(position + arrayOffset)});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -182,7 +226,7 @@ public class IntArrayBlock
|
|||
if (valueIsNull != null) {
|
||||
newValueIsNull[i] = valueIsNull[position + arrayOffset];
|
||||
}
|
||||
newValues[i] = values[position + arrayOffset];
|
||||
newValues[i] = values.get(position + arrayOffset);
|
||||
}
|
||||
return new IntArrayBlock(0, length, newValueIsNull, newValues);
|
||||
}
|
||||
|
|
@ -199,10 +243,13 @@ public class IntArrayBlock
|
|||
public Block copyRegion(int positionOffset, int length)
|
||||
{
|
||||
checkValidRegion(getPositionCount(), positionOffset, length);
|
||||
|
||||
positionOffset += arrayOffset;
|
||||
|
||||
IntVec newValues = new IntVec(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
newValues.set(i, this.values.get(positionOffset + i));
|
||||
}
|
||||
boolean[] newValueIsNull = valueIsNull == null ? null : compactArray(valueIsNull, positionOffset, length);
|
||||
int[] newValues = compactArray(values, positionOffset, length);
|
||||
|
||||
if (newValueIsNull == valueIsNull && newValues == values) {
|
||||
return this;
|
||||
|
|
@ -235,8 +282,8 @@ public class IntArrayBlock
|
|||
@Override
|
||||
public boolean[] filter(BloomFilter filter, boolean[] validPositions)
|
||||
{
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
validPositions[i] = validPositions[i] && filter.test(values[i]);
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
validPositions[i] = validPositions[i] && filter.test(values.get(i));
|
||||
}
|
||||
return validPositions;
|
||||
}
|
||||
|
|
@ -251,7 +298,7 @@ public class IntArrayBlock
|
|||
matchedPositions[matchCount++] = positions[i];
|
||||
}
|
||||
}
|
||||
else if (test.apply(values[positions[i] + arrayOffset])) {
|
||||
else if (test.apply(values.get(positions[i] + arrayOffset))) {
|
||||
matchedPositions[matchCount++] = positions[i];
|
||||
}
|
||||
}
|
||||
|
|
@ -266,6 +313,6 @@ public class IntArrayBlock
|
|||
return null;
|
||||
}
|
||||
|
||||
return values[position + arrayOffset];
|
||||
return values.get(position + arrayOffset);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
package io.prestosql.spi.block;
|
||||
|
||||
import io.prestosql.spi.util.BloomFilter;
|
||||
import nova.hetu.omnicache.vector.LongVec;
|
||||
import org.openjdk.jol.info.ClassLayout;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
|
@ -41,7 +42,7 @@ public class LongArrayBlock
|
|||
private final int positionCount;
|
||||
@Nullable
|
||||
private final boolean[] valueIsNull;
|
||||
private final long[] values; //change to use offheap --> accessible by RDMA
|
||||
private final LongVec values;
|
||||
|
||||
private final long sizeInBytes;
|
||||
private final long retainedSizeInBytes;
|
||||
|
|
@ -51,6 +52,11 @@ public class LongArrayBlock
|
|||
this(0, positionCount, valueIsNull.orElse(null), values);
|
||||
}
|
||||
|
||||
public LongArrayBlock(int positionCount, Optional<boolean[]> valueIsNull, LongVec longVec)
|
||||
{
|
||||
this(0, positionCount, valueIsNull.orElse(null), longVec);
|
||||
}
|
||||
|
||||
LongArrayBlock(int arrayOffset, int positionCount, boolean[] valueIsNull, long[] values)
|
||||
{
|
||||
if (arrayOffset < 0) {
|
||||
|
|
@ -65,7 +71,10 @@ public class LongArrayBlock
|
|||
if (values.length - arrayOffset < positionCount) {
|
||||
throw new IllegalArgumentException("values length is less than positionCount");
|
||||
}
|
||||
this.values = values;
|
||||
this.values = new LongVec(values.length);
|
||||
for (int idx = 0; idx < values.length; idx++) {
|
||||
this.values.set(idx, values[idx]);
|
||||
}
|
||||
|
||||
if (valueIsNull != null && valueIsNull.length - arrayOffset < positionCount) {
|
||||
throw new IllegalArgumentException("isNull length is less than positionCount");
|
||||
|
|
@ -76,6 +85,37 @@ public class LongArrayBlock
|
|||
retainedSizeInBytes = INSTANCE_SIZE + sizeOf(valueIsNull) + sizeOf(values);
|
||||
}
|
||||
|
||||
public LongArrayBlock(int arrayOffset, int positionCount, boolean[] valueIsNull, LongVec longVec)
|
||||
{
|
||||
if (arrayOffset < 0) {
|
||||
throw new IllegalArgumentException("arrayOffset is negative");
|
||||
}
|
||||
this.arrayOffset = arrayOffset;
|
||||
if (positionCount < 0) {
|
||||
throw new IllegalArgumentException("positionCount is negative");
|
||||
}
|
||||
this.positionCount = positionCount;
|
||||
|
||||
if (longVec.size() - arrayOffset < positionCount) {
|
||||
throw new IllegalArgumentException("values length is less than positionCount");
|
||||
}
|
||||
this.values = longVec;
|
||||
|
||||
if (valueIsNull != null && valueIsNull.length - arrayOffset < positionCount) {
|
||||
throw new IllegalArgumentException("isNull length is less than positionCount");
|
||||
}
|
||||
this.valueIsNull = valueIsNull;
|
||||
|
||||
sizeInBytes = (Long.BYTES + Byte.BYTES) * (long) positionCount;
|
||||
retainedSizeInBytes = INSTANCE_SIZE + sizeOf(valueIsNull) + values.capacity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LongVec getValues()
|
||||
{
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSizeInBytes()
|
||||
{
|
||||
|
|
@ -109,7 +149,12 @@ public class LongArrayBlock
|
|||
@Override
|
||||
public void retainedBytesForEachPart(BiConsumer<Object, Long> consumer)
|
||||
{
|
||||
consumer.accept(values, sizeOf(values));
|
||||
// TODO: try to avoid copy here
|
||||
long[] valuesArray = new long[values.size()];
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
valuesArray[i] = values.get(i);
|
||||
}
|
||||
consumer.accept(valuesArray, sizeOf(valuesArray));
|
||||
if (valueIsNull != null) {
|
||||
consumer.accept(valueIsNull, sizeOf(valueIsNull));
|
||||
}
|
||||
|
|
@ -129,7 +174,7 @@ public class LongArrayBlock
|
|||
if (offset != 0) {
|
||||
throw new IllegalArgumentException("offset must be zero");
|
||||
}
|
||||
return values[position + arrayOffset];
|
||||
return values.get(position + arrayOffset);
|
||||
}
|
||||
|
||||
public Long get(int position)
|
||||
|
|
@ -137,7 +182,7 @@ public class LongArrayBlock
|
|||
if (valueIsNull != null && valueIsNull[position + arrayOffset]) {
|
||||
return null;
|
||||
}
|
||||
return values[position + arrayOffset];
|
||||
return values.get(position + arrayOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -149,41 +194,7 @@ public class LongArrayBlock
|
|||
if (offset != 0) {
|
||||
throw new IllegalArgumentException("offset must be zero");
|
||||
}
|
||||
return toIntExact(values[position + arrayOffset]);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
// TODO: Remove when we fix intermediate types on aggregations.
|
||||
public short getShort(int position, int offset)
|
||||
{
|
||||
checkReadablePosition(position);
|
||||
if (offset != 0) {
|
||||
throw new IllegalArgumentException("offset must be zero");
|
||||
}
|
||||
|
||||
short value = (short) (values[position + arrayOffset]);
|
||||
if (value != values[position + arrayOffset]) {
|
||||
throw new ArithmeticException("short overflow");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
// TODO: Remove when we fix intermediate types on aggregations.
|
||||
public byte getByte(int position, int offset)
|
||||
{
|
||||
checkReadablePosition(position);
|
||||
if (offset != 0) {
|
||||
throw new IllegalArgumentException("offset must be zero");
|
||||
}
|
||||
|
||||
byte value = (byte) (values[position + arrayOffset]);
|
||||
if (value != values[position + arrayOffset]) {
|
||||
throw new ArithmeticException("byte overflow");
|
||||
}
|
||||
return value;
|
||||
return toIntExact(values.get(position + arrayOffset));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -203,7 +214,7 @@ public class LongArrayBlock
|
|||
public void writePositionTo(int position, BlockBuilder blockBuilder)
|
||||
{
|
||||
checkReadablePosition(position);
|
||||
blockBuilder.writeLong(values[position + arrayOffset]);
|
||||
blockBuilder.writeLong(values.get(position + arrayOffset));
|
||||
blockBuilder.closeEntry();
|
||||
}
|
||||
|
||||
|
|
@ -215,7 +226,7 @@ public class LongArrayBlock
|
|||
0,
|
||||
1,
|
||||
isNull(position) ? new boolean[] {true} : null,
|
||||
new long[] {values[position + arrayOffset]});
|
||||
new long[] {values.get(position + arrayOffset)});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -234,7 +245,7 @@ public class LongArrayBlock
|
|||
if (valueIsNull != null) {
|
||||
newValueIsNull[i] = valueIsNull[position + arrayOffset];
|
||||
}
|
||||
newValues[i] = values[position + arrayOffset];
|
||||
newValues[i] = values.get(position + arrayOffset);
|
||||
}
|
||||
return new LongArrayBlock(0, length, newValueIsNull, newValues);
|
||||
}
|
||||
|
|
@ -243,7 +254,6 @@ public class LongArrayBlock
|
|||
public Block getRegion(int positionOffset, int length)
|
||||
{
|
||||
checkValidRegion(getPositionCount(), positionOffset, length);
|
||||
|
||||
return new LongArrayBlock(positionOffset + arrayOffset, length, valueIsNull, values);
|
||||
}
|
||||
|
||||
|
|
@ -251,10 +261,13 @@ public class LongArrayBlock
|
|||
public Block copyRegion(int positionOffset, int length)
|
||||
{
|
||||
checkValidRegion(getPositionCount(), positionOffset, length);
|
||||
|
||||
positionOffset += arrayOffset;
|
||||
|
||||
LongVec newValues = new LongVec(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
newValues.set(i, this.values.get(positionOffset + i));
|
||||
}
|
||||
boolean[] newValueIsNull = valueIsNull == null ? null : compactArray(valueIsNull, positionOffset, length);
|
||||
long[] newValues = compactArray(values, positionOffset, length);
|
||||
|
||||
if (newValueIsNull == valueIsNull && newValues == values) {
|
||||
return this;
|
||||
|
|
@ -287,9 +300,10 @@ public class LongArrayBlock
|
|||
@Override
|
||||
public boolean[] filter(BloomFilter filter, boolean[] validPositions)
|
||||
{
|
||||
for (int i = arrayOffset; i < positionCount; i++) {
|
||||
validPositions[i] = validPositions[i] && filter.test(values[i]);
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
validPositions[i] = validPositions[i] && filter.test(values.get(i));
|
||||
}
|
||||
|
||||
return validPositions;
|
||||
}
|
||||
|
||||
|
|
@ -303,7 +317,7 @@ public class LongArrayBlock
|
|||
matchedPositions[matchCount++] = positions[i];
|
||||
}
|
||||
}
|
||||
else if (test.apply(values[positions[i] + arrayOffset])) {
|
||||
else if (test.apply(values.get(positions[i] + arrayOffset))) {
|
||||
matchedPositions[matchCount++] = positions[i];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,6 +121,14 @@ public class SingleRowBlockWriter<T>
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockBuilder writeDouble(double value)
|
||||
{
|
||||
checkFieldIndexToWrite();
|
||||
fieldBlockBuilders[currentFieldIndexToWrite].writeDouble(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockBuilder writeLong(long value)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import io.airlift.slice.Slice;
|
|||
import io.airlift.slice.SliceOutput;
|
||||
import io.airlift.slice.Slices;
|
||||
import io.prestosql.spi.util.BloomFilter;
|
||||
import nova.hetu.omnicache.vector.VarcharVec;
|
||||
import org.openjdk.jol.info.ClassLayout;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
|
@ -41,11 +42,13 @@ public class VariableWidthBlock
|
|||
private final int positionCount;
|
||||
private final Slice slice;
|
||||
private final int[] offsets;
|
||||
protected final VarcharVec varcharVec;
|
||||
protected final boolean isVecMode = true;
|
||||
@Nullable
|
||||
private final boolean[] valueIsNull;
|
||||
protected final boolean[] valueIsNull;
|
||||
|
||||
private final long retainedSizeInBytes;
|
||||
private final long sizeInBytes;
|
||||
protected final long retainedSizeInBytes;
|
||||
protected final long sizeInBytes;
|
||||
|
||||
public VariableWidthBlock(int positionCount, Slice slice, int[] offsets, Optional<boolean[]> valueIsNull)
|
||||
{
|
||||
|
|
@ -67,6 +70,18 @@ public class VariableWidthBlock
|
|||
throw new IllegalArgumentException("slice is null");
|
||||
}
|
||||
this.slice = slice;
|
||||
if (isVecMode) {
|
||||
byte[] data = slice.getBytes();
|
||||
this.varcharVec = new VarcharVec(data.length, offsets.length);
|
||||
this.varcharVec.setData(data);
|
||||
int[] lengths = new int [offsets.length];
|
||||
for (int i=0; i< (positionCount +1); i++) {
|
||||
if (i < offsets.length -1) {
|
||||
lengths[i] = offsets[i + 1] - offsets[i];
|
||||
}
|
||||
}
|
||||
this.varcharVec.set(offsets, lengths);
|
||||
}
|
||||
|
||||
if (offsets.length - arrayOffset < (positionCount + 1)) {
|
||||
throw new IllegalArgumentException("offsets length is less than positionCount");
|
||||
|
|
@ -80,6 +95,36 @@ public class VariableWidthBlock
|
|||
|
||||
sizeInBytes = offsets[arrayOffset + positionCount] - offsets[arrayOffset] + ((Integer.BYTES + Byte.BYTES) * (long) positionCount);
|
||||
retainedSizeInBytes = INSTANCE_SIZE + slice.getRetainedSize() + sizeOf(valueIsNull) + sizeOf(offsets);
|
||||
|
||||
}
|
||||
|
||||
public VariableWidthBlock(VarcharVec varcharVec, int[] offsets, int[] lengths, boolean[] valueIsNull)
|
||||
{
|
||||
this.arrayOffset = 0;
|
||||
this.positionCount = 0;
|
||||
if (varcharVec == null) {
|
||||
throw new IllegalArgumentException("varcharVec is null");
|
||||
}
|
||||
this.varcharVec = varcharVec;
|
||||
|
||||
for (int i=0; i < offsets.length; i++) {
|
||||
this.varcharVec.set(i, offsets[i], lengths[i]);
|
||||
}
|
||||
|
||||
this.slice = null;
|
||||
if (offsets.length - arrayOffset < (positionCount + 1)) {
|
||||
throw new IllegalArgumentException("offsets length is less than positionCount");
|
||||
}
|
||||
this.offsets = offsets;
|
||||
|
||||
if (valueIsNull != null && valueIsNull.length - arrayOffset < positionCount) {
|
||||
throw new IllegalArgumentException("valueIsNull length is less than positionCount");
|
||||
}
|
||||
this.valueIsNull = valueIsNull;
|
||||
|
||||
sizeInBytes = varcharVec.capacity();
|
||||
retainedSizeInBytes = varcharVec.capacity();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -91,6 +136,7 @@ public class VariableWidthBlock
|
|||
@Override
|
||||
public int getSliceLength(int position)
|
||||
{
|
||||
// System.out.println("GetSlice Length::" + position);
|
||||
checkReadablePosition(position);
|
||||
return getPositionOffset(position + 1) - getPositionOffset(position);
|
||||
}
|
||||
|
|
@ -128,6 +174,7 @@ public class VariableWidthBlock
|
|||
@Override
|
||||
public long getPositionsSizeInBytes(boolean[] positions)
|
||||
{
|
||||
System.out.println("Get position size in bytes:::");
|
||||
long sizeInBytes = 0;
|
||||
int usedPositionCount = 0;
|
||||
for (int i = 0; i < positions.length; ++i) {
|
||||
|
|
@ -160,7 +207,9 @@ public class VariableWidthBlock
|
|||
public Block copyPositions(int[] positions, int offset, int length)
|
||||
{
|
||||
checkArrayRange(positions, offset, length);
|
||||
|
||||
if(isVecMode) {
|
||||
return vecCopyPositions(positions, offset, length);
|
||||
}
|
||||
int finalLength = 0;
|
||||
for (int i = offset; i < offset + length; i++) {
|
||||
finalLength += getSliceLength(positions[i]);
|
||||
|
|
@ -185,9 +234,45 @@ public class VariableWidthBlock
|
|||
return new VariableWidthBlock(0, length, newSlice.slice(), newOffsets, newValueIsNull);
|
||||
}
|
||||
|
||||
private Block vecCopyPositions(int[] positions, int offset, int length) {
|
||||
int finalLength = 0;
|
||||
for (int i = 0; i < positions.length; i++) {
|
||||
finalLength += this.varcharVec.getLength(positions[i]);
|
||||
}
|
||||
|
||||
VarcharVec newVec = new VarcharVec(finalLength, length);
|
||||
int[] offsets = new int[positions.length];
|
||||
int[] lengths = new int[positions.length];
|
||||
int newOffset = 0;
|
||||
|
||||
boolean[] newValueIsNull = null;
|
||||
if (valueIsNull != null) {
|
||||
newValueIsNull = new boolean[length];
|
||||
}
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
int position = positions[i];
|
||||
if (!isEntryNull(position)) {
|
||||
byte[] data = this.varcharVec.getDataAtOffset(position);
|
||||
offsets[i] = newOffset;
|
||||
lengths[i] = data.length;
|
||||
newVec.setData(newOffset, data);
|
||||
newOffset = newOffset + data.length;
|
||||
}
|
||||
else if (newValueIsNull != null) {
|
||||
newValueIsNull[i] = true;
|
||||
}
|
||||
}
|
||||
newVec.set(offsets, lengths);
|
||||
return new VariableWidthBlock(newVec, offsets, lengths, newValueIsNull);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Slice getRawSlice(int position)
|
||||
{
|
||||
if (isVecMode) {
|
||||
return Slices.wrappedBuffer(varcharVec.getData(0, varcharVec.capacity()));
|
||||
}
|
||||
return slice;
|
||||
}
|
||||
|
||||
|
|
@ -196,13 +281,27 @@ public class VariableWidthBlock
|
|||
{
|
||||
checkValidRegion(getPositionCount(), positionOffset, length);
|
||||
|
||||
if (isVecMode) {
|
||||
return getRegionVec(positionOffset, length);
|
||||
}
|
||||
return new VariableWidthBlock(positionOffset + arrayOffset, length, slice, offsets, valueIsNull);
|
||||
}
|
||||
|
||||
private Block getRegionVec(int positionOffset, int length)
|
||||
{
|
||||
VarcharVec newVec = (VarcharVec) this.varcharVec.slice(positionOffset, positionOffset + length);
|
||||
return new VariableWidthBlock(newVec, newVec.getOffsets(), newVec.getLengths(), valueIsNull);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block copyRegion(int positionOffset, int length)
|
||||
{
|
||||
checkValidRegion(getPositionCount(), positionOffset, length);
|
||||
|
||||
if(isVecMode) {
|
||||
return copyRegionVec(positionOffset, length);
|
||||
}
|
||||
|
||||
positionOffset += arrayOffset;
|
||||
|
||||
int[] newOffsets = compactOffsets(offsets, positionOffset, length);
|
||||
|
|
@ -215,6 +314,12 @@ public class VariableWidthBlock
|
|||
return new VariableWidthBlock(0, length, newSlice, newOffsets, newValueIsNull);
|
||||
}
|
||||
|
||||
public Block copyRegionVec(int positionOffset, int length)
|
||||
{
|
||||
VarcharVec newVec = (VarcharVec) this.varcharVec.slice(positionOffset, positionOffset + length);
|
||||
return new VariableWidthBlock(newVec, newVec.getOffsets(), newVec.getLengths(), valueIsNull);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
|
@ -262,6 +367,10 @@ public class VariableWidthBlock
|
|||
if (valueIsNull != null && valueIsNull[position + arrayOffset]) {
|
||||
return null;
|
||||
}
|
||||
if (isVecMode) {
|
||||
System.out.println("Reading data from vector::::");
|
||||
return varcharVec.getData(position);
|
||||
}
|
||||
return slice.slice(offsets[position + arrayOffset], offsets[position + arrayOffset + 1] - offsets[position + arrayOffset]).getBytes();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ package io.prestosql.spi.type;
|
|||
import io.prestosql.spi.block.Block;
|
||||
import io.prestosql.spi.block.BlockBuilder;
|
||||
import io.prestosql.spi.block.BlockBuilderStatus;
|
||||
import io.prestosql.spi.block.LongArrayBlockBuilder;
|
||||
import io.prestosql.spi.block.DoubleArrayBlockBuilder;
|
||||
import io.prestosql.spi.block.PageBuilderStatus;
|
||||
import io.prestosql.spi.connector.ConnectorSession;
|
||||
|
||||
|
|
@ -24,7 +24,6 @@ import java.util.Optional;
|
|||
|
||||
import static io.prestosql.spi.type.TypeSignature.parseTypeSignature;
|
||||
import static java.lang.Double.doubleToLongBits;
|
||||
import static java.lang.Double.longBitsToDouble;
|
||||
|
||||
public final class DoubleType
|
||||
extends AbstractType
|
||||
|
|
@ -61,14 +60,14 @@ public final class DoubleType
|
|||
if (block.isNull(position)) {
|
||||
return null;
|
||||
}
|
||||
return longBitsToDouble(block.getLong(position, 0));
|
||||
return block.getDouble(position, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equalTo(Block leftBlock, int leftPosition, Block rightBlock, int rightPosition)
|
||||
{
|
||||
double leftValue = longBitsToDouble(leftBlock.getLong(leftPosition, 0));
|
||||
double rightValue = longBitsToDouble(rightBlock.getLong(rightPosition, 0));
|
||||
double leftValue = leftBlock.getDouble(leftPosition, 0);
|
||||
double rightValue = rightBlock.getDouble(rightPosition, 0);
|
||||
|
||||
// direct equality is correct here
|
||||
// noinspection FloatingPointEquality
|
||||
|
|
@ -79,14 +78,14 @@ public final class DoubleType
|
|||
public long hash(Block block, int position)
|
||||
{
|
||||
// convert to canonical NaN if necessary
|
||||
return AbstractLongType.hash(doubleToLongBits(longBitsToDouble(block.getLong(position, 0))));
|
||||
return AbstractLongType.hash(doubleToLongBits(block.getDouble(position, 0)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Block leftBlock, int leftPosition, Block rightBlock, int rightPosition)
|
||||
{
|
||||
double leftValue = longBitsToDouble(leftBlock.getLong(leftPosition, 0));
|
||||
double rightValue = longBitsToDouble(rightBlock.getLong(rightPosition, 0));
|
||||
double leftValue = leftBlock.getDouble(leftPosition, 0);
|
||||
double rightValue = rightBlock.getDouble(rightPosition, 0);
|
||||
return Double.compare(leftValue, rightValue);
|
||||
}
|
||||
|
||||
|
|
@ -97,20 +96,20 @@ public final class DoubleType
|
|||
blockBuilder.appendNull();
|
||||
}
|
||||
else {
|
||||
blockBuilder.writeLong(block.getLong(position, 0)).closeEntry();
|
||||
blockBuilder.writeDouble(block.getDouble(position, 0)).closeEntry();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(Block block, int position)
|
||||
{
|
||||
return longBitsToDouble(block.getLong(position, 0));
|
||||
return block.getDouble(position, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDouble(BlockBuilder blockBuilder, double value)
|
||||
{
|
||||
blockBuilder.writeLong(doubleToLongBits(value)).closeEntry();
|
||||
blockBuilder.writeDouble(value).closeEntry();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -123,7 +122,7 @@ public final class DoubleType
|
|||
else {
|
||||
maxBlockSizeInBytes = blockBuilderStatus.getMaxPageSizeInBytes();
|
||||
}
|
||||
return new LongArrayBlockBuilder(
|
||||
return new DoubleArrayBlockBuilder(
|
||||
blockBuilderStatus,
|
||||
Math.min(expectedEntries, maxBlockSizeInBytes / Double.BYTES));
|
||||
}
|
||||
|
|
@ -137,7 +136,7 @@ public final class DoubleType
|
|||
@Override
|
||||
public final BlockBuilder createFixedSizeBlockBuilder(int positionCount)
|
||||
{
|
||||
return new LongArrayBlockBuilder(null, positionCount);
|
||||
return new DoubleArrayBlockBuilder(null, positionCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ public final class TestingBlockEncodingSerde
|
|||
addBlockEncoding(new ByteArrayBlockEncoding());
|
||||
addBlockEncoding(new ShortArrayBlockEncoding());
|
||||
addBlockEncoding(new IntArrayBlockEncoding());
|
||||
addBlockEncoding(new DoubleArrayBlockEncoding());
|
||||
addBlockEncoding(new LongArrayBlockEncoding());
|
||||
addBlockEncoding(new Int128ArrayBlockEncoding());
|
||||
addBlockEncoding(new DictionaryBlockEncoding());
|
||||
|
|
|
|||
Loading…
Reference in New Issue