io.deephaven.engine.util.TableShowTools Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of deephaven-engine-table Show documentation
Show all versions of deephaven-engine-table Show documentation
Engine Table: Implementation and closely-coupled utilities
/**
* Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending
*/
package io.deephaven.engine.util;
import io.deephaven.datastructures.util.CollectionUtil;
import io.deephaven.engine.table.Table;
import io.deephaven.engine.table.impl.perf.QueryPerformanceRecorder;
import io.deephaven.engine.table.ColumnSource;
import io.deephaven.engine.rowset.RowSet;
import io.deephaven.time.DateTimeUtils;
import io.deephaven.util.SafeCloseable;
import io.deephaven.util.type.ArrayTypeUtils;
import java.io.PrintStream;
import java.lang.annotation.Annotation;
import java.time.Instant;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* The guts of TableTools.show.
*/
class TableShowTools {
static void showInternal(Table source, long firstRow, long lastRowExclusive, ZoneId timeZone, String delimiter,
PrintStream out, boolean showRowSet, String[] columns) {
try (final SafeCloseable ignored = QueryPerformanceRecorder.getInstance().getNugget("TableTools.show()")) {
if (columns.length == 0) {
final List columnNames = source.getDefinition().getColumnNames();
columns = columnNames.toArray(CollectionUtil.ZERO_LENGTH_STRING_ARRAY);
}
final ColumnSource[] columnSources =
Arrays.stream(columns).map(source::getColumnSource).toArray(ColumnSource[]::new);
final RowSet rowSet = source.getRowSet();
int lineLen = 0;
final Set columnLimits = new HashSet<>();
if (showRowSet) {
out.print("RowPosition");
out.print(delimiter);
out.print(" RowKey");
out.print(delimiter);
columnLimits.add(10);
columnLimits.add(21);
lineLen = 22;
}
final int[] columnLengths = new int[columns.length];
for (int i = 0; i < columns.length; i++) {
String column = columns[i];
if (i > 0) {
out.print(delimiter);
columnLimits.add(lineLen);
lineLen++;
}
final int columnLen = columnLengths[i] = getColumnLen(column, columnSources[i], rowSet);
while (columnLen > column.length()) {
column = " " + column;
}
out.print(column);
lineLen += column.length();
}
out.println();
for (int i = 0; i < lineLen; i++) {
if (columnLimits.contains(i)) {
if (delimiter.equals("|")) {
out.print("+");
} else {
out.print(delimiter);
}
} else {
out.print("-");
}
}
final ColumnPrinter[] columnPrinters = new ColumnPrinter[columns.length];
for (int i = 0; i < columns.length; i++) {
columnPrinters[i] = getColumnPrinter(columnSources[i], columnLengths[i], timeZone);
}
final ColumnPrinter positionPrinter = new DefaultPrinter(10);
final ColumnPrinter indexPrinter = new DefaultPrinter(10);
long ri = 0;
for (final RowSet.Iterator indexIterator = rowSet.iterator(); ri < lastRowExclusive
&& indexIterator.hasNext(); ++ri) {
final long key = indexIterator.nextLong();
if (ri < firstRow) {
continue;
}
if (showRowSet) {
out.println();
positionPrinter.print(out, ri);
out.print(delimiter);
indexPrinter.print(out, key);
}
for (int ci = 0; ci < columns.length; ci++) {
if (ci > 0 || showRowSet) {
out.print(delimiter);
} else {
out.println();
}
columnPrinters[ci].print(out, source.getColumnSource(columns[ci]).get(key));
}
}
out.println();
out.flush();
}
}
private static int getColumnLen(String name, ColumnSource columnSource, RowSet rowSet) {
int len = name.length();
if (columnSource.getType().isArray()) {
len = Math.max(len, 40);
} else if (columnSource.getType() == long.class || columnSource.getType() == Long.class) {
len = Math.max(len, 20);
} else if (columnSource.getType() == double.class || columnSource.getType() == Double.class) {
len = Math.max(len, 20);
} else if (columnSource.getType() == Instant.class) {
len = Math.max(len, 33);
} else if (columnSource.getType() == java.util.Date.class) {
len = Math.max(len, 33);
} else {
// noinspection unchecked
final Annotation annotation = columnSource.getType().getAnnotation(TableToolsShowControl.class);
if (annotation != null) {
len = Math.max(len, ((TableToolsShowControl) annotation).getWidth());
} else {
len = Math.max(len, 10);
}
}
if (columnSource.getType() == String.class) {
int ri = 0;
for (final RowSet.Iterator ii = rowSet.iterator(); ri < 100 && ii.hasNext(); ++ri) {
String s = (String) columnSource.get(ii.nextLong());
if (s != null) {
len = Math.min(Math.max(s.length(), len), 100);
}
}
}
return len;
}
private static ColumnPrinter getColumnPrinter(ColumnSource column, int len, ZoneId timeZone) {
if (column.getType() == Instant.class) {
return new InstantPrinter(len, timeZone);
} else if (!column.getType().isArray()) {
return new DefaultPrinter(len);
} else if (!column.getType().getComponentType().isPrimitive()) {
return new ObjectArrayPrinter(len);
} else {
return new PrimitiveArrayPrinter(len);
}
}
private interface ColumnPrinter {
void print(PrintStream out, Object value);
}
private static class DefaultPrinter implements ColumnPrinter {
private final int len;
private DefaultPrinter(int len) {
this.len = len;
}
@Override
public void print(PrintStream out, Object value) {
String strValue = TableTools.nullToNullString(value);
boolean isNumber = false;
if (value instanceof Number) {
isNumber = true;
}
if (strValue.length() > len) {
boolean isDouble = false;
if (value instanceof Double) {
isDouble = true;
}
if (isDouble && strValue.contains("E")) {
// sci notation getting chopped
String[] chunks = strValue.split("E");
int charsOver = strValue.length() - len;
int lastCharIndex = chunks[0].length() - charsOver;
String partOne = chunks[0].substring(0, lastCharIndex);
strValue = partOne + "E" + chunks[1];
} else if (!isNumber) {
strValue = strValue.substring(0, len - 3) + "...";
}
} else
while (strValue.length() < len) {
if (isNumber) {
strValue = " " + strValue;
} else {
strValue += " ";
}
}
out.print(strValue);
}
}
private static abstract class ArrayPrinter implements ColumnPrinter {
private final int len;
private ArrayPrinter(int len) {
this.len = len;
}
void printInternal(PrintStream out, Object value) {
String strValue = "" + value;
boolean isNumber = false;
if (value instanceof Number) {
isNumber = true;
}
if (strValue.length() > len) {
strValue = strValue.substring(0, len - 4) + "...]";
} else
while (strValue.length() < len) {
if (isNumber) {
strValue = " " + strValue;
} else {
strValue += " ";
}
}
out.print(strValue);
}
}
private static class ObjectArrayPrinter extends ArrayPrinter {
private ObjectArrayPrinter(int len) {
super(len);
}
@Override
public void print(PrintStream out, Object value) {
printInternal(out, Arrays.toString((Object[]) value));
}
}
private static class InstantPrinter extends DefaultPrinter {
private final ZoneId timeZone;
private InstantPrinter(int len, ZoneId timeZone) {
super(len);
this.timeZone = timeZone;
}
@Override
public void print(PrintStream out, Object value) {
super.print(out, value == null ? null : DateTimeUtils.formatDateTime((Instant) value, timeZone));
}
}
private static class PrimitiveArrayPrinter extends ArrayPrinter {
private PrimitiveArrayPrinter(int len) {
super(len);
}
@Override
public void print(PrintStream out, Object value) {
printInternal(out, Arrays.toString(ArrayTypeUtils.getBoxedArray(value)));
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy