use of org.knime.core.data.container.BlobSupportDataRow in project knime-core by knime.
the class AppendedRowsIterator method initNextRow.
/**
* Get next row internally.
*/
private void initNextRow() {
// reached end of table's iterator - take next
if (!m_curIterator.hasNext()) {
do {
if (m_curItIndex < m_iteratorSuppliers.length - 1) {
initNextTable();
} else {
// final end
m_nextRow = null;
// reached end of this table
return;
}
} while (!m_curIterator.hasNext());
}
// row from table
DataRow baseRow = m_curIterator.next();
m_curRowIndex++;
boolean keyHasChanged = false;
RowKey origKey = baseRow.getKey();
RowKey key = origKey;
while (m_duplicateMap.containsKey(key)) {
if (m_exec != null) {
try {
m_exec.checkCanceled();
} catch (CanceledExecutionException cee) {
throw new RuntimeCanceledExecutionException(cee);
}
}
switch(m_duplPolicy) {
case Fail:
assert false : "Duplicate checking is done in the BDT";
throw new RuntimeException("Duplicate key \"" + key + "\"");
case Skip:
if (!m_hasPrintedError) {
LOGGER.warn("Table contains duplicate entry \"" + key.toString() + "\", skipping this row. " + "Suppress further warnings.");
m_hasPrintedError = true;
}
if (!m_curIterator.hasNext()) {
// end of one table reached
// note, this causes one more call on the stack
// (but who wants to concatenate 60000 tables...)
initNextRow();
return;
}
if (m_exec != null) {
m_nrRowsSkipped++;
String message = "Skipping row " + m_curRowIndex + " (\"" + key.toString() + "\")";
if (m_totalRowCount > 0L) {
m_exec.setProgress(m_curRowIndex / (double) m_totalRowCount, message);
} else {
m_exec.setMessage(message);
}
}
// row from table
baseRow = m_curIterator.next();
m_curRowIndex++;
// stays false! rows have been skipped.
keyHasChanged = false;
origKey = baseRow.getKey();
key = origKey;
break;
case AppendSuffix:
// first time we come here
if (!keyHasChanged && m_exec != null) {
String message = "Unifying row " + m_curRowIndex + " (\"" + key.toString() + "\")";
if (m_totalRowCount > 0L) {
m_exec.setProgress(m_curRowIndex / (double) m_totalRowCount, message);
} else {
m_exec.setMessage(message);
}
}
keyHasChanged = true;
String newId = key.toString() + m_suffix;
key = new RowKey(newId);
// to do duplicate handling.
break;
default:
throw new RuntimeException("Unknown policy: " + m_duplPolicy);
}
}
switch(m_duplPolicy) {
case Fail:
// to do a efficient duplicate checking
break;
default:
m_duplicateMap.put(key, origKey);
}
if (m_exec != null) {
try {
m_exec.checkCanceled();
} catch (CanceledExecutionException cee) {
throw new RuntimeCanceledExecutionException(cee);
}
String message = "Adding row " + m_curRowIndex + " (\"" + key.toString() + "\"" + (keyHasChanged ? " uniquified)" : ")");
if (m_totalRowCount > 0L) {
m_exec.setProgress(m_curRowIndex / (double) m_totalRowCount, message);
} else {
m_exec.setMessage(message);
}
}
DataRow nextRow;
if (m_curMissingCells != null) {
// no missing cells implies the base row is complete
assert (m_curMissingCells.length + baseRow.getNumCells() == m_spec.getNumColumns());
// row enlarged by "missing" columns
DataRow filledBaseRow = new AppendedColumnRow(baseRow, m_curMissingCells);
nextRow = new ResortedCellsRow(filledBaseRow, m_curMapping);
} else {
nextRow = baseRow;
}
if (keyHasChanged) {
final boolean blobRow = (nextRow instanceof BlobSupportDataRow);
DataCell[] cells = new DataCell[nextRow.getNumCells()];
for (int i = 0; i < cells.length; i++) {
cells[i] = blobRow ? ((BlobSupportDataRow) nextRow).getRawCell(i) : nextRow.getCell(i);
}
m_nextRow = new BlobSupportDataRow(key, cells);
} else {
m_nextRow = nextRow;
}
}
use of org.knime.core.data.container.BlobSupportDataRow in project knime-core by knime.
the class BlobSupportDataCellSet method create.
/**
* Create new set containing selected cells from a {@link DataRow}. Using
* this method will check if the row is returned by a
* {@link BufferedDataTable} and will handle blobs appropriately.
*
* @param row The underlying row
* @param cols The indices of the cells to store in the set
* @return A newly created set.
* @throws NullPointerException If either argument is null.
* @throws IndexOutOfBoundsException If the indices are invalid.
*/
public static BlobSupportDataCellSet create(final DataRow row, final int[] cols) {
ArrayList<DataCell> coll = new ArrayList<DataCell>(cols.length);
for (int i = 0; i < cols.length; i++) {
DataCell c;
if (row instanceof BlobSupportDataRow) {
c = ((BlobSupportDataRow) row).getRawCell(cols[i]);
} else {
c = row.getCell(cols[i]);
}
coll.add(c);
}
return create(coll);
}
use of org.knime.core.data.container.BlobSupportDataRow in project knime-core by knime.
the class CollectionCellFactory method createSparseListCell.
/**
* Creates a new {@link ListCell} based on selected cells from a
* {@link DataRow}. This method will check if the row is returned by
* a {@link BufferedDataTable} and will handle blobs appropriately.
* Only the values that are different from the given default value are
* stored in the sparse list.
*
* @param row The underlying row
* @param cols The indices of interest.
* @param defaultElement The default element to use.
* @return A newly created {@link SparseListCell}.
* @throws NullPointerException If either argument is null.
* @throws IndexOutOfBoundsException If the indices are invalid.
*/
public static SparseListCell createSparseListCell(final DataRow row, final int[] cols, final DataCell defaultElement) {
if (row == null) {
throw new NullPointerException("row must not be null");
}
if (cols == null || cols.length < 1) {
throw new NullPointerException("cols must not be null or empty");
}
if (defaultElement == null) {
throw new NullPointerException("defaultElement must not be null");
}
final int[] idxs = new int[cols.length];
int idxIdx = 0;
final ArrayList<DataCell> coll = new ArrayList<DataCell>(cols.length);
for (int i = 0; i < cols.length; i++) {
DataCell c;
if (row instanceof BlobSupportDataRow) {
c = ((BlobSupportDataRow) row).getRawCell(cols[i]);
} else {
c = row.getCell(cols[i]);
}
// equals will unwrap the blob, if necessary
if (!defaultElement.equals(c)) {
coll.add(c);
idxs[idxIdx++] = i;
}
}
final BlobSupportDataCellList elements = new BlobSupportDataCellList(coll);
int[] elementIdxs;
if (idxIdx == idxs.length) {
// all values are unequal to the given default element
elementIdxs = idxs;
} else {
elementIdxs = Arrays.copyOf(idxs, idxIdx);
}
return new SparseListCell(cols.length, elements, elementIdxs, defaultElement);
}
use of org.knime.core.data.container.BlobSupportDataRow in project knime-core by knime.
the class ConcatenateTableFactory method addTable.
/**
* All rows of the given row input are added to a new data container. Creates a new data container if this data
* table spec differs from the previous table. This method call checks for row keys duplicates and throws a
* {@link DuplicateKeyException}.
*
* @param table the table to be added
* @param exec the execution context to possibly create a new data container
* @throws InterruptedException
* @throws IOException
* @throws DuplicateKeyException
* @throws CanceledExecutionException
*/
void addTable(final RowInput table, final ExecutionContext exec) throws InterruptedException, DuplicateKeyException, IOException, CanceledExecutionException {
// check if last container has been closed (i.e. createTable was called)
if (m_tables.size() > 0) {
if (m_tables.get(m_tables.size() - 1).isClosed()) {
throw new IllegalStateException("No more tables can be added! ConcatenateTable has already been created.");
}
}
// poll first row in order to check whether the incoming table is empty
DataRow row = table.poll();
if (row == null) {
// table is empty
if (m_ignoreEmptyTables && m_tables.size() > 0) {
m_iterationCount++;
return;
} else if (m_tables.size() == 0) {
// if this is the first table we receive and its empty, create an empty one and keep it
m_emptyTable = exec.createDataContainer(createSpec(table.getDataTableSpec(), m_addIterationColumn, false));
m_iterationCount++;
return;
}
}
// compare spec of the current table with the spec of the first table if changing specs are not tolerated
if (!m_tolerateChangingSpecs && (m_tables.size() > 0 || m_emptyTable != null)) {
if (!(m_ignoreEmptyTables && (row == null || m_emptyTable != null))) {
// don't fail if table is empty and to be ignored
// create spec for comparision -> set the most common column type for both table spec, if altered column types
// are to be tolerated
DataTableSpec tmpSpec1;
if (m_tables.size() == 0 && m_emptyTable != null) {
tmpSpec1 = createSpec(m_emptyTable.getTableSpec(), false, m_tolerateColumnTypes);
} else {
tmpSpec1 = createSpec(m_tables.get(0).getTableSpec(), false, m_tolerateColumnTypes);
}
DataTableSpec tmpSpec2 = createSpec(table.getDataTableSpec(), m_addIterationColumn, m_tolerateColumnTypes);
// fail if specs has been changed
compareSpecsAndFail(tmpSpec1, tmpSpec2);
}
}
// if table is empty and they are not to be ignored, nothing else to do -> return now
if (row == null) {
m_iterationCount++;
return;
}
// if there are too much tables -> create one new and copy the whole data
if (m_tables.size() > MAX_NUM_TABLES) {
copyTablesIntoOneTable(exec);
}
// create a new data container except the previously added has the same data table spec -> problem: if in each iteration a new row is added we
// end up with quite many data containers
BufferedDataContainer con;
DataTableSpec newTableSpec = createSpec(table.getDataTableSpec(), m_addIterationColumn, false);
if (m_tables.size() == 0) {
con = exec.createDataContainer(newTableSpec);
m_tables.add(con);
} else if (m_tables.size() > 0 && !newTableSpec.equalStructure(m_tables.get(m_tables.size() - 1).getTableSpec())) {
con = m_tables.get(m_tables.size() - 1);
con.close();
con = exec.createDataContainer(newTableSpec);
m_tables.add(con);
} else {
con = m_tables.get(m_tables.size() - 1);
}
// add rows of the table to the newly created data container
do {
exec.checkCanceled();
// change row key if desired
if (m_rowKeyCreator != null) {
// change row key
row = new BlobSupportDataRow(m_rowKeyCreator.apply(row.getKey()), row);
}
m_duplicateChecker.addKey(row.getKey().toString());
// add additional iteration column if desired
if (m_addIterationColumn) {
IntCell currIterCell = new IntCell(m_iterationCount);
row = new org.knime.core.data.append.AppendedColumnRow(row, currIterCell);
}
con.addRowToTable(row);
} while ((row = table.poll()) != null);
m_iterationCount++;
}
use of org.knime.core.data.container.BlobSupportDataRow in project knime-core by knime.
the class AutoconvertRowIterator method next.
/**
* {@inheritDoc}
*/
@Override
public DataRow next() {
final DataRow inputRow = m_iterator.next();
final DataCell toConvert = inputRow.getCell(m_colIndex);
final DataCell converted;
try {
converted = m_converter.convert(toConvert);
} catch (Exception ex) {
throw new RuntimeException("Error while auto-converting row", ex);
}
final boolean blobRow = (inputRow instanceof BlobSupportDataRow);
final DataCell[] cells = new DataCell[inputRow.getNumCells()];
for (int i = 0; i < cells.length; i++) {
if (i == m_colIndex) {
cells[i] = converted;
} else {
cells[i] = blobRow ? ((BlobSupportDataRow) inputRow).getRawCell(i) : inputRow.getCell(i);
}
}
return new BlobSupportDataRow(inputRow.getKey(), cells);
}
Aggregations