Skip to content

Commit

Permalink
Initial QST prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
devinrsmith committed Jun 4, 2021
1 parent 43539c1 commit be92326
Show file tree
Hide file tree
Showing 44 changed files with 2,008 additions and 1 deletion.
12 changes: 12 additions & 0 deletions qst/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
dependencies {
annotationProcessor 'org.immutables:value:2.8.1'
compileOnly 'org.immutables:value-annotations:2.8.1'

testImplementation(platform('org.junit:junit-bom:5.7.2'))
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.assertj:assertj-core:3.19.0'
}

test {
useJUnitPlatform()
}
13 changes: 13 additions & 0 deletions qst/src/main/java/io/deephaven/qst/AllowNulls.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.deephaven.qst;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.CLASS)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE})
public @interface AllowNulls {

}

159 changes: 159 additions & 0 deletions qst/src/main/java/io/deephaven/qst/Examples4.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package io.deephaven.qst;

import io.deephaven.qst.table.NewTable;
import io.deephaven.qst.table.column.Column;
import io.deephaven.qst.table.column.header.ColumnHeader;
import io.deephaven.qst.table.column.header.ColumnHeaders3;

public class Examples4 {





















static NewTable example1() {
return NewTable.of(
Column.of("LastName", "Rafferty", "Jones", "Steiner", "Robins", "Smith", "Rogers"),
Column.of("DeptId", 31, 33, 33, 34, 34, null),
Column.of("Telephone", "(347) 555-0123", "(917) 555-0198", "(212) 555-0167", "(952) 555-0110", null, null));
}

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

static NewTable example2() {
return NewTable
.header("LastName", String.class)
.header("DeptId", int.class)
.header("Telephone", String.class)
.row("Rafferty", 31, "(347) 555-0123")
.row("Jones", 33, "(917) 555-0198")
.row("Steiner", 33, "(212) 555-0167")
.row("Robins", 34, "(952) 555-0110")
.row("Smith", 34, null)
.row("Rogers", null, null)
.build();
}

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

static final ColumnHeader<Integer> DEPT_ID = ColumnHeader.ofInt("DeptId");
static final ColumnHeader<String> TELEPHONE = ColumnHeader.ofString("Telephone");

static final ColumnHeaders3<String, Integer, String> EMPLOYEE_HEADER = ColumnHeader
.of("LastName", String.class)
.header(DEPT_ID)
.header(TELEPHONE);

static final ColumnHeaders3<Integer, String, String> DEPARTMENT_HEADER =
DEPT_ID
.header("DeptName", String.class)
.header(TELEPHONE);

static NewTable example3a() {
return EMPLOYEE_HEADER
.row("Rafferty", 31, "(347) 555-0123")
.row("Jones", 33, "(917) 555-0198")
.row("Steiner", 33, "(212) 555-0167")
.row("Robins", 34, "(952) 555-0110")
.row("Smith", 34, null)
.row("Rogers", null, null)
.build();
}

static NewTable example3b() {
return EMPLOYEE_HEADER
.row("Foo", null, "(555) 555-5555")
.row("Bar", null, "(555) 555-5555")
.build();
}

static NewTable example3c() {
return DEPARTMENT_HEADER
.row(31, "Sales", "(646) 555-0134")
.row(33, "Engineering", "(646) 555-0178")
.row(34, "Clerical", "(646) 555-0159")
.row(35, "Marketing", "(212) 555-0111")
.build();
}

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

interface Employee {
String name();
Integer deptId();
String telephone();
}

interface Department {
int id();
String name();
String telephone();
}

// impls out-of-scope

static Employee RAFFERTY = null;
static Employee JONES = null;
static Employee STEINER = null;
static Employee ROBINS = null;
static Employee SMITH = null;
static Employee ROGERS = null;

static Department SALES = null;
static Department ENGINEERING = null;
static Department CLERICAL = null;
static Department MARKETING = null;

static NewTable example4a(Employee... employees) {
ColumnHeaders3<String, Integer, String>.Rows builder = EMPLOYEE_HEADER.start();
for (Employee employee : employees) {
builder.row(employee.name(), employee.deptId(), employee.telephone());
}
return builder.build();
}

static NewTable example4a() {
return example4a(
RAFFERTY,
JONES,
STEINER,
ROBINS,
SMITH,
ROGERS);
}

static NewTable example4b(Department... departments) {
ColumnHeaders3<Integer, String, String>.Rows builder = DEPARTMENT_HEADER.start();
for (Department d : departments) {
builder.row(d.id(), d.name(), d.telephone());
}
return builder.build();
}

static NewTable example4b() {
return example4b(
SALES,
ENGINEERING,
CLERICAL,
MARKETING);
}

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

}
16 changes: 16 additions & 0 deletions qst/src/main/java/io/deephaven/qst/QSTStyle.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.deephaven.qst;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.immutables.value.Value;
import org.immutables.value.Value.Style.ImplementationVisibility;

