com.xxdb.data.BasicTable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dolphindb-javaapi Show documentation
Show all versions of dolphindb-javaapi Show documentation
The messaging and data conversion protocol between Java and DolphinDB server
package com.xxdb.data;
import java.io.IOException;
import java.util.*;
import com.xxdb.compression.VectorDecompressor;
import com.xxdb.io.ExtendedDataInput;
import com.xxdb.io.ExtendedDataOutput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Corresponds to DolphinDB table object
*
*/
public class BasicTable extends AbstractEntity implements Table{
private List columns = new ArrayList();
private List colNames = new ArrayList();
private Map colNamesIndex = new HashMap();
private int[] colCompresses = null;
private static final Logger log = LoggerFactory.getLogger(BasicTable.class);
public BasicTable(ExtendedDataInput in) throws IOException{
int rows = in.readInt();
int cols = in.readInt();
String tableName = in.readString();
//read column names
for(int i=0; i>8;
int type = flag & 0xff;
boolean extended = type >= 128;
if(type >= 128)
type -= 128;
DATA_FORM df = DATA_FORM.values()[form];
DATA_TYPE dt = DATA_TYPE.valueOf(type);
if(df != DATA_FORM.DF_VECTOR)
throw new IOException("Invalid form for column [" + colNames.get(i) + "] for table " + tableName);
Vector vector;
if(dt == DATA_TYPE.DT_SYMBOL && extended){
if(collection == null)
collection = new SymbolBaseCollection();
vector = new BasicSymbolVector(df, in, collection);
} else if (dt == DATA_TYPE.DT_COMPRESS) {
if(decompressor == null)
decompressor = new VectorDecompressor();
vector = decompressor.decompress(BasicEntityFactory.instance(), in, extended, true);
}
else{
vector = (Vector)BasicEntityFactory.instance().createEntity(df, dt, in, extended);
}
if(vector.rows() != rows && vector.rows()!= 1)
throw new IOException("The number of rows for column " + colNames.get(i) + " is not consistent with other columns");
columns.add(vector);
}
if(collection != null)
collection.clear();
}
public BasicTable(final List colNames, final List cols) {
if(colNames.size() != cols.size()){
throw new Error("The length of column name and column data is unequal.");
}
int rowsCount = cols.get(0).rows();
for (int i=0;i colNames) {
this.colNames.clear();
colNamesIndex.clear();
for (String name : colNames){
this.colNames.add(name);
colNamesIndex.put(name, colNamesIndex.size());
}
}
public void setColumns (final List cols) {
columns.clear();
// this is a shallow copy!
for (Vector vector : cols)
columns.add(vector);
}
@Override
public DATA_CATEGORY getDataCategory() {
return DATA_CATEGORY.MIXED;
}
@Override
public DATA_TYPE getDataType() {
return DATA_TYPE.DT_DICTIONARY;
}
@Override
public DATA_FORM getDataForm() {
return DATA_FORM.DF_TABLE;
}
@Override
public int rows() {
if(columns()<=0)
return 0;
else
return columns.get(0).rows();
}
@Override
public int columns() {
return columns.size();
}
@Override
public Vector getColumn(int index) {
return columns.get(index);
}
@Override
public Vector getColumn(String name) {
Integer index = colNamesIndex.get(name);
if(index == null)
return null;
else
return getColumn(index);
}
public String getColumnName(int index){
return colNames.get(index);
}
public String getString(){
int rows = Math.min(Utils.DISPLAY_ROWS,rows());
int strColMaxWidth = Utils.DISPLAY_WIDTH/Math.min(columns(),Utils.DISPLAY_COLS)+5;
int length=0;
int curCol=0;
int maxColWidth;
StringBuilder[] list = new StringBuilder[rows+1];
StringBuilder separator = new StringBuilder();
String[] listTmp = new String[rows+1];
int i,curSize;
for(i=0; imaxColWidth)
maxColWidth=listTmp[i+1].length();
}
if(maxColWidth>strColMaxWidth && getColumn(curCol).getDataCategory()==DATA_CATEGORY.LITERAL)
maxColWidth=strColMaxWidth;
if((int)listTmp[0].length()>maxColWidth)
maxColWidth=Math.min(strColMaxWidth,(int)listTmp[0].length());
if(length+maxColWidth>Utils.DISPLAY_WIDTH && curCol+13)
list[i].append(listTmp[i].substring(0,maxColWidth-3));
list[i].append("...");
separator.append("---");
}
}
length+=maxColWidth;
curCol++;
}
if(curCol= 65)
jsonStr.append(columns.get(i).getJsonString(rowIndex));
else
jsonStr.append(((Scalar) columns.get(i).get(rowIndex)).getJsonString());
if(i< colNames.size()-1)
jsonStr.append(",");
}
jsonStr.delete(jsonStr.length()-1,jsonStr.length()-1);
jsonStr.append("}");
}
}catch (Exception e){
log.error(e.getMessage());
e.printStackTrace();
}
return jsonStr.toString();
}
public void write(ExtendedDataOutput out) throws IOException{
int flag = (DATA_FORM.DF_TABLE.ordinal() << 8) + getDataType().getValue();
out.writeShort(flag);
out.writeInt(rows());
out.writeInt(columns());
out.writeString(""); //table name
for(String colName : colNames)
out.writeString(colName);
SymbolBaseCollection collection = null;
for(Vector vector : columns){
if(vector instanceof BasicSymbolVector){
if(collection == null)
collection = new SymbolBaseCollection();
((BasicSymbolVector)vector).write(out, collection);
}
else
vector.write(out);
}
}
@Override
public void writeCompressed(ExtendedDataOutput output) throws IOException {
short flag = (short) (Entity.DATA_FORM.DF_TABLE.ordinal() << 8 | 8 & 0xff); //8: table type TODO: add table type
output.writeShort(flag);
int rows = this.rows();
int cols = this.columns();
output.writeInt(rows);
output.writeInt(cols);
output.writeString(""); //table name
for (int i = 0; i < cols; i++) {
output.writeString(this.getColumnName(i));
}
for (int i = 0; i < cols; i++) {
AbstractVector v = (AbstractVector) this.getColumn(i);
if(v.getDataType() == DATA_TYPE.DT_SYMBOL)
v.write(output);
else {
if(colCompresses !=null){
v.setCompressedMethod(colCompresses[i]);
}
v.writeCompressed(output);
}
}
}
public BasicTable combine(BasicTable table){
List newCol = new ArrayList<>();
for (int i=0; i< this.columns();i++) {
newCol.add(this.getColumn(i).combine(table.getColumn(i)));
}
return new BasicTable(this.colNames,newCol);
}
public Table getSubTable(int[] indices){
int colCount = columns.size();
List cols = new ArrayList(colCount);
for(int i=0; i cols = new ArrayList<>();
for (int i = 0; i < colCount; i++){
int index = startRow;
int[] indices = new int[endRow - startRow+1];
for (int j = 0; j < indices.length; j++){
indices[j] = index;
index++;
}
cols.add(columns.get(i).getSubVector(indices));
}
return new BasicTable(colNames, cols);
}
@Override
public void addColumn(String colName, Vector col) {
if (Objects.isNull(colName) || Objects.isNull(col))
throw new RuntimeException("The param 'colName' or 'col' in table cannot be null.");
if (colName.isEmpty())
throw new RuntimeException("The param 'colName' cannot be empty.");
if (colNames.contains(colName))
throw new RuntimeException("The table already contains column '" + colName + "'.");
if (Objects.nonNull(this.columns) && Objects.nonNull(this.columns.get(0)) && this.getColumn(0).rows() != col.rows())
throw new RuntimeException("The length of column " + colName + " must be the same as the first column length: " + this.getColumn(0).rows() +".");
colNames.add(colName);
colNamesIndex.put(colName, colNamesIndex.size());
columns.add(col);
}
/**
* replace a specific colName.
* @param originalColName
* @param newColName
*/
public void replaceColName(String originalColName, String newColName) {
if (Utils.isEmpty(originalColName) || Utils.isEmpty(newColName))
throw new RuntimeException("The param 'originalColName' or 'newColName' cannot be null or empty.");
if (this.colNames.contains(newColName))
throw new RuntimeException("The newColName '" + newColName +"' already exists in table. Column names cannot be duplicated.");
if (this.colNames.contains(originalColName)) {
int index = colNames.indexOf(originalColName);
colNames.set(index, newColName);
} else {
throw new RuntimeException("The param originalColName '" + originalColName +"' does not exist in table.");
}
}
/**
* Replace modifies the specified column.
* @param colName
* @param col
*/
@Override
public void replaceColumn(String colName, Vector col) {
if (Objects.isNull(colName) || Objects.isNull(col))
throw new RuntimeException("The param 'colName' or 'col' in table cannot be null.");
if (!colNames.contains(colName))
throw new RuntimeException("The column '" + colName + "' to be replaced doesn't exist in the table.");
if (Objects.nonNull(this.columns) && Objects.nonNull(this.columns.get(0)) && this.getColumn(0).rows() != col.rows())
throw new RuntimeException("The length of column " + colName + " must be the same as the first column length: " + this.getColumn(0).rows() +".");
int index = colNames.indexOf(colName);
columns.set(index, col);
}
}