nom.tam.util.ColumnTable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nom-tam-fits Show documentation
Show all versions of nom-tam-fits Show documentation
Java library for reading and writing FITS files. FITS, the Flexible Image Transport System, is the format commonly used in the archiving and transport of astronomical data.
package nom.tam.util;
/*
* #%L
* nom.tam FITS library
* %%
* Copyright (C) 2004 - 2015 nom-tam-fits
* %%
* This is free and unencumbered software released into the public domain.
*
* Anyone is free to copy, modify, publish, use, compile, sell, or
* distribute this software, either in source code form or as a compiled
* binary, for any purpose, commercial or non-commercial, and by any
* means.
*
* In jurisdictions that recognize copyright laws, the author or authors
* of this software dedicate any and all copyright interest in the
* software to the public domain. We make this dedication for the benefit
* of the public at large and to the detriment of our heirs and
* successors. We intend this dedication to be an overt act of
* relinquishment in perpetuity of all present and future rights to this
* software under copyright law.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
* #L%
*/
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import nom.tam.util.type.PrimitiveType;
import nom.tam.util.type.PrimitiveTypeHandler;
import nom.tam.util.type.PrimitiveTypes;
/**
* A data table is conventionally considered to consist of rows and columns,
* where the structure within each column is constant, but different columns may
* have different structures. I.e., structurally columns may differ but rows are
* identical. Typically tabular data is usually stored in row order which can
* make it extremely difficult to access efficiently using Java. This class
* provides efficient access to data which is stored in row order and allows
* users to get and set the elements of the table. The table can consist only of
* arrays of primitive types. Data stored in column order can be efficiently
* read and written using the BufferedDataXputStream classes. The table is
* represented entirely as a set of one-dimensional primitive arrays. For a
* given column, a row consists of some number of contiguous elements of the
* array. Each column is required to have the same number of rows. Information
* regarding the dimensionality of columns and possible data pointers is
* retained for use by clients which can understand them.
*/
public class ColumnTable implements DataTable {
private static final int MAX_COLUMN_INDEXES = 256;
private static final int MAX_TYPE_VALUE = MAX_COLUMN_INDEXES;
private interface PointerAccess {
void set(ColumnTable> table, X array);
X get(ColumnTable> table);
void write(ColumnTable> table, ArrayDataOutput os, int index, int arrOffset, int size) throws IOException;
void read(ColumnTable> table, ArrayDataInput is, int index, int arrOffset, int size) throws IOException;
}
private static final Map, PointerAccess>> POINTER_ACCESSORS;
private static final PointerAccess>[] POINTER_ACCESSORS_BY_TYPE = new PointerAccess>[MAX_TYPE_VALUE];
static {
POINTER_ACCESSORS_BY_TYPE[PrimitiveTypes.BYTE.type()] = new PointerAccess() {
@Override
public byte[][] get(ColumnTable> table) {
return table.bytePointers;
}
@Override
public void set(ColumnTable> table, byte[][] array) {
table.bytePointers = array;
}
@Override
public void write(ColumnTable> table, ArrayDataOutput os, int index, int arrOffset, int size) throws IOException {
os.write(table.bytePointers[index], arrOffset, size);
}
@Override
@SuppressFBWarnings(value = "RR_NOT_CHECKED", justification = "this read will never return less than the requested length")
public void read(ColumnTable> table, ArrayDataInput is, int index, int arrOffset, int size) throws IOException {
is.read(table.bytePointers[index], arrOffset, size);
}
};
POINTER_ACCESSORS_BY_TYPE[PrimitiveTypes.BOOLEAN.type()] = new PointerAccess() {
@Override
public boolean[][] get(ColumnTable> table) {
return table.booleanPointers;
}
@Override
public void set(ColumnTable> table, boolean[][] array) {
table.booleanPointers = array;
}
@Override
public void write(ColumnTable> table, ArrayDataOutput os, int index, int arrOffset, int size) throws IOException {
os.write(table.booleanPointers[index], arrOffset, size);
}
@Override
public void read(ColumnTable> table, ArrayDataInput is, int index, int arrOffset, int size) throws IOException {
is.read(table.booleanPointers[index], arrOffset, size);
}
};
POINTER_ACCESSORS_BY_TYPE[PrimitiveTypes.SHORT.type()] = new PointerAccess() {
@Override
public short[][] get(ColumnTable> table) {
return table.shortPointers;
}
@Override
public void set(ColumnTable> table, short[][] array) {
table.shortPointers = array;
}
@Override
public void write(ColumnTable> table, ArrayDataOutput os, int index, int arrOffset, int size) throws IOException {
os.write(table.shortPointers[index], arrOffset, size);
}
@Override
public void read(ColumnTable> table, ArrayDataInput is, int index, int arrOffset, int size) throws IOException {
is.read(table.shortPointers[index], arrOffset, size);
}
};
POINTER_ACCESSORS_BY_TYPE[PrimitiveTypes.CHAR.type()] = new PointerAccess() {
@Override
public char[][] get(ColumnTable> table) {
return table.charPointers;
}
@Override
public void set(ColumnTable> table, char[][] array) {
table.charPointers = array;
}
@Override
public void write(ColumnTable> table, ArrayDataOutput os, int index, int arrOffset, int size) throws IOException {
os.write(table.charPointers[index], arrOffset, size);
}
@Override
@SuppressFBWarnings(value = "RR_NOT_CHECKED", justification = "this read will never return less than the requested length")
public void read(ColumnTable> table, ArrayDataInput is, int index, int arrOffset, int size) throws IOException {
is.read(table.charPointers[index], arrOffset, size);
}
};
POINTER_ACCESSORS_BY_TYPE[PrimitiveTypes.INT.type()] = new PointerAccess() {
@Override
public int[][] get(ColumnTable> table) {
return table.intPointers;
}
@Override
public void set(ColumnTable> table, int[][] array) {
table.intPointers = array;
}
@Override
public void write(ColumnTable> table, ArrayDataOutput os, int index, int arrOffset, int size) throws IOException {
os.write(table.intPointers[index], arrOffset, size);
}
@Override
public void read(ColumnTable> table, ArrayDataInput is, int index, int arrOffset, int size) throws IOException {
is.read(table.intPointers[index], arrOffset, size);
}
};
POINTER_ACCESSORS_BY_TYPE[PrimitiveTypes.LONG.type()] = new PointerAccess() {
@Override
public long[][] get(ColumnTable> table) {
return table.longPointers;
}
@Override
public void set(ColumnTable> table, long[][] array) {
table.longPointers = array;
}
@Override
public void write(ColumnTable> table, ArrayDataOutput os, int index, int arrOffset, int size) throws IOException {
os.write(table.longPointers[index], arrOffset, size);
}
@Override
public void read(ColumnTable> table, ArrayDataInput is, int index, int arrOffset, int size) throws IOException {
is.read(table.longPointers[index], arrOffset, size);
}
};
POINTER_ACCESSORS_BY_TYPE[PrimitiveTypes.FLOAT.type()] = new PointerAccess() {
@Override
public float[][] get(ColumnTable> table) {
return table.floatPointers;
}
@Override
public void set(ColumnTable> table, float[][] array) {
table.floatPointers = array;
}
@Override
public void write(ColumnTable> table, ArrayDataOutput os, int index, int arrOffset, int size) throws IOException {
os.write(table.floatPointers[index], arrOffset, size);
}
@Override
public void read(ColumnTable> table, ArrayDataInput is, int index, int arrOffset, int size) throws IOException {
is.read(table.floatPointers[index], arrOffset, size);
}
};
POINTER_ACCESSORS_BY_TYPE[PrimitiveTypes.DOUBLE.type()] = new PointerAccess() {
@Override
public double[][] get(ColumnTable> table) {
return table.doublePointers;
}
@Override
public void set(ColumnTable> table, double[][] array) {
table.doublePointers = array;
}
@Override
public void write(ColumnTable> table, ArrayDataOutput os, int index, int arrOffset, int size) throws IOException {
os.write(table.doublePointers[index], arrOffset, size);
}
@Override
public void read(ColumnTable> table, ArrayDataInput is, int index, int arrOffset, int size) throws IOException {
is.read(table.doublePointers[index], arrOffset, size);
}
};
Map, PointerAccess>> pointerAccess = new HashMap, PointerAccess>>();
pointerAccess.put(PrimitiveTypes.BYTE, POINTER_ACCESSORS_BY_TYPE[PrimitiveTypes.BYTE.type()]);
pointerAccess.put(PrimitiveTypes.BOOLEAN, POINTER_ACCESSORS_BY_TYPE[PrimitiveTypes.BOOLEAN.type()]);
pointerAccess.put(PrimitiveTypes.CHAR, POINTER_ACCESSORS_BY_TYPE[PrimitiveTypes.CHAR.type()]);
pointerAccess.put(PrimitiveTypes.SHORT, POINTER_ACCESSORS_BY_TYPE[PrimitiveTypes.SHORT.type()]);
pointerAccess.put(PrimitiveTypes.INT, POINTER_ACCESSORS_BY_TYPE[PrimitiveTypes.INT.type()]);
pointerAccess.put(PrimitiveTypes.LONG, POINTER_ACCESSORS_BY_TYPE[PrimitiveTypes.LONG.type()]);
pointerAccess.put(PrimitiveTypes.FLOAT, POINTER_ACCESSORS_BY_TYPE[PrimitiveTypes.FLOAT.type()]);
pointerAccess.put(PrimitiveTypes.DOUBLE, POINTER_ACCESSORS_BY_TYPE[PrimitiveTypes.DOUBLE.type()]);
POINTER_ACCESSORS = Collections.unmodifiableMap(pointerAccess);
}
/** The columns to be read/written */
private Object[] arrays;
/** The number of elements in a row for each column */
private int[] sizes;
/** The number of rows */
private int nrow;
/**
* The base type of each row (using the second character of the [x class
* names of the arrays.
*/
private char[] types;
private Class>[] bases;
// The following arrays are used to avoid having to check
// casts during the I/O loops.
// They point to elements of arrays.
private byte[][] bytePointers;
private short[][] shortPointers;
private int[][] intPointers;
private long[][] longPointers;
private float[][] floatPointers;
private double[][] doublePointers;
private char[][] charPointers;
private boolean[][] booleanPointers;
/**
* Allow the client to provide opaque data.
*/
private T extraState;
/**
* Create the object after checking consistency.
*
* @param arrays
* An array of one-d primitive arrays.
* @param sizes
* The number of elements in each row for the corresponding
* column
* @throws TableException
* if the structure of the columns is not consistent
*/
public ColumnTable(Object[] arrays, int[] sizes) throws TableException {
setup(arrays, sizes);
}
/**
* Add a column .
*
* @param newColumn
* the column to add.
* @param size
* size for the column
* @throws TableException
* if the structure of the new column does not fit the structure
* of the rows/columns
*/
public void addColumn(Object newColumn, int size) throws TableException {
String classname = newColumn.getClass().getName();
this.nrow = checkColumnConsistency(newColumn, classname, this.nrow, size);
int ncol = this.arrays.length;
Object[] newArrays = new Object[ncol + 1];
int[] newSizes = new int[ncol + 1];
Class>[] newBases = new Class[ncol + 1];
char[] newTypes = new char[ncol + 1];
System.arraycopy(this.arrays, 0, newArrays, 0, ncol);
System.arraycopy(this.sizes, 0, newSizes, 0, ncol);
System.arraycopy(this.bases, 0, newBases, 0, ncol);
System.arraycopy(this.types, 0, newTypes, 0, ncol);
this.arrays = newArrays;
this.sizes = newSizes;
this.bases = newBases;
this.types = newTypes;
this.arrays[ncol] = newColumn;
this.sizes[ncol] = size;
this.bases[ncol] = ArrayFuncs.getBaseClass(newColumn);
this.types[ncol] = classname.charAt(1);
addPointer(newColumn);
}
/**
* Add a pointer in the pointer lists.
*
* @param data
* data pointer to add
* @throws TableException
* if the structure of the specified array does not fit the
* structure of the rows/columns
*/
protected void addPointer(Object data) throws TableException {
PointerAccess
© 2015 - 2025 Weber Informatics LLC | Privacy Policy