@Target({ElementType.PACKAGE, ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
@Value.Style(
visibility = ImplementationVisibility.PACKAGE,
defaults = @Value.Immutable(copy = false),
strictBuilder = true)
public @interface QSTStyle {}
2 changes: 2 additions & 0 deletions qst/src/main/java/io/deephaven/qst/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@QSTStyle
package io.deephaven.qst;
30 changes: 30 additions & 0 deletions qst/src/main/java/io/deephaven/qst/table/EmptyTable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.deephaven.qst.table;

import org.immutables.value.Value.Check;
import org.immutables.value.Value.Immutable;
import org.immutables.value.Value.Parameter;

@Immutable(builder = false, copy = false)
public abstract class EmptyTable extends TableBase {

public static EmptyTable of(long size) {
return ImmutableEmptyTable.of(size, TableHeader.empty());
}

public static EmptyTable of(long size, TableHeader header) {
return ImmutableEmptyTable.of(size, header);
}

@Parameter
public abstract long size();

@Parameter
public abstract TableHeader header();

@Check
final void checkSize() {
if (size() < 0) {
throw new IllegalArgumentException("Must have non-negative size");
}
}
}
22 changes: 22 additions & 0 deletions qst/src/main/java/io/deephaven/qst/table/HeadTable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.deephaven.qst.table;

import org.immutables.value.Value.Check;
import org.immutables.value.Value.Immutable;
import org.immutables.value.Value.Parameter;

@Immutable(builder = false, copy = false)
public abstract class HeadTable extends TableBase {

@Parameter
public abstract Table parent();

@Parameter
public abstract long size();

@Check
final void checkSize() {
if (size() <= 0) {
throw new IllegalArgumentException("Must have positive size");
}
}
}
79 changes: 79 additions & 0 deletions qst/src/main/java/io/deephaven/qst/table/NewTable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package io.deephaven.qst.table;

import io.deephaven.qst.table.ImmutableTableHeader.Builder;
import io.deephaven.qst.table.column.Column;
import io.deephaven.qst.table.column.header.ColumnHeader;
import java.util.Iterator;
import java.util.List;
import org.immutables.value.Value.Check;
import org.immutables.value.Value.Immutable;

@Immutable
public abstract class NewTable extends TableBase {

public static NewTable empty(TableHeader header) {
ImmutableNewTable.Builder builder = ImmutableNewTable.builder().size(0);
for (ColumnHeader<?> columnHeader : header.headers()) {
builder.addColumns(columnHeader.emptyData());
}
return builder.build();
}

public static NewTable of(Column<?>... columns) {
final int size = columns.length > 0 ? columns[0].size() : 0;
return ImmutableNewTable.builder().addColumns(columns).size(size).build();
}

public static NewTable of(Iterable<Column<?>> columns) {
Iterator<Column<?>> it = columns.iterator();
final int size = it.hasNext() ? it.next().size() : 0;
return ImmutableNewTable.builder().addAllColumns(columns).size(size).build();
}

public static <A> ColumnHeader<A> header(String name, Class<A> clazz) {
return ColumnHeader.of(name, clazz);
}

public abstract List<Column<?>> columns();

public abstract int size();

public final int numColumns() {
return columns().size();
}

public final TableHeader header() {
Builder builder = ImmutableTableHeader.builder();
for (Column<?> column : columns()) {
builder.addHeaders(column.header());
}
return builder.build();
}

public final NewTable with(Column<?> column) {
return ImmutableNewTable.builder()
.size(size())
.addAllColumns(columns())
.addColumns(column)
.build();
}

@Check
final void checkColumnsSizes() {
if (!columns()
.stream()
.map(Column::values)
.mapToInt(List::size)
.allMatch(s -> s == size())) {
throw new IllegalArgumentException("All columns must be the same size");
}
}

@Check
final void checkValidHeader() {
// ensure we can build the header
if (header().numColumns() != numColumns()) {
throw new IllegalArgumentException("All headers must have distinct names");
}
}
}
13 changes: 13 additions & 0 deletions qst/src/main/java/io/deephaven/qst/table/NewTableBuildable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.deephaven.qst.table;

import io.deephaven.qst.table.column.Column;
import java.util.stream.Stream;

public abstract class NewTableBuildable {

protected abstract Stream<Column<?>> columns();

public final NewTable build() {
return NewTable.of(() -> columns().iterator());
}
}
8 changes: 8 additions & 0 deletions qst/src/main/java/io/deephaven/qst/table/NewTableColumn.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.deephaven.qst.table;

import org.immutables.value.Value.Immutable;

@Immutable
public abstract class NewTableColumn {

}
16 changes: 16 additions & 0 deletions qst/src/main/java/io/deephaven/qst/table/Table.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.deephaven.qst.table;

public interface Table {

static EmptyTable empty(long size) {
return EmptyTable.of(size);
}

static EmptyTable empty(long size, TableHeader header) {
return EmptyTable.of(size, header);
}

HeadTable head(long size);

TailTable tail(long size);
}
14 changes: 14 additions & 0 deletions qst/src/main/java/io/deephaven/qst/table/TableBase.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.deephaven.qst.table;

public abstract class TableBase implements Table {

@Override
public final HeadTable head(long size) {
return ImmutableHeadTable.of(this, size);
}

@Override
public final TailTable tail(long size) {
return ImmutableTailTable.of(this, size);
}
}
Loading

0 comments on commit be92326

Please sign in to comment.