use of org.knime.core.node.workflow.LoopStartNodeTerminator in project knime-core by knime.
the class LoopEndJoinNodeModel method execute.
/**
* {@inheritDoc}
*/
@Override
protected BufferedDataTable[] execute(final BufferedDataTable[] inData, final ExecutionContext exec) throws Exception {
boolean hasSameRowsInEachIteration = m_configuration.hasSameRowsInEachIteration();
LoopStartNode startNode = getLoopStartNode();
if (!(startNode instanceof LoopStartNodeTerminator)) {
throw new IllegalStateException("Loop end is not connected" + " to matching/corresponding loop start node. You" + " are trying to create an infinite loop!");
}
boolean continueLoop = !((LoopStartNodeTerminator) startNode).terminateLoop();
if (m_currentAppendTable == null) {
m_currentAppendTable = copy(inData[0], false, exec);
} else if (hasSameRowsInEachIteration) {
boolean isCacheNew = m_iteration % 50 == 0;
double amount = isCacheNew ? (1.0 / 3.0) : (1.0 / 2.0);
ExecutionContext copyCtx = exec.createSubExecutionContext(amount);
ExecutionContext joinCtx = exec.createSubExecutionContext(amount);
exec.setProgress("Copying input");
BufferedDataTable t = copy(inData[0], true, copyCtx);
copyCtx.setProgress(1.0);
exec.setProgress("Joining with previous input");
m_currentAppendTable = exec.createJoinedTable(m_currentAppendTable, t, joinCtx);
joinCtx.setProgress(1.0);
if (isCacheNew) {
exec.setProgress("Caching intermediate results (iteration " + m_iteration + ")");
ExecutionContext ctx = exec.createSubExecutionContext(amount);
// copy the whole table every 50 columns (avoids wrapping to much individual tables)
// In this case the whole table is copied and column names DON'T need to be made unique (bugfix 6544)
m_currentAppendTable = copy(m_currentAppendTable, m_appendIterSuffixForBackwardComp, ctx);
ctx.setProgress(1.0);
}
} else {
Joiner2Settings settings = new Joiner2Settings();
settings.setCompositionMode(CompositionMode.MatchAll);
settings.setDuplicateColumnSuffix(" (Iter #" + m_iteration + ")");
settings.setDuplicateHandling(DuplicateHandling.AppendSuffix);
settings.setEnableHiLite(false);
// joining on RowIDs, this should not generate new row IDs but
// only fill missing rows in either table
settings.setJoinMode(JoinMode.FullOuterJoin);
settings.setLeftIncludeAll(true);
settings.setRightIncludeAll(true);
// TODO to be replaced by Joiner2Settings.ROW_KEY_IDENTIFIER
// once that is public
settings.setLeftJoinColumns(new String[] { "$RowID$" });
settings.setRightJoinColumns(new String[] { "$RowID$" });
BufferedDataTable left = m_currentAppendTable;
BufferedDataTable right = copy(inData[0], true, exec.createSubExecutionContext(0.1));
Joiner joiner = new Joiner(left.getDataTableSpec(), right.getDataTableSpec(), settings);
m_currentAppendTable = joiner.computeJoinTable(left, right, exec.createSubExecutionContext(0.9));
}
m_iteration += 1;
if (continueLoop) {
super.continueLoop();
return null;
} else {
return new BufferedDataTable[] { m_currentAppendTable };
}
}
use of org.knime.core.node.workflow.LoopStartNodeTerminator in project knime-core by knime.
the class LoopEnd2NodeModel method execute.
/**
* {@inheritDoc}
*/
@Override
protected BufferedDataTable[] execute(final BufferedDataTable[] inData, final ExecutionContext exec) throws Exception {
if (!(this.getLoopStartNode() instanceof LoopStartNodeTerminator)) {
throw new IllegalStateException("Loop end is not connected" + " to matching/corresponding loop start node. You" + "are trying to create an infinite loop!");
}
if (m_tableFactories[0] == null) {
// first iteration -> create table factories
Optional<Function<RowKey, RowKey>> rowKeyFunc1;
Optional<Function<RowKey, RowKey>> rowKeyFunc2;
switch(m_settings.rowKeyPolicy()) {
case APPEND_SUFFIX:
rowKeyFunc1 = Optional.of(k -> {
return new RowKey(k.toString() + "#" + (m_iteration));
});
rowKeyFunc2 = Optional.of(k -> {
return new RowKey(k.toString() + "#" + (m_iteration));
});
break;
case GENERATE_NEW:
rowKeyFunc1 = Optional.of(k -> {
return new RowKey("Row" + (m_count1++));
});
rowKeyFunc2 = Optional.of(k -> {
return new RowKey("Row" + (m_count2++));
});
break;
case UNMODIFIED:
default:
rowKeyFunc1 = Optional.empty();
rowKeyFunc2 = Optional.empty();
}
m_tableFactories[0] = new ConcatenateTableFactory(m_settings.ignoreEmptyTables1(), m_settings.tolerateColumnTypes1(), m_settings.addIterationColumn(), m_settings.tolerateChangingTableSpecs1(), rowKeyFunc1);
m_tableFactories[1] = new ConcatenateTableFactory(m_settings.ignoreEmptyTables2(), m_settings.tolerateColumnTypes2(), m_settings.addIterationColumn(), m_settings.tolerateChangingTableSpecs2(), rowKeyFunc2);
}
// add tables to factories
m_tableFactories[0].addTable(inData[0], exec);
m_tableFactories[1].addTable(inData[1], exec);
final boolean terminateLoop = ((LoopStartNodeTerminator) this.getLoopStartNode()).terminateLoop();
if (terminateLoop) {
m_iteration = 0;
m_count1 = 0;
m_count2 = 0;
BufferedDataTable[] outTables = new BufferedDataTable[2];
outTables[0] = m_tableFactories[0].createTable(exec);
outTables[1] = m_tableFactories[1].createTable(exec);
return outTables;
} else {
continueLoop();
m_iteration++;
return new BufferedDataTable[2];
}
}
use of org.knime.core.node.workflow.LoopStartNodeTerminator in project knime-core by knime.
the class LoopEndConditionNodeModel method execute.
/**
* {@inheritDoc}
*/
@Override
protected BufferedDataTable[] execute(final BufferedDataTable[] inData, final ExecutionContext exec) throws Exception {
int count = peekFlowVariableInt("currentIteration");
exec.setMessage("Iteration " + count);
DataTableSpec spec1 = createSpec1(inData[0].getDataTableSpec());
if (m_collectContainer == null) {
assert m_variableContainer == null;
m_startTime = System.currentTimeMillis();
// first time we are getting to this: open container
m_collectContainer = exec.createDataContainer(spec1);
m_variableContainer = exec.createDataContainer(createSpec2());
} else if (!spec1.equalStructure(m_collectContainer.getTableSpec())) {
DataTableSpec predSpec = m_collectContainer.getTableSpec();
StringBuilder error = new StringBuilder("Input table's structure differs from reference " + "(first iteration) table: ");
if (spec1.getNumColumns() != predSpec.getNumColumns()) {
error.append("different column counts ");
error.append(spec1.getNumColumns());
error.append(" vs. ").append(predSpec.getNumColumns());
} else {
for (int i = 0; i < spec1.getNumColumns(); i++) {
DataColumnSpec inCol = spec1.getColumnSpec(i);
DataColumnSpec predCol = predSpec.getColumnSpec(i);
if (!inCol.equalStructure(predCol)) {
error.append("Column ").append(i).append(" [");
error.append(inCol).append("] vs. [");
error.append(predCol).append("]");
}
}
}
throw new IllegalArgumentException(error.toString());
}
RowKey rk = new RowKey("Iteration " + count);
if (m_settings.variableType() == Type.DOUBLE) {
m_variableContainer.addRowToTable(new DefaultRow(rk, new DoubleCell(peekFlowVariableDouble(m_settings.variableName()))));
} else if (m_settings.variableType() == Type.INTEGER) {
m_variableContainer.addRowToTable(new DefaultRow(rk, new IntCell(peekFlowVariableInt(m_settings.variableName()))));
} else {
m_variableContainer.addRowToTable(new DefaultRow(rk, new StringCell(peekFlowVariableString(m_settings.variableName()))));
}
LoopStartNode lsn = getLoopStartNode();
boolean stop = checkCondition() || ((lsn instanceof LoopStartNodeTerminator) && ((LoopStartNodeTerminator) lsn).terminateLoop());
if ((m_settings.addLastRows() && !m_settings.addLastRowsOnly()) || ((stop == m_settings.addLastRows()) && (stop == m_settings.addLastRowsOnly()))) {
exec.setMessage("Collecting rows from current iteration");
int k = 0;
final double max = inData[0].size();
IntCell currIterCell = new IntCell(count);
for (DataRow row : inData[0]) {
exec.checkCanceled();
if (k++ % 10 == 0) {
exec.setProgress(k / max);
}
DataRow newRow = new DefaultRow(new RowKey(row.getKey() + "#" + count), row);
if (m_settings.addIterationColumn()) {
newRow = new AppendedColumnRow(newRow, currIterCell);
}
m_collectContainer.addRowToTable(newRow);
}
}
if (stop) {
m_collectContainer.close();
m_variableContainer.close();
BufferedDataTable out1 = m_collectContainer.getTable();
BufferedDataTable out2 = m_variableContainer.getTable();
LOGGER.debug("Total loop execution time: " + (System.currentTimeMillis() - m_startTime) + "ms");
m_startTime = 0;
return new BufferedDataTable[] { out1, out2 };
} else {
continueLoop();
return new BufferedDataTable[2];
}
}
use of org.knime.core.node.workflow.LoopStartNodeTerminator in project knime-core by knime.
the class LoopEndNodeModel method execute.
/**
* {@inheritDoc}
*/
@Override
protected BufferedDataTable[] execute(final BufferedDataTable[] inData, final ExecutionContext exec) throws Exception {
if (!(this.getLoopStartNode() instanceof LoopStartNodeTerminator)) {
throw new IllegalStateException("Loop End is not connected" + " to matching/corresponding Loop Start node. You" + " are trying to create an infinite loop!");
}
if (m_tableFactory == null) {
// first time we get here: create table factory
Optional<Function<RowKey, RowKey>> rowKeyFunc;
switch(m_settings.rowKeyPolicy()) {
case APPEND_SUFFIX:
rowKeyFunc = Optional.of(k -> {
return new RowKey(k.toString() + "#" + (m_iteration));
});
break;
case GENERATE_NEW:
rowKeyFunc = Optional.of(k -> {
return new RowKey("Row" + (m_count++));
});
break;
case UNMODIFIED:
default:
rowKeyFunc = Optional.empty();
}
m_tableFactory = new ConcatenateTableFactory(m_settings.ignoreEmptyTables(), m_settings.tolerateColumnTypes(), m_settings.addIterationColumn(), m_settings.tolerateChangingTableSpecs(), rowKeyFunc);
m_startTime = System.currentTimeMillis();
}
m_tableFactory.addTable(inData[0], exec);
boolean terminateLoop = ((LoopStartNodeTerminator) this.getLoopStartNode()).terminateLoop();
if (terminateLoop) {
LOGGER.debug("Total loop execution time: " + (System.currentTimeMillis() - m_startTime) + "ms");
m_startTime = 0;
m_iteration = 0;
m_count = 0;
return new BufferedDataTable[] { m_tableFactory.createTable(exec) };
} else {
m_iteration++;
continueLoop();
return new BufferedDataTable[1];
}
}
use of org.knime.core.node.workflow.LoopStartNodeTerminator in project knime-core by knime.
the class VariableLoopEndNodeModel method execute.
/**
* {@inheritDoc}
*/
@Override
protected PortObject[] execute(final PortObject[] inObjects, final ExecutionContext exec) throws Exception {
// check for loop start node.
if (!(this.getLoopStartNode() instanceof LoopStartNodeTerminator)) {
throw new IllegalStateException("Loop End is not connected" + " to matching/corresponding Loop Start node. You" + " are trying to create an infinite loop!");
}
DataTableSpec amendedSpec = createDataTableSpec();
if (m_resultContainer == null) {
// first time we are getting to this: open container
m_startTime = System.currentTimeMillis();
m_resultContainer = exec.createDataContainer(amendedSpec);
// if initially created data table spec and current spec differ, fail
} else if (!amendedSpec.equalStructure(m_resultContainer.getTableSpec())) {
DataTableSpec predSpec = m_resultContainer.getTableSpec();
StringBuilder error = new StringBuilder("Output table's structure differs from reference " + "(first iteration) table: ");
if (amendedSpec.getNumColumns() != predSpec.getNumColumns()) {
error.append("different column counts ");
error.append(amendedSpec.getNumColumns());
error.append(" vs. ").append(predSpec.getNumColumns());
} else {
for (int i = 0; i < amendedSpec.getNumColumns(); i++) {
DataColumnSpec inCol = amendedSpec.getColumnSpec(i);
DataColumnSpec predCol = predSpec.getColumnSpec(i);
if (!inCol.equalStructure(predCol)) {
error.append("Column ").append(i).append(" [");
error.append(inCol).append("] vs. [");
error.append(predCol).append("]");
}
}
}
error.append(". Have the input variables changed in number, name or type?");
throw new IllegalArgumentException(error.toString());
}
// after all data table checks we are fine now and can add a single row
// containing the values of the flow variables
m_resultContainer.addRowToTable(createNewRow());
boolean terminateLoop = ((LoopStartNodeTerminator) this.getLoopStartNode()).terminateLoop();
if (terminateLoop) {
// this was the last iteration - close container and continue
m_resultContainer.close();
BufferedDataTable outTable = m_resultContainer.getTable();
m_resultContainer.close();
m_resultContainer = null;
m_count = 0;
LOGGER.debug("Total loop execution time: " + (System.currentTimeMillis() - m_startTime) + "ms");
m_startTime = 0;
return new BufferedDataTable[] { outTable };
} else {
continueLoop();
m_count++;
return new BufferedDataTable[1];
}
}
Aggregations