use of org.knime.core.data.collection.BlobSupportDataCellIterator in project knime-core by knime.
the class SplitCellFactory method getCells.
/**
* {@inheritDoc}
*/
@Override
public DataCell[] getCells(final DataRow row) {
DataCell inCell = row.getCell(m_colIndex);
DataCell[] result = new DataCell[m_colSpecs.length];
Arrays.fill(result, DataType.getMissingCell());
if (inCell.isMissing()) {
if (m_warnMessage == null) {
m_warnMessage = "Some rows contain missing values";
}
return result;
}
CollectionDataValue v = (CollectionDataValue) inCell;
Iterator<DataCell> it = v.iterator();
for (int i = 0; i < m_colSpecs.length && it.hasNext(); i++) {
DataCell next;
DataType type;
if (it instanceof BlobSupportDataCellIterator) {
next = ((BlobSupportDataCellIterator) it).nextWithBlobSupport();
if (next instanceof BlobWrapperDataCell) {
// try to not access the cell (will get deserialized)
BlobWrapperDataCell bw = (BlobWrapperDataCell) next;
type = DataType.getType(bw.getBlobClass());
} else {
type = next.getType();
}
} else {
next = it.next();
type = next.getType();
}
if (m_commonTypes[i] == null) {
m_commonTypes[i] = type;
} else {
m_commonTypes[i] = DataType.getCommonSuperType(m_commonTypes[i], type);
}
result[i] = next;
}
if (it.hasNext()) {
m_warnMessage = "At least one row had more elements than " + "specified; row was truncated.";
}
m_domainCreator.updateDomain(new DefaultRow(row.getKey(), result));
return result;
}
use of org.knime.core.data.collection.BlobSupportDataCellIterator in project knime-core by knime.
the class Buffer method handleIncomingBlob.
private DataCell handleIncomingBlob(final DataCell cell, final int col, final int totalColCount, final boolean copyForVersionHop, final boolean forceCopyOfBlobsArg) throws IOException {
if (!(m_outputFormat instanceof DefaultTableStoreFormat)) {
return cell;
}
// whether the content of the argument row needs to be copied
// into a new BlobSupportDataRow (will do that when either this
// flag is true or cellCopies != null)
boolean isWrapperCell = cell instanceof BlobWrapperDataCell;
BlobAddress ad;
final CellClassInfo cl;
BlobWrapperDataCell wc;
if (isWrapperCell) {
wc = (BlobWrapperDataCell) cell;
ad = wc.getAddress();
cl = wc.getBlobClassInfo();
} else if (cell instanceof BlobDataCell) {
wc = null;
cl = CellClassInfo.get(cell);
ad = ((BlobDataCell) cell).getBlobAddress();
} else if (cell instanceof CellCollection) {
CellCollection cdv = (CellCollection) cell;
if (cdv.containsBlobWrapperCells()) {
Iterator<DataCell> it = cdv.iterator();
if (!(it instanceof BlobSupportDataCellIterator)) {
LOGGER.coding("(Collection) DataCell of class \"" + cell.getClass().getSimpleName() + "\" contains Blobs, but does not " + "return an iterator supporting those " + "(expected " + BlobSupportDataCellIterator.class.getName() + ", got " + it.getClass().getName() + ")");
}
while (it.hasNext()) {
DataCell n = it instanceof BlobSupportDataCellIterator ? ((BlobSupportDataCellIterator) it).nextWithBlobSupport() : it.next();
DataCell correctedCell = handleIncomingBlob(n, col, totalColCount, copyForVersionHop, forceCopyOfBlobsArg);
if (correctedCell != n) {
if (it instanceof BlobSupportDataCellIterator) {
BlobSupportDataCellIterator bsdi = (BlobSupportDataCellIterator) it;
bsdi.replaceLastReturnedWithWrapperCell(correctedCell);
} else {
// coding problem was reported above.
}
}
}
}
return cell;
} else {
// ordinary cell (e.g. double cell)
return cell;
}
boolean forceCopyOfBlobs = forceCopyOfBlobsArg;
Buffer ownerBuffer;
if (ad != null) {
// either copying from or to an isolated buffer (or both)
forceCopyOfBlobs |= ad.getBufferID() == -1 || getBufferID() == -1;
// (and this is not an ordinary buffer (but a BufferedDataCont.)
if (ad.getBufferID() == getBufferID() && getBufferID() != -1) {
ownerBuffer = this;
} else {
// table that's been created somewhere in the workflow
ContainerTable t = m_globalRepository.get(ad.getBufferID());
ownerBuffer = t != null ? t.getBuffer() : null;
}
/* this can only be true if the argument row contains wrapper
* cells for blobs that do not have a buffer set; that is,
* someone took a BlobDataCell from a predecessor node
* (ad != null) and put it manually into a new wrapper cell
* (wc != null) - by doing that you loose the buffer info
* (wc.getBuffer == null) */
if (isWrapperCell && wc.getBuffer() == null) {
wc.setAddressAndBuffer(ad, ownerBuffer);
}
} else {
ownerBuffer = null;
}
// if we have to make a clone of the blob cell (true if
// isCopyOfExisting is true and the blob address corresponds to the next
// assignable m_indicesOfBlobInColumns[col])
boolean isToCloneForVersionHop = false;
if (copyForVersionHop) {
isToCloneForVersionHop = ad != null && ad.getBufferID() == getBufferID();
// buffer multiple times -- don't copy the duplicates
if (isToCloneForVersionHop && m_indicesOfBlobInColumns == null) {
// first to assign
isToCloneForVersionHop = ad.getIndexOfBlobInColumn() == 0;
assert isToCloneForVersionHop : "Clone of buffer does not return blobs in order";
} else if (isToCloneForVersionHop && m_indicesOfBlobInColumns != null) {
isToCloneForVersionHop = ad.getIndexOfBlobInColumn() == m_indicesOfBlobInColumns[col];
}
}
// if we have to clone the blob because the forceCopyOfBlobs flag is
// on (e.g. because the owning node is a loop end node)
boolean isToCloneDueToForceCopyOfBlobs = false;
// don't overwrite the deep-clone
if (forceCopyOfBlobs && !isToCloneForVersionHop) {
if (m_copiedBlobsMap == null) {
m_copiedBlobsMap = new HashMap<BlobAddress, BlobAddress>();
}
// if not previously copied into this buffer
if (ad != null) {
BlobAddress previousCopyAddress = m_copiedBlobsMap.get(ad);
if (previousCopyAddress == null) {
isToCloneDueToForceCopyOfBlobs = true;
if (isWrapperCell && ownerBuffer == null) {
ownerBuffer = ((BlobWrapperDataCell) cell).getBuffer();
}
} else {
return new BlobWrapperDataCell(this, previousCopyAddress, cl);
}
}
}
// we have to make a clone
if (ownerBuffer == null || isToCloneForVersionHop || isToCloneDueToForceCopyOfBlobs) {
// need to set ownership if this blob was not assigned yet
// or has been assigned to an unlinked (i.e. local) buffer
boolean isCompress = ad != null ? ad.isUseCompression() : isUseCompressionForBlobs(cl);
BlobAddress rewrite = new BlobAddress(m_bufferID, col, isCompress);
if (ad == null) {
// take ownership
if (isWrapperCell) {
((BlobWrapperDataCell) cell).setAddressAndBuffer(rewrite, this);
} else {
((BlobDataCell) cell).setBlobAddress(rewrite);
}
ad = rewrite;
}
if (m_indicesOfBlobInColumns == null) {
m_indicesOfBlobInColumns = new int[totalColCount];
}
// to buffer to copy the blob from (if at all)
Buffer b = null;
if (isToCloneDueToForceCopyOfBlobs) {
b = ownerBuffer;
m_copiedBlobsMap.put(ad, rewrite);
} else {
ContainerTable tbl = m_localRepository.get(ad.getBufferID());
b = tbl == null ? null : tbl.getBuffer();
}
if (b != null && !isToCloneForVersionHop) {
int indexBlobInCol = m_indicesOfBlobInColumns[col]++;
rewrite.setIndexOfBlobInColumn(indexBlobInCol);
File source = b.getBlobFile(ad.getIndexOfBlobInColumn(), ad.getColumn(), false, ad.isUseCompression());
File dest = getBlobFile(indexBlobInCol, col, true, ad.isUseCompression());
FileUtil.copy(source, dest);
wc = new BlobWrapperDataCell(this, rewrite, cl);
} else {
BlobDataCell bc;
if (isWrapperCell) {
DataCell c = ((BlobWrapperDataCell) cell).getCell();
bc = c.isMissing() ? null : (BlobDataCell) c;
} else {
bc = (BlobDataCell) cell;
}
// to take an error along
if (bc != null) {
if (m_outputWriter == null) {
ensureTempFileExists();
initOutputWriter(m_binFile);
}
writeBlobDataCell(bc, rewrite);
wc = new BlobWrapperDataCell(this, rewrite, cl, bc);
} else {
wc = new BlobWrapperDataCell(this, rewrite, cl);
}
}
m_containsBlobs = true;
} else {
// blob has been saved in one of the predecessor nodes
if (isWrapperCell) {
wc = (BlobWrapperDataCell) cell;
} else {
wc = new BlobWrapperDataCell(ownerBuffer, ad, cl);
}
}
return wc;
}
Aggregations