Skip to content

Commit

Permalink
Allow other Vector types
Browse files Browse the repository at this point in the history
  • Loading branch information
devinrsmith committed Oct 17, 2023
1 parent a9abaf6 commit 1f1467c
Show file tree
Hide file tree
Showing 16 changed files with 614 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,28 @@ public static ColumnDefinition<Instant> ofTime(@NotNull final String name) {
}

public static ColumnDefinition<?> of(String name, Type<?> type) {
return type.walk(new Adapter(name));
return ensureConsistent(type, type.walk(new Adapter(name)));
}

public static ColumnDefinition<?> of(String name, PrimitiveType<?> type) {
final PrimitiveType.Visitor<ColumnDefinition<?>> adapter = new Adapter(name);
return type.walk(adapter);
return ensureConsistent(type, type.walk(adapter));
}

public static ColumnDefinition<?> of(String name, GenericType<?> type) {
final GenericType.Visitor<ColumnDefinition<?>> adapter = new Adapter(name);
return type.walk(adapter);
return ensureConsistent(type, type.walk(adapter));
}

private static <T> ColumnDefinition<T> ensureConsistent(Type<?> expected, ColumnDefinition<T> cd) {
final Type<T> actual = cd.getType();
if (!expected.equals(actual)) {
throw new IllegalStateException(String.format(
"ColumnDefinition.getType() inconsistency. expected=%s, actual=%s, name=%s, dataType=%s, componentType=%s",
expected, actual, cd.getName(), cd.getDataType().getName(),
cd.getComponentType() == null ? null : cd.getComponentType().getName()));
}
return cd;
}

public static <T extends Vector<?>> ColumnDefinition<T> ofVector(
Expand Down Expand Up @@ -150,6 +161,44 @@ public static <T> ColumnDefinition<T> fromGenericType(
name, dataType, checkAndMaybeInferComponentType(dataType, componentType), columnType);
}

public static <T> Type<T> type(
@NotNull final Class<T> dataType,
@Nullable final Class<?> componentType) {
if (componentType == null) {
return Type.find(dataType);
}
if (dataType.isArray()) {
return NativeArrayType.of(dataType, Type.find(componentType));
}
if (Vector.class.isAssignableFrom(dataType)) {
return vectorTypeAsType(dataType, componentType);
}
return null;
}

private static <T> Type<T> vectorTypeAsType(
@NotNull final Class<T> dataType,
@NotNull final Class<?> componentType) {
// noinspection unchecked
return (Type<T>) vectorType(dataType, componentType);
}

private static <VT extends Vector<VT>> ArrayType<VT, ?> vectorType(
@NotNull final Class<?> dataType,
@NotNull final Class<?> componentType) {
// noinspection unchecked
final Class<VT> vectorType = (Class<VT>) dataType;
return vectorType(vectorType, Type.find(componentType));
}

private static <VT extends Vector<VT>, ComponentType> ArrayType<VT, ComponentType> vectorType(
Class<VT> vectorClass,
Type<ComponentType> type) {
return type instanceof PrimitiveType
? PrimitiveVectorType.of(vectorClass, (PrimitiveType<ComponentType>) type)
: GenericVectorType.of(vectorClass, (GenericType<ComponentType>) type);
}

/**
* Base component type class for each {@link Vector} type.
*/
Expand Down Expand Up @@ -389,6 +438,10 @@ public ColumnType getColumnType() {
return columnType;
}

public Type<TYPE> getType() {
return type(dataType, componentType);
}

