Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add java-client support for primitive array types #5494

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions java-client/flight-examples/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ application.applicationDistribution.into('bin') {
from(createApplication('do-put-table', 'io.deephaven.client.examples.DoPutTable'))

from(createApplication('add-to-input-table', 'io.deephaven.client.examples.AddToInputTable'))
from(createApplication('add-to-blink-table', 'io.deephaven.client.examples.AddToBlinkTable'))
from(createApplication('kv-input-table', 'io.deephaven.client.examples.KeyValueInputTable'))

from(createApplication('get-table', 'io.deephaven.client.examples.GetDirectTable'))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
//
// Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending
//
package io.deephaven.client.examples;

import io.deephaven.client.impl.FlightSession;
import io.deephaven.client.impl.TableHandle;
import io.deephaven.client.impl.TableHandle.TableHandleException;
import io.deephaven.qst.column.header.ColumnHeader;
import io.deephaven.qst.table.BlinkInputTable;
import io.deephaven.qst.table.NewTable;
import io.deephaven.qst.table.TableHeader;
import io.deephaven.qst.table.TableSpec;
import io.deephaven.qst.type.Type;
import picocli.CommandLine;
import picocli.CommandLine.Command;

import java.time.Instant;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

@Command(name = "add-to-blink-table", mixinStandardHelpOptions = true,
description = "Add to Blink Table", version = "0.1.0")
class AddToBlinkTable extends FlightExampleBase {

public <T> void addAndPublish(FlightSession flight, String name, Type<T> type, T... data)
throws TableHandleException, InterruptedException, ExecutionException, TimeoutException {
final ColumnHeader<T> header = ColumnHeader.of(name, type);
final ColumnHeader<T>.Rows rows = header.start(data.length);
for (T datum : data) {
rows.row(datum);
}
final NewTable newTable = rows.newTable();
final BlinkInputTable blinkTable = BlinkInputTable.of(TableHeader.of(header));
final TableSpec tail = blinkTable.tail(32);
final List<TableHandle> handles = flight.session().execute(List.of(blinkTable, tail));
try (
final TableHandle blinkHandle = handles.get(0);
final TableHandle output = handles.get(1)) {
flight.addToInputTable(blinkHandle, newTable, bufferAllocator).get(5, TimeUnit.SECONDS);
flight.session().publish(name + "_Table", output).get(5, TimeUnit.SECONDS);
}
}

@Override
protected void execute(FlightSession flight) throws Exception {
addAndPublish(flight, "Boolean", Type.booleanType(), null, true, false);
addAndPublish(flight, "Byte", Type.byteType(), null, (byte) 42);
addAndPublish(flight, "Char", Type.charType(), null, 'a');
addAndPublish(flight, "Short", Type.shortType(), null, (short) 42);
addAndPublish(flight, "Int", Type.intType(), null, 42);
addAndPublish(flight, "Long", Type.longType(), null, 42L);
addAndPublish(flight, "Float", Type.floatType(), null, 42.24f);
addAndPublish(flight, "Double", Type.doubleType(), null, 42.24);

addAndPublish(flight, "BoxedBoolean", Type.booleanType().boxedType(), null, true, false);
addAndPublish(flight, "BoxedByte", Type.byteType().boxedType(), null, (byte) 42);
addAndPublish(flight, "BoxedChar", Type.charType().boxedType(), null, 'a');
addAndPublish(flight, "BoxedShort", Type.shortType().boxedType(), null, (short) 42);
addAndPublish(flight, "BoxedInt", Type.intType().boxedType(), null, 42);
addAndPublish(flight, "BoxedLong", Type.longType().boxedType(), null, 42L);
addAndPublish(flight, "BoxedFloat", Type.floatType().boxedType(), null, 42.24f);
addAndPublish(flight, "BoxedDouble", Type.doubleType().boxedType(), null, 42.24);

addAndPublish(flight, "String", Type.stringType(), null, "", "Hello");
addAndPublish(flight, "Instant", Type.instantType(), null, Instant.now());

addAndPublish(flight, "BooleanArray", Type.booleanType().arrayType(),
null,
new boolean[] {true},
new boolean[] {true, false});
addAndPublish(flight, "ByteArray", Type.byteType().arrayType(),
null,
new byte[] {},
new byte[] {(byte) 42, (byte) 43});
addAndPublish(flight, "CharArray", Type.charType().arrayType(),
null,
new char[] {},
new char[] {'a', 'b'});
addAndPublish(flight, "ShortArray", Type.shortType().arrayType(),
null,
new short[] {},
new short[] {(short) 42, (short) 43});
addAndPublish(flight, "IntArray", Type.intType().arrayType(),
null,
new int[] {},
new int[] {42, 43});
addAndPublish(flight, "LongArray", Type.longType().arrayType(),
null,
new long[] {},
new long[] {42L, 43L});
addAndPublish(flight, "FloatArray", Type.floatType().arrayType(),
null,
new float[] {},
new float[] {42.42f, 43.43f});
addAndPublish(flight, "DoubleArray", Type.doubleType().arrayType(),
null,
new double[] {},
new double[] {42.42, 43.43});

addAndPublish(flight, "StringArray", Type.stringType().arrayType(),
null,
new String[] {},
new String[] {null, "", "Hello World"});
addAndPublish(flight, "InstantArray", Type.instantType().arrayType(),
null,
new Instant[] {},
new Instant[] {null, Instant.now()});
}

public static void main(String[] args) {
int execute = new CommandLine(new AddToBlinkTable()).execute(args);
System.exit(execute);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
import io.deephaven.qst.type.DoubleType;
import io.deephaven.qst.type.FloatType;
import io.deephaven.qst.type.GenericType;
import io.deephaven.qst.type.GenericType.Visitor;
import io.deephaven.qst.type.GenericVectorType;
import io.deephaven.qst.type.InstantType;
import io.deephaven.qst.type.IntType;
import io.deephaven.qst.type.LongType;
import io.deephaven.qst.type.NativeArrayType;
import io.deephaven.qst.type.PrimitiveType;
import io.deephaven.qst.type.PrimitiveVectorType;
import io.deephaven.qst.type.ShortType;
import io.deephaven.qst.type.StringType;
import io.deephaven.qst.type.Type;
Expand All @@ -33,7 +35,8 @@
/**
* Utilities for creating a {@link Field}.
*/
public class FieldAdapter implements Type.Visitor<Field>, PrimitiveType.Visitor<Field> {
public class FieldAdapter implements Type.Visitor<Field>, PrimitiveType.Visitor<Field>, GenericType.Visitor<Field>,
ArrayType.Visitor<Field> {

/**
* Convert a {@code header} into a {@link Field}.
Expand Down Expand Up @@ -98,6 +101,10 @@ private static Field field(String name, FieldType type) {
return new Field(name, type, null);
}

private static UnsupportedOperationException unsupported(Type<?> type) {
return new UnsupportedOperationException(String.format("Field type '%s' is not supported yet", type));
}

private final String name;

private FieldAdapter(String name) {
Expand All @@ -109,40 +116,6 @@ public Field visit(PrimitiveType<?> primitive) {
return primitive.walk((PrimitiveType.Visitor<Field>) this);
}

@Override
public Field visit(GenericType<?> generic) {
return generic.walk(new Visitor<Field>() {
@Override
public Field visit(BoxedType<?> boxedType) {
return FieldAdapter.this.visit(boxedType.primitiveType());
}

@Override
public Field visit(StringType stringType) {
return stringField(name);
}

@Override
public Field visit(InstantType instantType) {
return instantField(name);
}

@Override
public Field visit(ArrayType<?, ?> arrayType) {
if (arrayType.componentType().equals(Type.find(byte.class))) {
return byteVectorField(name);
} else {
throw new UnsupportedOperationException();
}
}

@Override
public Field visit(CustomType<?> customType) {
throw new UnsupportedOperationException();
}
});
}

@Override
public Field visit(ByteType byteType) {
return byteField(name);
Expand Down Expand Up @@ -182,4 +155,136 @@ public Field visit(FloatType floatType) {
public Field visit(DoubleType doubleType) {
return doubleField(name);
}

// ----------------------------------------------------------

@Override
public Field visit(GenericType<?> generic) {
return generic.walk((GenericType.Visitor<Field>) this);
}

@Override
public Field visit(BoxedType<?> boxedType) {
// same field type as primitives
return boxedType.primitiveType().walk((PrimitiveType.Visitor<Field>) this);
}

@Override
public Field visit(StringType stringType) {
return stringField(name);
}

@Override
public Field visit(InstantType instantType) {
return instantField(name);
}

@Override
public Field visit(CustomType<?> customType) {
throw unsupported(customType);
}

// ----------------------------------------------------------

@Override
public Field visit(ArrayType<?, ?> arrayType) {
return arrayType.walk((ArrayType.Visitor<Field>) this);
}

@Override
public Field visit(NativeArrayType<?, ?> nativeArrayType) {
return nativeArrayType.componentType().walk(new NativeArrayVisitor());
}

@Override
public Field visit(PrimitiveVectorType<?, ?> vectorPrimitiveType) {
throw unsupported(vectorPrimitiveType);
}

@Override
public Field visit(GenericVectorType<?, ?> genericVectorType) {
throw unsupported(genericVectorType);
}

// ----------------------------------------------------------

final class NativeArrayVisitor
implements Type.Visitor<Field>, PrimitiveType.Visitor<Field>, GenericType.Visitor<Field> {
@Override
public Field visit(PrimitiveType<?> primitiveType) {
return primitiveType.walk((PrimitiveType.Visitor<Field>) this);
}

@Override
public Field visit(BooleanType booleanType) {
return field(name, MinorType.LIST.getType(), "java.lang.Boolean[]");
}

@Override
public Field visit(ByteType byteType) {
return byteVectorField(name);
}

@Override
public Field visit(CharType charType) {
return field(name, MinorType.LIST.getType(), "char[]");
}

@Override
public Field visit(ShortType shortType) {
return field(name, MinorType.LIST.getType(), "short[]");
}

@Override
public Field visit(IntType intType) {
return field(name, MinorType.LIST.getType(), "int[]");
}

@Override
public Field visit(LongType longType) {
return field(name, MinorType.LIST.getType(), "long[]");
}

@Override
public Field visit(FloatType floatType) {
return field(name, MinorType.LIST.getType(), "float[]");
}

@Override
public Field visit(DoubleType doubleType) {
return field(name, MinorType.LIST.getType(), "double[]");
}

// ----------------------------------------------------------

@Override
public Field visit(GenericType<?> genericType) {
return genericType.walk((GenericType.Visitor<Field>) this);
}

@Override
public Field visit(BoxedType<?> boxedType) {
throw unsupported(boxedType.arrayType());
}

@Override
public Field visit(StringType stringType) {
return field(name, MinorType.LIST.getType(), "java.lang.String[]");
}

@Override
public Field visit(InstantType instantType) {
return field(name, MinorType.LIST.getType(), "java.time.Instant[]");
}

@Override
public Field visit(ArrayType<?, ?> arrayType) {
throw unsupported(arrayType.arrayType());
}

@Override
public Field visit(CustomType<?> customType) {
throw unsupported(customType.arrayType());
}
}
}
Loading
Loading