From 4eadb96cc9bd2d9ab1d17976c80a63255a0fc7f9 Mon Sep 17 00:00:00 2001 From: Nathaniel Bauernfeind Date: Wed, 4 Dec 2024 14:14:52 -0700 Subject: [PATCH] Dense Union Reader + fixedChunkLength fixes --- .../engine/table/impl/BaseTable.java | 3 + .../chunk/DefaultChunkReaderFactory.java | 18 +-- .../chunk/DefaultChunkWriterFactory.java | 4 +- .../barrage/chunk/UnionChunkReader.java | 121 ++++++++++++++++++ .../barrage/chunk/UnionChunkWriter.java | 20 +-- .../array/BooleanArrayExpansionKernel.java | 56 +++++--- .../BoxedBooleanArrayExpansionKernel.java | 54 +++++--- .../chunk/array/ByteArrayExpansionKernel.java | 49 +++++-- .../chunk/array/CharArrayExpansionKernel.java | 49 +++++-- .../array/DoubleArrayExpansionKernel.java | 49 +++++-- .../array/FloatArrayExpansionKernel.java | 49 +++++-- .../chunk/array/IntArrayExpansionKernel.java | 49 +++++-- .../chunk/array/LongArrayExpansionKernel.java | 49 +++++-- .../array/ObjectArrayExpansionKernel.java | 44 +++++-- .../array/ShortArrayExpansionKernel.java | 49 +++++-- .../vector/ByteVectorExpansionKernel.java | 46 +++++-- .../vector/CharVectorExpansionKernel.java | 46 +++++-- .../vector/DoubleVectorExpansionKernel.java | 46 +++++-- .../vector/FloatVectorExpansionKernel.java | 46 +++++-- .../vector/IntVectorExpansionKernel.java | 46 +++++-- .../vector/LongVectorExpansionKernel.java | 46 +++++-- .../vector/ObjectVectorExpansionKernel.java | 47 +++++-- .../vector/ShortVectorExpansionKernel.java | 46 +++++-- .../extensions/barrage/util/BarrageUtil.java | 3 + .../extensions/barrage/Barrage.gwt.xml | 1 + 25 files changed, 773 insertions(+), 263 deletions(-) create mode 100644 extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/UnionChunkReader.java diff --git a/engine/table/src/main/java/io/deephaven/engine/table/impl/BaseTable.java b/engine/table/src/main/java/io/deephaven/engine/table/impl/BaseTable.java index e0a1e4d1102..9642fba9bed 100644 --- a/engine/table/src/main/java/io/deephaven/engine/table/impl/BaseTable.java +++ b/engine/table/src/main/java/io/deephaven/engine/table/impl/BaseTable.java @@ -360,6 +360,9 @@ public enum CopyAttributeOperation { CopyAttributeOperation.Flatten, // add flatten for now because web flattens all views CopyAttributeOperation.Preview)); + tempMap.put(BARRAGE_SCHEMA_ATTRIBUTE, EnumSet.of( + CopyAttributeOperation.Filter)); + attributeToCopySet = Collections.unmodifiableMap(tempMap); } diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/DefaultChunkReaderFactory.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/DefaultChunkReaderFactory.java index 6500ed749f8..9fe71ffdd0f 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/DefaultChunkReaderFactory.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/DefaultChunkReaderFactory.java @@ -46,8 +46,10 @@ import java.time.Period; import java.time.ZoneId; import java.time.ZonedDateTime; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -272,18 +274,12 @@ public > ChunkReader newReaderPojo( // maybe defaults to Map if (typeId == ArrowType.ArrowTypeID.Union) { - // TODO: defaults to Object final ArrowType.Union unionType = (ArrowType.Union) field.getType(); - switch (unionType.getMode()) { - case Sparse: - // TODO NATE NOCOMMIT: implement - break; - case Dense: - // TODO NATE NOCOMMIT: implement - break; - default: - throw new IllegalArgumentException("Unexpected union mode: " + unionType.getMode()); - } + final List>> innerReaders = new ArrayList<>(); + + // noinspection unchecked + return (ChunkReader) new UnionChunkReader( + UnionChunkReader.mode(unionType.getMode()), innerReaders); } throw new UnsupportedOperationException(String.format( diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/DefaultChunkWriterFactory.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/DefaultChunkWriterFactory.java index f18d56e4a6f..77fca4cd630 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/DefaultChunkWriterFactory.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/DefaultChunkWriterFactory.java @@ -293,8 +293,8 @@ public > ChunkWriter newWriterPojo( .map(BarrageTypeInfo::chunkType) .collect(Collectors.toList()); - UnionChunkWriter.Mode mode = unionType.getMode() == UnionMode.Sparse ? UnionChunkWriter.Mode.Sparse - : UnionChunkWriter.Mode.Dense; + UnionChunkReader.Mode mode = unionType.getMode() == UnionMode.Sparse ? UnionChunkReader.Mode.Sparse + : UnionChunkReader.Mode.Dense; // noinspection unchecked return (ChunkWriter) new UnionChunkWriter<>(mode, childClassMatcher, childWriters, childChunkTypes); diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/UnionChunkReader.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/UnionChunkReader.java new file mode 100644 index 00000000000..eb899830b81 --- /dev/null +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/UnionChunkReader.java @@ -0,0 +1,121 @@ +// +// Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending +// +package io.deephaven.extensions.barrage.chunk; + +import io.deephaven.base.verify.Assert; +import io.deephaven.chunk.ObjectChunk; +import io.deephaven.chunk.WritableByteChunk; +import io.deephaven.chunk.WritableChunk; +import io.deephaven.chunk.WritableIntChunk; +import io.deephaven.chunk.WritableObjectChunk; +import io.deephaven.chunk.attributes.ChunkPositions; +import io.deephaven.chunk.attributes.Values; +import io.deephaven.engine.table.impl.chunkboxer.ChunkBoxer; +import io.deephaven.util.SafeCloseable; +import io.deephaven.util.SafeCloseableList; +import io.deephaven.util.datastructures.LongSizedDataStructure; +import org.apache.arrow.vector.types.UnionMode; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.DataInput; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import java.util.PrimitiveIterator; + +public class UnionChunkReader extends BaseChunkReader> { + public enum Mode { + Dense, Sparse + } + public static Mode mode(UnionMode mode) { + return mode == UnionMode.Dense ? Mode.Dense : Mode.Sparse; + } + + private static final String DEBUG_NAME = "UnionChunkReader"; + + private final Mode mode; + private final List>> readers; + + public UnionChunkReader( + final Mode mode, + final List>> readers) { + this.mode = mode; + this.readers = readers; + // the specification doesn't allow the union column to have more than signed byte number of types + Assert.leq(readers.size(), "readers.size()", Byte.MAX_VALUE, "Byte.MAX_VALUE"); + } + + @Override + public WritableObjectChunk readChunk( + @NotNull final Iterator fieldNodeIter, + @NotNull final PrimitiveIterator.OfLong bufferInfoIter, + @NotNull final DataInput is, + @Nullable final WritableChunk outChunk, + final int outOffset, + final int totalRows) throws IOException { + final ChunkWriter.FieldNodeInfo nodeInfo = fieldNodeIter.next(); + // column of interest buffer + final long coiBufferLength = bufferInfoIter.nextLong(); + // if Dense we also have an offset buffer + final long offsetsBufferLength = mode == Mode.Dense ? bufferInfoIter.nextLong() : 0; + + int numRows = nodeInfo.numElements; + if (numRows == 0) { + is.skipBytes(LongSizedDataStructure.intSize(DEBUG_NAME, coiBufferLength + offsetsBufferLength)); + for (final ChunkReader> reader : readers) { + // noinspection EmptyTryBlock + try (final SafeCloseable ignored = reader.readChunk(fieldNodeIter, bufferInfoIter, is, null, 0, 0)) { + // do nothing; we need each reader to consume fieldNodeIter and bufferInfoIter + } + } + return WritableObjectChunk.makeWritableChunk(numRows); + } + + try (final WritableByteChunk columnsOfInterest = + WritableByteChunk.makeWritableChunk(numRows); + final WritableIntChunk offsets = mode == Mode.Sparse + ? null + : WritableIntChunk.makeWritableChunk(numRows); + final SafeCloseableList closeableList = new SafeCloseableList()) { + + // noinspection unchecked + final ObjectChunk[] chunks = new ObjectChunk[readers.size()]; + + for (int ii = 0; ii < readers.size(); ++ii) { + final WritableChunk chunk = + readers.get(ii).readChunk(fieldNodeIter, bufferInfoIter, is, null, 0, 0); + closeableList.add(chunk); + + final ChunkBoxer.BoxerKernel boxer = ChunkBoxer.getBoxer(chunk.getChunkType(), chunk.size()); + closeableList.add(boxer); + + // noinspection unchecked + chunks[ii] = (ObjectChunk) boxer.box(chunk); + } + + final WritableObjectChunk result; + if (outChunk != null) { + result = outChunk.asWritableObjectChunk(); + } else { + result = WritableObjectChunk.makeWritableChunk(numRows); + result.setSize(numRows); + } + + for (int ii = 0; ii < result.size(); ++ii) { + final byte coi = columnsOfInterest.get(ii); + final int offset; + if (mode == Mode.Dense) { + offset = offsets.get(ii); + } else { + offset = ii; + } + + result.set(ii, chunks[coi].get(offset)); + } + + return result; + } + } +} diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/UnionChunkWriter.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/UnionChunkWriter.java index 239d421905a..41f1dd74f23 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/UnionChunkWriter.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/UnionChunkWriter.java @@ -26,19 +26,15 @@ import java.util.stream.Collectors; public class UnionChunkWriter extends BaseChunkWriter> { - public enum Mode { - Dense, Sparse - } - private static final String DEBUG_NAME = "UnionChunkWriter"; - private final Mode mode; + private final UnionChunkReader.Mode mode; private final List> classMatchers; private final List>> writers; private final List writerChunkTypes; public UnionChunkWriter( - final Mode mode, + final UnionChunkReader.Mode mode, final List> classMatchers, final List>> writers, final List writerChunkTypes) { @@ -48,7 +44,7 @@ public UnionChunkWriter( this.writers = writers; this.writerChunkTypes = writerChunkTypes; // the specification doesn't allow the union column to have more than signed byte number of types - Assert.leq(classMatchers.size(), "classMatchers.size()", 127); + Assert.leq(classMatchers.size(), "classMatchers.size()", Byte.MAX_VALUE, "Byte.MAX_VALUE"); } @Override @@ -88,7 +84,7 @@ private UnionChunkInputStream( super(context, mySubset, options); final int numColumns = classMatchers.size(); final ObjectChunk chunk = context.getChunk(); - if (mode == Mode.Sparse) { + if (mode == UnionChunkReader.Mode.Sparse) { columnOffset = null; } else { // noinspection resource @@ -104,7 +100,7 @@ private UnionChunkInputStream( // noinspection resource innerChunks[ii] = WritableObjectChunk.makeWritableChunk(chunk.size()); - if (mode == Mode.Sparse) { + if (mode == UnionChunkReader.Mode.Sparse) { innerChunks[ii].fillWithNullValue(0, chunk.size()); } else { innerChunks[ii].setSize(0); @@ -115,7 +111,7 @@ private UnionChunkInputStream( int jj; for (jj = 0; jj < classMatchers.size(); ++jj) { if (value.getClass().isAssignableFrom(classMatchers.get(jj))) { - if (mode == Mode.Sparse) { + if (mode == UnionChunkReader.Mode.Sparse) { columnOfInterest.set(ii, (byte) jj); innerChunks[jj].set(ii, value); } else { @@ -156,6 +152,10 @@ private UnionChunkInputStream( try (ChunkWriter.Context> innerContext = writer.makeContext(kernel != null ? (Chunk) kernel.unbox(innerChunk) : innerChunk, 0)) { + if (kernel != null) { + // while we did steal the kernel's chunk after unboxing, now no one owns the original chunk + innerChunk.close(); + } innerColumns[ii] = writer.getInputStream(innerContext, null, options); } diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/BooleanArrayExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/BooleanArrayExpansionKernel.java index ca09b12d014..d6919230207 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/BooleanArrayExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/BooleanArrayExpansionKernel.java @@ -20,8 +20,10 @@ import org.jetbrains.annotations.Nullable; public class BooleanArrayExpansionKernel implements ArrayExpansionKernel { - private final static boolean[] ZERO_LEN_ARRAY = new boolean[0]; - public final static BooleanArrayExpansionKernel INSTANCE = new BooleanArrayExpansionKernel(); + public static final BooleanArrayExpansionKernel INSTANCE = new BooleanArrayExpansionKernel(); + + private static final String DEBUG_NAME = "BooleanArrayExpansionKernel"; + private static final boolean[] ZERO_LEN_ARRAY = new boolean[0]; @Override public WritableChunk expand( @@ -39,15 +41,17 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < typedSource.size(); ++ii) { - final boolean[] row = typedSource.get(ii); - int rowLen = row == null ? 0 : row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + int rowLen; + if (fixedSizeLength != 0) { + rowLen = Math.abs(fixedSizeLength); + } else { + final boolean[] row = typedSource.get(ii); + rowLen = row == null ? 0 : row.length; } totalSize += rowLen; } final WritableByteChunk result = WritableByteChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); int lenWritten = 0; if (offsetsDest != null) { @@ -58,18 +62,36 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, lenWritten); } - if (row == null) { - continue; - } - int rowLen = row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + int written = 0; + if (row != null) { + int offset = 0; + if (fixedSizeLength != 0) { + // limit length to fixedSizeLength + written = Math.min(row.length, Math.abs(fixedSizeLength)); + if (fixedSizeLength < 0 && written < row.length) { + // read from the end of the array when fixedSizeLength is negative + offset = row.length - written; + } + } else { + written = row.length; + } + + // copy the row into the result + for (int j = 0; j < written; ++j) { + final byte value = row[j] ? BooleanUtils.TRUE_BOOLEAN_AS_BYTE : BooleanUtils.FALSE_BOOLEAN_AS_BYTE; + result.set(lenWritten + j, value); + } } - for (int j = 0; j < rowLen; ++j) { - final byte value = row[j] ? BooleanUtils.TRUE_BOOLEAN_AS_BYTE : BooleanUtils.FALSE_BOOLEAN_AS_BYTE; - result.set(lenWritten + j, value); + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - written)); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(lenWritten + written, toNull); + written += toNull; + } } - lenWritten += rowLen; + lenWritten += written; } if (offsetsDest != null) { offsetsDest.set(typedSource.size(), lenWritten); diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/BoxedBooleanArrayExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/BoxedBooleanArrayExpansionKernel.java index 0aae8b92bca..7c8b8645874 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/BoxedBooleanArrayExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/BoxedBooleanArrayExpansionKernel.java @@ -20,8 +20,10 @@ import org.jetbrains.annotations.Nullable; public class BoxedBooleanArrayExpansionKernel implements ArrayExpansionKernel { - private final static Boolean[] ZERO_LEN_ARRAY = new Boolean[0]; - public final static BoxedBooleanArrayExpansionKernel INSTANCE = new BoxedBooleanArrayExpansionKernel(); + public static final BoxedBooleanArrayExpansionKernel INSTANCE = new BoxedBooleanArrayExpansionKernel(); + + private static final String DEBUG_NAME = "BoxedBooleanArrayExpansionKernel"; + private static final Boolean[] ZERO_LEN_ARRAY = new Boolean[0]; @Override public WritableChunk expand( @@ -39,15 +41,17 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < typedSource.size(); ++ii) { - final Boolean[] row = typedSource.get(ii); - int rowLen = row == null ? 0 : row.length; + int rowLen; if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + rowLen = Math.abs(fixedSizeLength); + } else { + final Boolean[] row = typedSource.get(ii); + rowLen = row == null ? 0 : row.length; } totalSize += rowLen; } final WritableByteChunk result = WritableByteChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); int lenWritten = 0; if (offsetsDest != null) { @@ -58,18 +62,36 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, lenWritten); } - if (row == null) { - continue; - } - int rowLen = row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + int written = 0; + if (row != null) { + int offset = 0; + if (fixedSizeLength != 0) { + // limit length to fixedSizeLength + written = Math.min(row.length, Math.abs(fixedSizeLength)); + if (fixedSizeLength < 0 && written < row.length) { + // read from the end of the array when fixedSizeLength is negative + offset = row.length - written; + } + } else { + written = row.length; + } + + // copy the row into the result + for (int j = 0; j < written; ++j) { + final byte value = BooleanUtils.booleanAsByte(row[j]); + result.set(lenWritten + j, value); + } } - for (int j = 0; j < rowLen; ++j) { - final byte value = BooleanUtils.booleanAsByte(row[j]); - result.set(lenWritten + j, value); + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - written)); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(lenWritten + written, toNull); + written += toNull; + } } - lenWritten += rowLen; + lenWritten += written; } if (offsetsDest != null) { offsetsDest.set(typedSource.size(), lenWritten); diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/ByteArrayExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/ByteArrayExpansionKernel.java index 1312720d20e..b6048257d60 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/ByteArrayExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/ByteArrayExpansionKernel.java @@ -23,8 +23,10 @@ import org.jetbrains.annotations.Nullable; public class ByteArrayExpansionKernel implements ArrayExpansionKernel { - private final static byte[] ZERO_LEN_ARRAY = new byte[0]; - public final static ByteArrayExpansionKernel INSTANCE = new ByteArrayExpansionKernel(); + public static final ByteArrayExpansionKernel INSTANCE = new ByteArrayExpansionKernel(); + + private static final String DEBUG_NAME = "ByteArrayExpansionKernel"; + private static final byte[] ZERO_LEN_ARRAY = new byte[0]; @Override public WritableChunk expand( @@ -40,15 +42,17 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < source.size(); ++ii) { - final byte[] row = source.get(ii); - int rowLen = row == null ? 0 : row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + final int rowLen; + if (fixedSizeLength != 0) { + rowLen = Math.abs(fixedSizeLength); + } else { + final byte[] row = source.get(ii); + rowLen = row == null ? 0 : row.length; } totalSize += rowLen; } final WritableByteChunk result = WritableByteChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); int lenWritten = 0; if (offsetsDest != null) { @@ -59,15 +63,32 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, lenWritten); } - if (row == null) { - continue; + int written = 0; + if (row != null) { + int offset = 0; + if (fixedSizeLength != 0) { + // limit length to fixedSizeLength + written = Math.min(row.length, Math.abs(fixedSizeLength)); + if (fixedSizeLength < 0 && written < row.length) { + // read from the end of the array when fixedSizeLength is negative + offset = row.length - written; + } + } else { + written = row.length; + } + // copy the row into the result + result.copyFromArray(row, offset, lenWritten, written); } - int rowLen = row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - written)); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(lenWritten + written, toNull); + written += toNull; + } } - result.copyFromArray(row, 0, lenWritten, rowLen); - lenWritten += rowLen; + lenWritten += written; } if (offsetsDest != null) { offsetsDest.set(source.size(), lenWritten); diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/CharArrayExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/CharArrayExpansionKernel.java index 06b51614b80..f09d69e80b5 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/CharArrayExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/CharArrayExpansionKernel.java @@ -19,8 +19,10 @@ import org.jetbrains.annotations.Nullable; public class CharArrayExpansionKernel implements ArrayExpansionKernel { - private final static char[] ZERO_LEN_ARRAY = new char[0]; - public final static CharArrayExpansionKernel INSTANCE = new CharArrayExpansionKernel(); + public static final CharArrayExpansionKernel INSTANCE = new CharArrayExpansionKernel(); + + private static final String DEBUG_NAME = "CharArrayExpansionKernel"; + private static final char[] ZERO_LEN_ARRAY = new char[0]; @Override public WritableChunk expand( @@ -36,15 +38,17 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < source.size(); ++ii) { - final char[] row = source.get(ii); - int rowLen = row == null ? 0 : row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + final int rowLen; + if (fixedSizeLength != 0) { + rowLen = Math.abs(fixedSizeLength); + } else { + final char[] row = source.get(ii); + rowLen = row == null ? 0 : row.length; } totalSize += rowLen; } final WritableCharChunk result = WritableCharChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); int lenWritten = 0; if (offsetsDest != null) { @@ -55,15 +59,32 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, lenWritten); } - if (row == null) { - continue; + int written = 0; + if (row != null) { + int offset = 0; + if (fixedSizeLength != 0) { + // limit length to fixedSizeLength + written = Math.min(row.length, Math.abs(fixedSizeLength)); + if (fixedSizeLength < 0 && written < row.length) { + // read from the end of the array when fixedSizeLength is negative + offset = row.length - written; + } + } else { + written = row.length; + } + // copy the row into the result + result.copyFromArray(row, offset, lenWritten, written); } - int rowLen = row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - written)); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(lenWritten + written, toNull); + written += toNull; + } } - result.copyFromArray(row, 0, lenWritten, rowLen); - lenWritten += rowLen; + lenWritten += written; } if (offsetsDest != null) { offsetsDest.set(source.size(), lenWritten); diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/DoubleArrayExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/DoubleArrayExpansionKernel.java index 5d201f9bcea..0dd62e4e721 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/DoubleArrayExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/DoubleArrayExpansionKernel.java @@ -23,8 +23,10 @@ import org.jetbrains.annotations.Nullable; public class DoubleArrayExpansionKernel implements ArrayExpansionKernel { - private final static double[] ZERO_LEN_ARRAY = new double[0]; - public final static DoubleArrayExpansionKernel INSTANCE = new DoubleArrayExpansionKernel(); + public static final DoubleArrayExpansionKernel INSTANCE = new DoubleArrayExpansionKernel(); + + private static final String DEBUG_NAME = "DoubleArrayExpansionKernel"; + private static final double[] ZERO_LEN_ARRAY = new double[0]; @Override public WritableChunk expand( @@ -40,15 +42,17 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < source.size(); ++ii) { - final double[] row = source.get(ii); - int rowLen = row == null ? 0 : row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + final int rowLen; + if (fixedSizeLength != 0) { + rowLen = Math.abs(fixedSizeLength); + } else { + final double[] row = source.get(ii); + rowLen = row == null ? 0 : row.length; } totalSize += rowLen; } final WritableDoubleChunk result = WritableDoubleChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); int lenWritten = 0; if (offsetsDest != null) { @@ -59,15 +63,32 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, lenWritten); } - if (row == null) { - continue; + int written = 0; + if (row != null) { + int offset = 0; + if (fixedSizeLength != 0) { + // limit length to fixedSizeLength + written = Math.min(row.length, Math.abs(fixedSizeLength)); + if (fixedSizeLength < 0 && written < row.length) { + // read from the end of the array when fixedSizeLength is negative + offset = row.length - written; + } + } else { + written = row.length; + } + // copy the row into the result + result.copyFromArray(row, offset, lenWritten, written); } - int rowLen = row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - written)); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(lenWritten + written, toNull); + written += toNull; + } } - result.copyFromArray(row, 0, lenWritten, rowLen); - lenWritten += rowLen; + lenWritten += written; } if (offsetsDest != null) { offsetsDest.set(source.size(), lenWritten); diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/FloatArrayExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/FloatArrayExpansionKernel.java index e9853645ec5..4e5963ec132 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/FloatArrayExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/FloatArrayExpansionKernel.java @@ -23,8 +23,10 @@ import org.jetbrains.annotations.Nullable; public class FloatArrayExpansionKernel implements ArrayExpansionKernel { - private final static float[] ZERO_LEN_ARRAY = new float[0]; - public final static FloatArrayExpansionKernel INSTANCE = new FloatArrayExpansionKernel(); + public static final FloatArrayExpansionKernel INSTANCE = new FloatArrayExpansionKernel(); + + private static final String DEBUG_NAME = "FloatArrayExpansionKernel"; + private static final float[] ZERO_LEN_ARRAY = new float[0]; @Override public WritableChunk expand( @@ -40,15 +42,17 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < source.size(); ++ii) { - final float[] row = source.get(ii); - int rowLen = row == null ? 0 : row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + final int rowLen; + if (fixedSizeLength != 0) { + rowLen = Math.abs(fixedSizeLength); + } else { + final float[] row = source.get(ii); + rowLen = row == null ? 0 : row.length; } totalSize += rowLen; } final WritableFloatChunk result = WritableFloatChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); int lenWritten = 0; if (offsetsDest != null) { @@ -59,15 +63,32 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, lenWritten); } - if (row == null) { - continue; + int written = 0; + if (row != null) { + int offset = 0; + if (fixedSizeLength != 0) { + // limit length to fixedSizeLength + written = Math.min(row.length, Math.abs(fixedSizeLength)); + if (fixedSizeLength < 0 && written < row.length) { + // read from the end of the array when fixedSizeLength is negative + offset = row.length - written; + } + } else { + written = row.length; + } + // copy the row into the result + result.copyFromArray(row, offset, lenWritten, written); } - int rowLen = row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - written)); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(lenWritten + written, toNull); + written += toNull; + } } - result.copyFromArray(row, 0, lenWritten, rowLen); - lenWritten += rowLen; + lenWritten += written; } if (offsetsDest != null) { offsetsDest.set(source.size(), lenWritten); diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/IntArrayExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/IntArrayExpansionKernel.java index 5e10b9d751e..c0909ad37f7 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/IntArrayExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/IntArrayExpansionKernel.java @@ -23,8 +23,10 @@ import org.jetbrains.annotations.Nullable; public class IntArrayExpansionKernel implements ArrayExpansionKernel { - private final static int[] ZERO_LEN_ARRAY = new int[0]; - public final static IntArrayExpansionKernel INSTANCE = new IntArrayExpansionKernel(); + public static final IntArrayExpansionKernel INSTANCE = new IntArrayExpansionKernel(); + + private static final String DEBUG_NAME = "IntArrayExpansionKernel"; + private static final int[] ZERO_LEN_ARRAY = new int[0]; @Override public WritableChunk expand( @@ -40,15 +42,17 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < source.size(); ++ii) { - final int[] row = source.get(ii); - int rowLen = row == null ? 0 : row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + final int rowLen; + if (fixedSizeLength != 0) { + rowLen = Math.abs(fixedSizeLength); + } else { + final int[] row = source.get(ii); + rowLen = row == null ? 0 : row.length; } totalSize += rowLen; } final WritableIntChunk result = WritableIntChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); int lenWritten = 0; if (offsetsDest != null) { @@ -59,15 +63,32 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, lenWritten); } - if (row == null) { - continue; + int written = 0; + if (row != null) { + int offset = 0; + if (fixedSizeLength != 0) { + // limit length to fixedSizeLength + written = Math.min(row.length, Math.abs(fixedSizeLength)); + if (fixedSizeLength < 0 && written < row.length) { + // read from the end of the array when fixedSizeLength is negative + offset = row.length - written; + } + } else { + written = row.length; + } + // copy the row into the result + result.copyFromArray(row, offset, lenWritten, written); } - int rowLen = row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - written)); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(lenWritten + written, toNull); + written += toNull; + } } - result.copyFromArray(row, 0, lenWritten, rowLen); - lenWritten += rowLen; + lenWritten += written; } if (offsetsDest != null) { offsetsDest.set(source.size(), lenWritten); diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/LongArrayExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/LongArrayExpansionKernel.java index 99bbba564d4..7a19b14bd9d 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/LongArrayExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/LongArrayExpansionKernel.java @@ -23,8 +23,10 @@ import org.jetbrains.annotations.Nullable; public class LongArrayExpansionKernel implements ArrayExpansionKernel { - private final static long[] ZERO_LEN_ARRAY = new long[0]; - public final static LongArrayExpansionKernel INSTANCE = new LongArrayExpansionKernel(); + public static final LongArrayExpansionKernel INSTANCE = new LongArrayExpansionKernel(); + + private static final String DEBUG_NAME = "LongArrayExpansionKernel"; + private static final long[] ZERO_LEN_ARRAY = new long[0]; @Override public WritableChunk expand( @@ -40,15 +42,17 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < source.size(); ++ii) { - final long[] row = source.get(ii); - int rowLen = row == null ? 0 : row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + final int rowLen; + if (fixedSizeLength != 0) { + rowLen = Math.abs(fixedSizeLength); + } else { + final long[] row = source.get(ii); + rowLen = row == null ? 0 : row.length; } totalSize += rowLen; } final WritableLongChunk result = WritableLongChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); int lenWritten = 0; if (offsetsDest != null) { @@ -59,15 +63,32 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, lenWritten); } - if (row == null) { - continue; + int written = 0; + if (row != null) { + int offset = 0; + if (fixedSizeLength != 0) { + // limit length to fixedSizeLength + written = Math.min(row.length, Math.abs(fixedSizeLength)); + if (fixedSizeLength < 0 && written < row.length) { + // read from the end of the array when fixedSizeLength is negative + offset = row.length - written; + } + } else { + written = row.length; + } + // copy the row into the result + result.copyFromArray(row, offset, lenWritten, written); } - int rowLen = row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - written)); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(lenWritten + written, toNull); + written += toNull; + } } - result.copyFromArray(row, 0, lenWritten, rowLen); - lenWritten += rowLen; + lenWritten += written; } if (offsetsDest != null) { offsetsDest.set(source.size(), lenWritten); diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/ObjectArrayExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/ObjectArrayExpansionKernel.java index 83e944acb7f..fbe0c59c1c2 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/ObjectArrayExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/ObjectArrayExpansionKernel.java @@ -17,6 +17,7 @@ import org.jetbrains.annotations.Nullable; public class ObjectArrayExpansionKernel implements ArrayExpansionKernel { + private static final String DEBUG_NAME = "ObjectArrayExpansionKernel"; private final Class componentType; @@ -40,15 +41,17 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < typedSource.size(); ++ii) { - final T[] row = typedSource.get(ii); - int rowLen = row == null ? 0 : row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + final int rowLen; + if (fixedSizeLength != 0) { + rowLen = Math.abs(fixedSizeLength); + } else { + final T[] row = typedSource.get(ii); + rowLen = row == null ? 0 : row.length; } totalSize += rowLen; } final WritableObjectChunk result = WritableObjectChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); int lenWritten = 0; if (offsetsDest != null) { @@ -59,15 +62,32 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, lenWritten); } - if (row == null) { - continue; + int written = 0; + if (row != null) { + int offset = 0; + if (fixedSizeLength != 0) { + // limit length to fixedSizeLength + written = Math.min(row.length, Math.abs(fixedSizeLength)); + if (fixedSizeLength < 0 && written < row.length) { + // read from the end of the array when fixedSizeLength is negative + offset = row.length - written; + } + } else { + written = row.length; + } + // copy the row into the result + result.copyFromArray(row, 0, lenWritten, written); } - int rowLen = row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - written)); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(lenWritten + written, toNull); + written += toNull; + } } - result.copyFromArray(row, 0, lenWritten, rowLen); - lenWritten += rowLen; + lenWritten += written; } if (offsetsDest != null) { offsetsDest.set(typedSource.size(), lenWritten); diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/ShortArrayExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/ShortArrayExpansionKernel.java index 51d51864ffb..c01f8518ddc 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/ShortArrayExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/array/ShortArrayExpansionKernel.java @@ -23,8 +23,10 @@ import org.jetbrains.annotations.Nullable; public class ShortArrayExpansionKernel implements ArrayExpansionKernel { - private final static short[] ZERO_LEN_ARRAY = new short[0]; - public final static ShortArrayExpansionKernel INSTANCE = new ShortArrayExpansionKernel(); + public static final ShortArrayExpansionKernel INSTANCE = new ShortArrayExpansionKernel(); + + private static final String DEBUG_NAME = "ShortArrayExpansionKernel"; + private static final short[] ZERO_LEN_ARRAY = new short[0]; @Override public WritableChunk expand( @@ -40,15 +42,17 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < source.size(); ++ii) { - final short[] row = source.get(ii); - int rowLen = row == null ? 0 : row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + final int rowLen; + if (fixedSizeLength != 0) { + rowLen = Math.abs(fixedSizeLength); + } else { + final short[] row = source.get(ii); + rowLen = row == null ? 0 : row.length; } totalSize += rowLen; } final WritableShortChunk result = WritableShortChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); int lenWritten = 0; if (offsetsDest != null) { @@ -59,15 +63,32 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, lenWritten); } - if (row == null) { - continue; + int written = 0; + if (row != null) { + int offset = 0; + if (fixedSizeLength != 0) { + // limit length to fixedSizeLength + written = Math.min(row.length, Math.abs(fixedSizeLength)); + if (fixedSizeLength < 0 && written < row.length) { + // read from the end of the array when fixedSizeLength is negative + offset = row.length - written; + } + } else { + written = row.length; + } + // copy the row into the result + result.copyFromArray(row, offset, lenWritten, written); } - int rowLen = row.length; - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - written)); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(lenWritten + written, toNull); + written += toNull; + } } - result.copyFromArray(row, 0, lenWritten, rowLen); - lenWritten += rowLen; + lenWritten += written; } if (offsetsDest != null) { offsetsDest.set(source.size(), lenWritten); diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/ByteVectorExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/ByteVectorExpansionKernel.java index 582f6377d08..c238460be55 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/ByteVectorExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/ByteVectorExpansionKernel.java @@ -26,11 +26,15 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.stream.Stream; + import static io.deephaven.vector.ByteVectorDirect.ZERO_LENGTH_VECTOR; public class ByteVectorExpansionKernel implements VectorExpansionKernel { public final static ByteVectorExpansionKernel INSTANCE = new ByteVectorExpansionKernel(); + private static final String DEBUG_NAME = "ByteVectorExpansionKernel"; + @Override public WritableChunk expand( @NotNull final ObjectChunk source, @@ -48,14 +52,16 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < typedSource.size(); ++ii) { final ByteVector row = typedSource.get(ii); - long rowLen = row == null ? 0 : row.size(); - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + long rowLen; + if (fixedSizeLength != 0) { + rowLen = Math.abs(fixedSizeLength); + } else { + rowLen = row == null ? 0 : row.size(); } totalSize += rowLen; } final WritableByteChunk result = WritableByteChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); result.setSize(0); if (offsetsDest != null) { @@ -66,15 +72,31 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, result.size()); } - if (row == null) { - continue; + if (row != null) { + final ByteConsumer consumer = result::add; + try (final CloseablePrimitiveIteratorOfByte iter = row.iterator()) { + Stream stream = iter.stream(); + if (fixedSizeLength > 0) { + // limit length to fixedSizeLength + stream = iter.stream().limit(fixedSizeLength); + } else if (fixedSizeLength < 0) { + final long numToSkip = Math.max(0, row.size() + fixedSizeLength); + if (numToSkip > 0) { + // read from the end of the array when fixedSizeLength is negative + stream = stream.skip(numToSkip); + } + } + // copy the row into the result + stream.forEach(consumer::accept); + } } - final ByteConsumer consumer = result::add; - try (final CloseablePrimitiveIteratorOfByte iter = row.iterator()) { - if (fixedSizeLength > 0) { - iter.stream().limit(fixedSizeLength).forEach(consumer::accept); - } else { - iter.forEachRemaining(consumer); + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - (row == null ? 0 : row.size()))); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(result.size(), toNull); + result.setSize(result.size() + toNull); } } } diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/CharVectorExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/CharVectorExpansionKernel.java index 3ab4037bb7b..ad1901a9386 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/CharVectorExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/CharVectorExpansionKernel.java @@ -22,11 +22,15 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.stream.Stream; + import static io.deephaven.vector.CharVectorDirect.ZERO_LENGTH_VECTOR; public class CharVectorExpansionKernel implements VectorExpansionKernel { public final static CharVectorExpansionKernel INSTANCE = new CharVectorExpansionKernel(); + private static final String DEBUG_NAME = "CharVectorExpansionKernel"; + @Override public WritableChunk expand( @NotNull final ObjectChunk source, @@ -44,14 +48,16 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < typedSource.size(); ++ii) { final CharVector row = typedSource.get(ii); - long rowLen = row == null ? 0 : row.size(); - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + long rowLen; + if (fixedSizeLength != 0) { + rowLen = Math.abs(fixedSizeLength); + } else { + rowLen = row == null ? 0 : row.size(); } totalSize += rowLen; } final WritableCharChunk result = WritableCharChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); result.setSize(0); if (offsetsDest != null) { @@ -62,15 +68,31 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, result.size()); } - if (row == null) { - continue; + if (row != null) { + final CharConsumer consumer = result::add; + try (final CloseablePrimitiveIteratorOfChar iter = row.iterator()) { + Stream stream = iter.stream(); + if (fixedSizeLength > 0) { + // limit length to fixedSizeLength + stream = iter.stream().limit(fixedSizeLength); + } else if (fixedSizeLength < 0) { + final long numToSkip = Math.max(0, row.size() + fixedSizeLength); + if (numToSkip > 0) { + // read from the end of the array when fixedSizeLength is negative + stream = stream.skip(numToSkip); + } + } + // copy the row into the result + stream.forEach(consumer::accept); + } } - final CharConsumer consumer = result::add; - try (final CloseablePrimitiveIteratorOfChar iter = row.iterator()) { - if (fixedSizeLength > 0) { - iter.stream().limit(fixedSizeLength).forEach(consumer::accept); - } else { - iter.forEachRemaining(consumer); + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - (row == null ? 0 : row.size()))); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(result.size(), toNull); + result.setSize(result.size() + toNull); } } } diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/DoubleVectorExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/DoubleVectorExpansionKernel.java index 37ebe5626dc..226e981d88a 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/DoubleVectorExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/DoubleVectorExpansionKernel.java @@ -27,11 +27,15 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.stream.Stream; + import static io.deephaven.vector.DoubleVectorDirect.ZERO_LENGTH_VECTOR; public class DoubleVectorExpansionKernel implements VectorExpansionKernel { public final static DoubleVectorExpansionKernel INSTANCE = new DoubleVectorExpansionKernel(); + private static final String DEBUG_NAME = "DoubleVectorExpansionKernel"; + @Override public WritableChunk expand( @NotNull final ObjectChunk source, @@ -49,14 +53,16 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < typedSource.size(); ++ii) { final DoubleVector row = typedSource.get(ii); - long rowLen = row == null ? 0 : row.size(); - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + long rowLen; + if (fixedSizeLength != 0) { + rowLen = Math.abs(fixedSizeLength); + } else { + rowLen = row == null ? 0 : row.size(); } totalSize += rowLen; } final WritableDoubleChunk result = WritableDoubleChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); result.setSize(0); if (offsetsDest != null) { @@ -67,15 +73,31 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, result.size()); } - if (row == null) { - continue; + if (row != null) { + final DoubleConsumer consumer = result::add; + try (final CloseablePrimitiveIteratorOfDouble iter = row.iterator()) { + Stream stream = iter.stream(); + if (fixedSizeLength > 0) { + // limit length to fixedSizeLength + stream = iter.stream().limit(fixedSizeLength); + } else if (fixedSizeLength < 0) { + final long numToSkip = Math.max(0, row.size() + fixedSizeLength); + if (numToSkip > 0) { + // read from the end of the array when fixedSizeLength is negative + stream = stream.skip(numToSkip); + } + } + // copy the row into the result + stream.forEach(consumer::accept); + } } - final DoubleConsumer consumer = result::add; - try (final CloseablePrimitiveIteratorOfDouble iter = row.iterator()) { - if (fixedSizeLength > 0) { - iter.stream().limit(fixedSizeLength).forEach(consumer::accept); - } else { - iter.forEachRemaining(consumer); + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - (row == null ? 0 : row.size()))); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(result.size(), toNull); + result.setSize(result.size() + toNull); } } } diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/FloatVectorExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/FloatVectorExpansionKernel.java index c2038e78859..6ac0fc5da8b 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/FloatVectorExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/FloatVectorExpansionKernel.java @@ -26,11 +26,15 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.stream.Stream; + import static io.deephaven.vector.FloatVectorDirect.ZERO_LENGTH_VECTOR; public class FloatVectorExpansionKernel implements VectorExpansionKernel { public final static FloatVectorExpansionKernel INSTANCE = new FloatVectorExpansionKernel(); + private static final String DEBUG_NAME = "FloatVectorExpansionKernel"; + @Override public WritableChunk expand( @NotNull final ObjectChunk source, @@ -48,14 +52,16 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < typedSource.size(); ++ii) { final FloatVector row = typedSource.get(ii); - long rowLen = row == null ? 0 : row.size(); - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + long rowLen; + if (fixedSizeLength != 0) { + rowLen = Math.abs(fixedSizeLength); + } else { + rowLen = row == null ? 0 : row.size(); } totalSize += rowLen; } final WritableFloatChunk result = WritableFloatChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); result.setSize(0); if (offsetsDest != null) { @@ -66,15 +72,31 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, result.size()); } - if (row == null) { - continue; + if (row != null) { + final FloatConsumer consumer = result::add; + try (final CloseablePrimitiveIteratorOfFloat iter = row.iterator()) { + Stream stream = iter.stream(); + if (fixedSizeLength > 0) { + // limit length to fixedSizeLength + stream = iter.stream().limit(fixedSizeLength); + } else if (fixedSizeLength < 0) { + final long numToSkip = Math.max(0, row.size() + fixedSizeLength); + if (numToSkip > 0) { + // read from the end of the array when fixedSizeLength is negative + stream = stream.skip(numToSkip); + } + } + // copy the row into the result + stream.forEach(consumer::accept); + } } - final FloatConsumer consumer = result::add; - try (final CloseablePrimitiveIteratorOfFloat iter = row.iterator()) { - if (fixedSizeLength > 0) { - iter.stream().limit(fixedSizeLength).forEach(consumer::accept); - } else { - iter.forEachRemaining(consumer); + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - (row == null ? 0 : row.size()))); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(result.size(), toNull); + result.setSize(result.size() + toNull); } } } diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/IntVectorExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/IntVectorExpansionKernel.java index f3fed8ad122..248e40857b6 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/IntVectorExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/IntVectorExpansionKernel.java @@ -27,11 +27,15 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.stream.Stream; + import static io.deephaven.vector.IntVectorDirect.ZERO_LENGTH_VECTOR; public class IntVectorExpansionKernel implements VectorExpansionKernel { public final static IntVectorExpansionKernel INSTANCE = new IntVectorExpansionKernel(); + private static final String DEBUG_NAME = "IntVectorExpansionKernel"; + @Override public WritableChunk expand( @NotNull final ObjectChunk source, @@ -49,14 +53,16 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < typedSource.size(); ++ii) { final IntVector row = typedSource.get(ii); - long rowLen = row == null ? 0 : row.size(); - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + long rowLen; + if (fixedSizeLength != 0) { + rowLen = Math.abs(fixedSizeLength); + } else { + rowLen = row == null ? 0 : row.size(); } totalSize += rowLen; } final WritableIntChunk result = WritableIntChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); result.setSize(0); if (offsetsDest != null) { @@ -67,15 +73,31 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, result.size()); } - if (row == null) { - continue; + if (row != null) { + final IntConsumer consumer = result::add; + try (final CloseablePrimitiveIteratorOfInt iter = row.iterator()) { + Stream stream = iter.stream(); + if (fixedSizeLength > 0) { + // limit length to fixedSizeLength + stream = iter.stream().limit(fixedSizeLength); + } else if (fixedSizeLength < 0) { + final long numToSkip = Math.max(0, row.size() + fixedSizeLength); + if (numToSkip > 0) { + // read from the end of the array when fixedSizeLength is negative + stream = stream.skip(numToSkip); + } + } + // copy the row into the result + stream.forEach(consumer::accept); + } } - final IntConsumer consumer = result::add; - try (final CloseablePrimitiveIteratorOfInt iter = row.iterator()) { - if (fixedSizeLength > 0) { - iter.stream().limit(fixedSizeLength).forEach(consumer::accept); - } else { - iter.forEachRemaining(consumer); + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - (row == null ? 0 : row.size()))); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(result.size(), toNull); + result.setSize(result.size() + toNull); } } } diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/LongVectorExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/LongVectorExpansionKernel.java index c346ba3859a..a28894dc059 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/LongVectorExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/LongVectorExpansionKernel.java @@ -27,11 +27,15 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.stream.Stream; + import static io.deephaven.vector.LongVectorDirect.ZERO_LENGTH_VECTOR; public class LongVectorExpansionKernel implements VectorExpansionKernel { public final static LongVectorExpansionKernel INSTANCE = new LongVectorExpansionKernel(); + private static final String DEBUG_NAME = "LongVectorExpansionKernel"; + @Override public WritableChunk expand( @NotNull final ObjectChunk source, @@ -49,14 +53,16 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < typedSource.size(); ++ii) { final LongVector row = typedSource.get(ii); - long rowLen = row == null ? 0 : row.size(); - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + long rowLen; + if (fixedSizeLength != 0) { + rowLen = Math.abs(fixedSizeLength); + } else { + rowLen = row == null ? 0 : row.size(); } totalSize += rowLen; } final WritableLongChunk result = WritableLongChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); result.setSize(0); if (offsetsDest != null) { @@ -67,15 +73,31 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, result.size()); } - if (row == null) { - continue; + if (row != null) { + final LongConsumer consumer = result::add; + try (final CloseablePrimitiveIteratorOfLong iter = row.iterator()) { + Stream stream = iter.stream(); + if (fixedSizeLength > 0) { + // limit length to fixedSizeLength + stream = iter.stream().limit(fixedSizeLength); + } else if (fixedSizeLength < 0) { + final long numToSkip = Math.max(0, row.size() + fixedSizeLength); + if (numToSkip > 0) { + // read from the end of the array when fixedSizeLength is negative + stream = stream.skip(numToSkip); + } + } + // copy the row into the result + stream.forEach(consumer::accept); + } } - final LongConsumer consumer = result::add; - try (final CloseablePrimitiveIteratorOfLong iter = row.iterator()) { - if (fixedSizeLength > 0) { - iter.stream().limit(fixedSizeLength).forEach(consumer::accept); - } else { - iter.forEachRemaining(consumer); + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - (row == null ? 0 : row.size()))); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(result.size(), toNull); + result.setSize(result.size() + toNull); } } } diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/ObjectVectorExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/ObjectVectorExpansionKernel.java index d28b00d5064..f18de255dca 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/ObjectVectorExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/ObjectVectorExpansionKernel.java @@ -20,8 +20,11 @@ import org.jetbrains.annotations.Nullable; import java.lang.reflect.Array; +import java.util.stream.Stream; public class ObjectVectorExpansionKernel implements VectorExpansionKernel> { + private static final String DEBUG_NAME = "ObjectVectorExpansionKernel"; + private final Class componentType; public ObjectVectorExpansionKernel(final Class componentType) { @@ -45,14 +48,16 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < typedSource.size(); ++ii) { final ObjectVector row = typedSource.get(ii); - long rowLen = row == null ? 0 : row.size(); - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + long rowLen; + if (fixedSizeLength != 0) { + rowLen = Math.abs(fixedSizeLength); + } else { + rowLen = row == null ? 0 : row.size(); } totalSize += rowLen; } final WritableObjectChunk result = WritableObjectChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); result.setSize(0); if (offsetsDest != null) { @@ -63,16 +68,32 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, result.size()); } - if (row == null) { - continue; - } - try (final CloseableIterator iter = row.iterator()) { - if (fixedSizeLength > 0) { - // noinspection unchecked - iter.stream().limit(fixedSizeLength).forEach(v -> result.add((T) v)); - } else { + if (row != null) { + try (final CloseableIterator iter = row.iterator()) { + Stream stream = iter.stream(); + if (fixedSizeLength > 0) { + // limit length to fixedSizeLength + stream = stream.limit(fixedSizeLength); + } else if (fixedSizeLength < 0) { + final long numToSkip = Math.max(0, row.size() + fixedSizeLength); + if (numToSkip > 0) { + // read from the end of the array when fixedSizeLength is negative + stream = stream.skip(numToSkip); + } + } + + // copy the row into the result // noinspection unchecked - iter.forEachRemaining(v -> result.add((T) v)); + stream.forEach(v -> result.add((T) v)); + } + } + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - (row == null ? 0 : row.size()))); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(result.size(), toNull); + result.setSize(result.size() + toNull); } } } diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/ShortVectorExpansionKernel.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/ShortVectorExpansionKernel.java index 2f2ce6a244e..500161bbc79 100644 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/ShortVectorExpansionKernel.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/vector/ShortVectorExpansionKernel.java @@ -26,11 +26,15 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.stream.Stream; + import static io.deephaven.vector.ShortVectorDirect.ZERO_LENGTH_VECTOR; public class ShortVectorExpansionKernel implements VectorExpansionKernel { public final static ShortVectorExpansionKernel INSTANCE = new ShortVectorExpansionKernel(); + private static final String DEBUG_NAME = "ShortVectorExpansionKernel"; + @Override public WritableChunk expand( @NotNull final ObjectChunk source, @@ -48,14 +52,16 @@ public WritableChunk expand( long totalSize = 0; for (int ii = 0; ii < typedSource.size(); ++ii) { final ShortVector row = typedSource.get(ii); - long rowLen = row == null ? 0 : row.size(); - if (fixedSizeLength > 0) { - rowLen = Math.min(rowLen, fixedSizeLength); + long rowLen; + if (fixedSizeLength != 0) { + rowLen = Math.abs(fixedSizeLength); + } else { + rowLen = row == null ? 0 : row.size(); } totalSize += rowLen; } final WritableShortChunk result = WritableShortChunk.makeWritableChunk( - LongSizedDataStructure.intSize("ExpansionKernel", totalSize)); + LongSizedDataStructure.intSize(DEBUG_NAME, totalSize)); result.setSize(0); if (offsetsDest != null) { @@ -66,15 +72,31 @@ public WritableChunk expand( if (offsetsDest != null) { offsetsDest.set(ii, result.size()); } - if (row == null) { - continue; + if (row != null) { + final ShortConsumer consumer = result::add; + try (final CloseablePrimitiveIteratorOfShort iter = row.iterator()) { + Stream stream = iter.stream(); + if (fixedSizeLength > 0) { + // limit length to fixedSizeLength + stream = iter.stream().limit(fixedSizeLength); + } else if (fixedSizeLength < 0) { + final long numToSkip = Math.max(0, row.size() + fixedSizeLength); + if (numToSkip > 0) { + // read from the end of the array when fixedSizeLength is negative + stream = stream.skip(numToSkip); + } + } + // copy the row into the result + stream.forEach(consumer::accept); + } } - final ShortConsumer consumer = result::add; - try (final CloseablePrimitiveIteratorOfShort iter = row.iterator()) { - if (fixedSizeLength > 0) { - iter.stream().limit(fixedSizeLength).forEach(consumer::accept); - } else { - iter.forEachRemaining(consumer); + if (fixedSizeLength != 0) { + final int toNull = LongSizedDataStructure.intSize( + DEBUG_NAME, Math.max(0, Math.abs(fixedSizeLength) - (row == null ? 0 : row.size()))); + if (toNull > 0) { + // fill the rest of the row with nulls + result.fillWithNullValue(result.size(), toNull); + result.setSize(result.size() + toNull); } } } diff --git a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/util/BarrageUtil.java b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/util/BarrageUtil.java index 7358f587477..43a3bf8b634 100755 --- a/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/util/BarrageUtil.java +++ b/extensions/barrage/src/main/java/io/deephaven/extensions/barrage/util/BarrageUtil.java @@ -583,6 +583,9 @@ private static Class getDefaultType( final Class childType = getDefaultType(arrowField.getChildren().get(0), null); return Array.newInstance(childType, 0).getClass(); } + if (arrowField.getType().getTypeID() == ArrowType.ArrowTypeID.Union) { + return Object.class; + } throw Exceptions.statusRuntimeException(Code.INVALID_ARGUMENT, exMsg + " of type " + arrowField.getType().getTypeID().toString()); } diff --git a/extensions/barrage/src/main/resources/io/deephaven/extensions/barrage/Barrage.gwt.xml b/extensions/barrage/src/main/resources/io/deephaven/extensions/barrage/Barrage.gwt.xml index 3360608b9a7..f1f20a125b1 100644 --- a/extensions/barrage/src/main/resources/io/deephaven/extensions/barrage/Barrage.gwt.xml +++ b/extensions/barrage/src/main/resources/io/deephaven/extensions/barrage/Barrage.gwt.xml @@ -11,5 +11,6 @@ +