public ColumnDefinition<TYPE> withPartitioning() {
return isPartitioning() ? this : new ColumnDefinition<>(name, dataType, componentType, ColumnType.Partitioning);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import io.deephaven.base.verify.Assert;
import io.deephaven.io.log.impl.LogOutputStringImpl;
import io.deephaven.qst.column.header.ColumnHeader;
import io.deephaven.qst.type.Type;
import org.jetbrains.annotations.NotNull;

import java.util.Map.Entry;
Expand Down Expand Up @@ -267,6 +268,13 @@ public Class<?>[] getColumnTypesArray() {
return getColumnStream().map(ColumnDefinition::getDataType).toArray(Class[]::new);
}

/**
* @return The column {@link ColumnDefinition#getType()} types} as a list in the same order as {@link #getColumns()}
*/
public List<Type<?>> getColumnTypes2() {
return getColumnStream().map(ColumnDefinition::getType).collect(Collectors.toList());
}

/**
* @param columnName The column name to search for
* @param <T> The column {@link ColumnDefinition#getDataType() data types}, as a type parameter
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
/**
* Copyright (c) 2016-2023 Deephaven Data Labs and Patent Pending
*/
package io.deephaven.engine.table;

import io.deephaven.qst.type.BoxedType;
import io.deephaven.qst.type.GenericType;
import io.deephaven.qst.type.GenericTypeBase;
import io.deephaven.qst.type.PrimitiveType;
import io.deephaven.qst.type.PrimitiveVectorType;
import io.deephaven.qst.type.Type;
import io.deephaven.vector.ByteVector;
import io.deephaven.vector.ByteVectorDirect;
import io.deephaven.vector.CharVector;
import io.deephaven.vector.CharVectorDirect;
import io.deephaven.vector.DoubleVector;
import io.deephaven.vector.DoubleVectorDirect;
import io.deephaven.vector.FloatVector;
import io.deephaven.vector.FloatVectorDirect;
import io.deephaven.vector.IntVector;
import io.deephaven.vector.IntVectorDirect;
import io.deephaven.vector.LongVector;
import io.deephaven.vector.LongVectorDirect;
import io.deephaven.vector.ObjectVector;
import io.deephaven.vector.ShortVector;
import io.deephaven.vector.ShortVectorDirect;
import org.junit.Test;

import java.time.Instant;

import static org.junit.Assert.assertEquals;

public class ColumnDefinitionTypeTest {

private static final String FOO = "Foo";

public interface FooCustom {

}

@Test
public void testPrimitives() {
checkTransitiveType(Type.booleanType().boxedType());
checkTransitiveType(Type.byteType());
checkTransitiveType(Type.charType());
checkTransitiveType(Type.shortType());
checkTransitiveType(Type.intType());
checkTransitiveType(Type.longType());
checkTransitiveType(Type.floatType());
checkTransitiveType(Type.doubleType());

checkTransformedType(Type.booleanType(), Type.booleanType().boxedType());
checkTransformedType(Type.byteType().boxedType(), Type.byteType());
checkTransformedType(Type.charType().boxedType(), Type.charType());
checkTransformedType(Type.shortType().boxedType(), Type.shortType());
checkTransformedType(Type.intType().boxedType(), Type.intType());
checkTransformedType(Type.longType().boxedType(), Type.longType());
checkTransformedType(Type.floatType().boxedType(), Type.floatType());
checkTransformedType(Type.doubleType().boxedType(), Type.doubleType());
}

@Test
public void testGenerics() {
checkTransitiveType(Type.stringType());
checkTransitiveType(Type.instantType());
checkTransitiveType(Type.ofCustom(FooCustom.class));
}

@Test
public void testPrimitiveArrays() {
PrimitiveType.instances().forEach(primitiveType -> checkTransitiveType(primitiveType.arrayType()));
}

@Test
public void testGenericArrays() {
BoxedType.instances().map(GenericType::arrayType).forEach(ColumnDefinitionTypeTest::checkTransitiveType);

checkTransitiveType(Type.stringType().arrayType());
checkTransitiveType(Type.instantType().arrayType());
checkTransitiveType(Type.ofCustom(FooCustom.class).arrayType());

PrimitiveType.instances().map(Type::arrayType).map(GenericTypeBase::arrayType)
.forEach(ColumnDefinitionTypeTest::checkTransitiveType);

checkTransitiveType(Type.stringType().arrayType().arrayType());
checkTransitiveType(Type.instantType().arrayType().arrayType());
checkTransitiveType(Type.ofCustom(FooCustom.class).arrayType().arrayType());
}

@Test
public void testPrimitiveVectors() {
checkTransitiveType(ByteVector.type());
checkTransitiveType(CharVector.type());
checkTransitiveType(ShortVector.type());
checkTransitiveType(IntVector.type());
checkTransitiveType(LongVector.type());
checkTransitiveType(FloatVector.type());
checkTransitiveType(DoubleVector.type());
}

@Test
public void testGenericVectors() {
checkTransitiveType(ObjectVector.type(Type.stringType()));
checkTransitiveType(ObjectVector.type(Type.instantType()));
checkTransitiveType(ObjectVector.type(Type.ofCustom(FooCustom.class)));

BoxedType.instances().map(ObjectVector::type).forEach(ColumnDefinitionTypeTest::checkTransitiveType);
}

@Test
public void testOfBooleanType() {
checkType(Type.booleanType().boxedType(), ColumnDefinition.ofBoolean(FOO));
}

@Test
public void testOfCharType() {
checkType(Type.charType(), ColumnDefinition.ofChar(FOO));
}

@Test
public void testOfByteType() {
checkType(Type.byteType(), ColumnDefinition.ofByte(FOO));
}

@Test
public void testOfShortType() {
checkType(Type.shortType(), ColumnDefinition.ofShort(FOO));
}

@Test
public void testOfIntType() {
checkType(Type.intType(), ColumnDefinition.ofInt(FOO));
}

@Test
public void testOfLongType() {
checkType(Type.longType(), ColumnDefinition.ofLong(FOO));
}

@Test
public void testOfFloatType() {
checkType(Type.floatType(), ColumnDefinition.ofFloat(FOO));
}

@Test
public void testOfDoubleType() {
checkType(Type.doubleType(), ColumnDefinition.ofDouble(FOO));
}

@Test
public void testOfStringType() {
checkType(Type.stringType(), ColumnDefinition.ofString(FOO));
}

@Test
public void testOfTimeType() {
checkType(Type.instantType(), ColumnDefinition.ofTime(FOO));
}

@Test
public void testOfVector() {
checkType(CharVector.type(), ColumnDefinition.ofVector(FOO, CharVector.class));
checkType(ByteVector.type(), ColumnDefinition.ofVector(FOO, ByteVector.class));
checkType(ShortVector.type(), ColumnDefinition.ofVector(FOO, ShortVector.class));
checkType(IntVector.type(), ColumnDefinition.ofVector(FOO, IntVector.class));
checkType(LongVector.type(), ColumnDefinition.ofVector(FOO, LongVector.class));
checkType(FloatVector.type(), ColumnDefinition.ofVector(FOO, FloatVector.class));
checkType(DoubleVector.type(), ColumnDefinition.ofVector(FOO, DoubleVector.class));
checkType(ObjectVector.type(Type.ofCustom(Object.class)), ColumnDefinition.ofVector(FOO, ObjectVector.class));
}

@Test
public void testFromGenericType() {
checkType(ObjectVector.type(Type.stringType()),
ColumnDefinition.fromGenericType(FOO, ObjectVector.class, String.class));
checkType(ObjectVector.type(Type.instantType()),
ColumnDefinition.fromGenericType(FOO, ObjectVector.class, Instant.class));
checkType(ObjectVector.type(Type.ofCustom(FooCustom.class)),
ColumnDefinition.fromGenericType(FOO, ObjectVector.class, FooCustom.class));
BoxedType.instances().forEach(boxedType -> checkType(ObjectVector.type(boxedType),
ColumnDefinition.fromGenericType(FOO, ObjectVector.class, boxedType.clazz())));
}

@Test
public void testExplicitVectorTypes() {
checkType(PrimitiveVectorType.of(CharVectorDirect.class, Type.charType()),
ColumnDefinition.ofVector(FOO, CharVectorDirect.class));
checkType(PrimitiveVectorType.of(ByteVectorDirect.class, Type.byteType()),
ColumnDefinition.ofVector(FOO, ByteVectorDirect.class));
checkType(PrimitiveVectorType.of(ShortVectorDirect.class, Type.shortType()),
ColumnDefinition.ofVector(FOO, ShortVectorDirect.class));
checkType(PrimitiveVectorType.of(IntVectorDirect.class, Type.intType()),
ColumnDefinition.ofVector(FOO, IntVectorDirect.class));
checkType(PrimitiveVectorType.of(LongVectorDirect.class, Type.longType()),
ColumnDefinition.ofVector(FOO, LongVectorDirect.class));
checkType(PrimitiveVectorType.of(FloatVectorDirect.class, Type.floatType()),
ColumnDefinition.ofVector(FOO, FloatVectorDirect.class));
checkType(PrimitiveVectorType.of(DoubleVectorDirect.class, Type.doubleType()),
ColumnDefinition.ofVector(FOO, DoubleVectorDirect.class));
}

private static void checkTransitiveType(Type<?> type) {
checkType(type, cd(type));
}

private static void checkTransformedType(Type<?> cdInput, Type<?> expected) {
checkType(expected, cd(cdInput));
}

private static void checkType(Type<?> expected, ColumnDefinition<?> actual) {
assertEquals(expected, actual.getType());
}

private static ColumnDefinition<?> cd(Type<?> type) {
return ColumnDefinition.of(FOO, type);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Copyright (c) 2016-2023 Deephaven Data Labs and Patent Pending
*/
package io.deephaven.qst.type;

import io.deephaven.vector.ObjectVector;
import io.deephaven.vector.ObjectVectorDirect;
import io.deephaven.vector.Vector;
import org.junit.Test;

import java.time.Instant;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;

public class GenericVectorTest {

@Test
public void stringType() {
final GenericVectorType<ObjectVector<String>, String> type = ObjectVector.type(Type.stringType());
assertThat(type.clazz()).isEqualTo(ObjectVector.class);
assertThat(type.componentType()).isEqualTo(Type.stringType());
}

@Test
public void instantType() {
final GenericVectorType<ObjectVector<Instant>, Instant> type = ObjectVector.type(Type.instantType());
assertThat(type.clazz()).isEqualTo(ObjectVector.class);
assertThat(type.componentType()).isEqualTo(Type.instantType());
}

@Test
public void boxedTypes() {
BoxedType.instances().forEach(boxedType -> {
final GenericVectorType<? extends ObjectVector<?>, ?> type = ObjectVector.type(boxedType);
assertThat(type.clazz()).isEqualTo(ObjectVector.class);
assertThat(type.componentType()).isEqualTo(boxedType);
});
}

@Test
public void badClass() {
try {
GenericVectorType.of(Vector.class, Type.stringType());
failBecauseExceptionWasNotThrown(IllegalAccessError.class);
} catch (IllegalArgumentException e) {
// expected
}
}

@Test
public void alternativeTypes() {
final GenericVectorType<ObjectVectorDirect, String> type =
GenericVectorType.of(ObjectVectorDirect.class, Type.stringType());
assertThat(type.clazz()).isEqualTo(ObjectVectorDirect.class);
assertThat(type.componentType()).isEqualTo(Type.stringType());
}
}
Loading

0 comments on commit 1f1467c

Please sign in to comment.