Skip to content

Commit 4b6315e

Browse files
committed
Commit #1 reading chunks, checkpoint to talk to nate, next will try reading schema at beginning of stream
1 parent 713a76f commit 4b6315e

9 files changed

Lines changed: 385 additions & 192 deletions

File tree

extensions/barrage/src/main/java/io/deephaven/extensions/barrage/chunk/ChunkInputStreamGenerator.java

Lines changed: 6 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import io.deephaven.chunk.attributes.Values;
1111
import io.deephaven.chunk.util.pools.PoolableChunk;
1212
import io.deephaven.engine.rowset.RowSet;
13-
import io.deephaven.extensions.barrage.ColumnConversionMode;
1413
import io.deephaven.extensions.barrage.util.DefensiveDrainable;
1514
import io.deephaven.extensions.barrage.util.StreamReaderOptions;
1615
import io.deephaven.time.DateTimeUtils;
@@ -19,7 +18,6 @@
1918
import io.deephaven.chunk.Chunk;
2019
import io.deephaven.chunk.ChunkType;
2120
import io.deephaven.util.SafeCloseable;
22-
import io.deephaven.util.type.TypeUtils;
2321
import io.deephaven.vector.Vector;
2422
import org.jetbrains.annotations.Nullable;
2523

@@ -31,7 +29,6 @@
3129
import java.time.LocalDate;
3230
import java.time.LocalTime;
3331
import java.time.ZonedDateTime;
34-
import java.util.Arrays;
3532
import java.util.Iterator;
3633
import java.util.PrimitiveIterator;
3734

@@ -187,6 +184,7 @@ static <T> ChunkInputStreamGenerator makeInputStreamGenerator(
187184
}
188185
}
189186

187+
@Deprecated
190188
static WritableChunk<Values> extractChunkFromInputStream(
191189
final StreamReaderOptions options,
192190
final ChunkType chunkType, final Class<?> type, final Class<?> componentType,
@@ -195,10 +193,10 @@ static WritableChunk<Values> extractChunkFromInputStream(
195193
final DataInput is,
196194
final WritableChunk<Values> outChunk, final int offset, final int totalRows) throws IOException {
197195
return extractChunkFromInputStream(options, 1, chunkType, type, componentType, fieldNodeIter, bufferInfoIter,
198-
is,
199-
outChunk, offset, totalRows);
196+
is, outChunk, offset, totalRows);
200197
}
201198

199+
@Deprecated
202200
static WritableChunk<Values> extractChunkFromInputStream(
203201
final StreamReaderOptions options,
204202
final int factor,
@@ -207,170 +205,9 @@ static WritableChunk<Values> extractChunkFromInputStream(
207205
final PrimitiveIterator.OfLong bufferInfoIter,
208206
final DataInput is,
209207
final WritableChunk<Values> outChunk, final int outOffset, final int totalRows) throws IOException {
210-
// TODO (deephaven-core#5453): pass in ArrowType to enable ser/deser of single java class in multiple formats
211-
switch (chunkType) {
212-
case Boolean:
213-
throw new UnsupportedOperationException("Booleans are reinterpreted as bytes");
214-
case Char:
215-
return CharChunkInputStreamGenerator.extractChunkFromInputStream(
216-
Character.BYTES, options, fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
217-
case Byte:
218-
if (type == Boolean.class || type == boolean.class) {
219-
return BooleanChunkInputStreamGenerator.extractChunkFromInputStream(
220-
options, fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
221-
}
222-
return ByteChunkInputStreamGenerator.extractChunkFromInputStream(
223-
Byte.BYTES, options, fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
224-
case Short:
225-
return ShortChunkInputStreamGenerator.extractChunkFromInputStream(
226-
Short.BYTES, options, fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
227-
case Int:
228-
return IntChunkInputStreamGenerator.extractChunkFromInputStream(
229-
Integer.BYTES, options, fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
230-
case Long:
231-
if (factor == 1) {
232-
return LongChunkInputStreamGenerator.extractChunkFromInputStream(
233-
Long.BYTES, options,
234-
fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
235-
}
236-
return LongChunkInputStreamGenerator.extractChunkFromInputStreamWithConversion(
237-
Long.BYTES, options,
238-
(long v) -> v == QueryConstants.NULL_LONG ? QueryConstants.NULL_LONG : (v * factor),
239-
fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
240-
case Float:
241-
return FloatChunkInputStreamGenerator.extractChunkFromInputStream(
242-
Float.BYTES, options, fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
243-
case Double:
244-
return DoubleChunkInputStreamGenerator.extractChunkFromInputStream(
245-
Double.BYTES, options, fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
246-
case Object:
247-
if (type.isArray()) {
248-
if (componentType == byte.class) {
249-
return VarBinaryChunkInputStreamGenerator.extractChunkFromInputStream(
250-
is,
251-
fieldNodeIter,
252-
bufferInfoIter,
253-
(buf, off, len) -> Arrays.copyOfRange(buf, off, off + len),
254-
outChunk, outOffset, totalRows);
255-
} else {
256-
return VarListChunkInputStreamGenerator.extractChunkFromInputStream(
257-
options, type, fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
258-
}
259-
}
260-
if (Vector.class.isAssignableFrom(type)) {
261-
// noinspection unchecked
262-
return VectorChunkInputStreamGenerator.extractChunkFromInputStream(
263-
options, (Class<Vector<?>>) type, componentType, fieldNodeIter, bufferInfoIter, is,
264-
outChunk, outOffset, totalRows);
265-
}
266-
if (type == BigInteger.class) {
267-
return VarBinaryChunkInputStreamGenerator.extractChunkFromInputStream(
268-
is,
269-
fieldNodeIter,
270-
bufferInfoIter,
271-
BigInteger::new,
272-
outChunk, outOffset, totalRows);
273-
}
274-
if (type == BigDecimal.class) {
275-
return VarBinaryChunkInputStreamGenerator.extractChunkFromInputStream(
276-
is,
277-
fieldNodeIter,
278-
bufferInfoIter,
279-
(final byte[] buf, final int offset, final int length) -> {
280-
// read the int scale value as little endian, arrow's endianness.
281-
final byte b1 = buf[offset];
282-
final byte b2 = buf[offset + 1];
283-
final byte b3 = buf[offset + 2];
284-
final byte b4 = buf[offset + 3];
285-
final int scale = b4 << 24 | (b3 & 0xFF) << 16 | (b2 & 0xFF) << 8 | (b1 & 0xFF);
286-
return new BigDecimal(new BigInteger(buf, offset + 4, length - 4), scale);
287-
},
288-
outChunk, outOffset, totalRows);
289-
}
290-
if (type == Instant.class) {
291-
return FixedWidthChunkInputStreamGenerator.extractChunkFromInputStreamWithTypeConversion(
292-
Long.BYTES, options, io -> {
293-
final long value = io.readLong();
294-
if (value == QueryConstants.NULL_LONG) {
295-
return null;
296-
}
297-
return DateTimeUtils.epochNanosToInstant(value * factor);
298-
},
299-
fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
300-
}
301-
if (type == ZonedDateTime.class) {
302-
return FixedWidthChunkInputStreamGenerator.extractChunkFromInputStreamWithTypeConversion(
303-
Long.BYTES, options, io -> {
304-
final long value = io.readLong();
305-
if (value == QueryConstants.NULL_LONG) {
306-
return null;
307-
}
308-
return DateTimeUtils.epochNanosToZonedDateTime(
309-
value * factor, DateTimeUtils.timeZone());
310-
},
311-
fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
312-
}
313-
if (type == Byte.class) {
314-
return FixedWidthChunkInputStreamGenerator.extractChunkFromInputStreamWithTypeConversion(
315-
Byte.BYTES, options, io -> TypeUtils.box(io.readByte()),
316-
fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
317-
}
318-
if (type == Character.class) {
319-
return FixedWidthChunkInputStreamGenerator.extractChunkFromInputStreamWithTypeConversion(
320-
Character.BYTES, options, io -> TypeUtils.box(io.readChar()),
321-
fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
322-
}
323-
if (type == Double.class) {
324-
return FixedWidthChunkInputStreamGenerator.extractChunkFromInputStreamWithTypeConversion(
325-
Double.BYTES, options, io -> TypeUtils.box(io.readDouble()),
326-
fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
327-
}
328-
if (type == Float.class) {
329-
return FixedWidthChunkInputStreamGenerator.extractChunkFromInputStreamWithTypeConversion(
330-
Float.BYTES, options, io -> TypeUtils.box(io.readFloat()),
331-
fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
332-
}
333-
if (type == Integer.class) {
334-
return FixedWidthChunkInputStreamGenerator.extractChunkFromInputStreamWithTypeConversion(
335-
Integer.BYTES, options, io -> TypeUtils.box(io.readInt()),
336-
fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
337-
}
338-
if (type == Long.class) {
339-
return FixedWidthChunkInputStreamGenerator.extractChunkFromInputStreamWithTypeConversion(
340-
Long.BYTES, options, io -> TypeUtils.box(io.readLong()),
341-
fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
342-
}
343-
if (type == Short.class) {
344-
return FixedWidthChunkInputStreamGenerator.extractChunkFromInputStreamWithTypeConversion(
345-
Short.BYTES, options, io -> TypeUtils.box(io.readShort()),
346-
fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
347-
}
348-
if (type == LocalDate.class) {
349-
return LongChunkInputStreamGenerator.extractChunkFromInputStreamWithTransform(
350-
Long.BYTES, options,
351-
value -> value == QueryConstants.NULL_LONG
352-
? null
353-
: LocalDate.ofEpochDay(value / MS_PER_DAY),
354-
fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
355-
}
356-
if (type == LocalTime.class) {
357-
return LongChunkInputStreamGenerator.extractChunkFromInputStreamWithTransform(
358-
Long.BYTES, options,
359-
value -> value == QueryConstants.NULL_LONG ? null : LocalTime.ofNanoOfDay(value),
360-
fieldNodeIter, bufferInfoIter, is, outChunk, outOffset, totalRows);
361-
}
362-
if (type == String.class ||
363-
options.columnConversionMode().equals(ColumnConversionMode.Stringify)) {
364-
return VarBinaryChunkInputStreamGenerator.extractChunkFromInputStream(is, fieldNodeIter,
365-
bufferInfoIter,
366-
(buf, off, len) -> new String(buf, off, len, Charsets.UTF_8), outChunk, outOffset,
367-
totalRows);
368-
}
369-
throw new UnsupportedOperationException(
370-
"Do not yet support column conversion mode: " + options.columnConversionMode());
371-
default:
372-
throw new UnsupportedOperationException();
373-
}
208+
return DefaultChunkReadingFactory.INSTANCE.extractChunkFromInputStream(options, factor,
209+
new ChunkReadingFactory.ChunkTypeInfo(chunkType, type, componentType, null), fieldNodeIter,
210+
bufferInfoIter, is, outChunk, outOffset, totalRows);
374211
}
375212

376213
/**
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
//
2+
// Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending
3+
//
4+
package io.deephaven.extensions.barrage.chunk;
5+
6+
import io.deephaven.chunk.ChunkType;
7+
import io.deephaven.chunk.WritableChunk;
8+
import io.deephaven.chunk.attributes.Values;
9+
import io.deephaven.extensions.barrage.util.StreamReaderOptions;
10+
import org.apache.arrow.flatbuf.Field;
11+
import org.apache.arrow.flatbuf.Type;
12+
13+
import java.io.DataInput;
14+
import java.io.IOException;
15+
import java.util.Iterator;
16+
import java.util.PrimitiveIterator;
17+
18+
/**
19+
*
20+
*/
21+
public interface ChunkReadingFactory {
22+
/**
23+
*
24+
*/
25+
class ChunkTypeInfo {
26+
private final ChunkType chunkType;
27+
private final Class<?> type;
28+
private final Class<?> componentType;
29+
private final Field arrowField;
30+
31+
public ChunkTypeInfo(ChunkType chunkType, Class<?> type, Class<?> componentType, Field arrowField) {
32+
this.chunkType = chunkType;
33+
this.type = type;
34+
this.componentType = componentType;
35+
this.arrowField = arrowField;
36+
}
37+
38+
public ChunkType chunkType() {
39+
return chunkType;
40+
}
41+
42+
public Class<?> type() {
43+
return type;
44+
}
45+
46+
public Class<?> componentType() {
47+
return componentType;
48+
}
49+
50+
public Field arrowField() {
51+
return arrowField;
52+
}
53+
54+
public Field componentArrowField() {
55+
if (arrowField.typeType() != Type.List) {
56+
throw new IllegalStateException("Not a flight List");
57+
}
58+
if (arrowField.childrenLength() != 1) {
59+
throw new IllegalStateException("Incorrect number of child Fields");
60+
}
61+
return arrowField.children(0);
62+
}
63+
}
64+
65+
/**
66+
*
67+
* @param options
68+
* @param factor
69+
* @param typeInfo
70+
* @param fieldNodeIter
71+
* @param bufferInfoIter
72+
* @param is
73+
* @param outChunk
74+
* @param outOffset
75+
* @param totalRows
76+
* @return
77+
* @throws IOException
78+
*/
79+
WritableChunk<Values> extractChunkFromInputStream(
80+
final StreamReaderOptions options,
81+
final int factor,
82+
final ChunkTypeInfo typeInfo,
83+
final Iterator<ChunkInputStreamGenerator.FieldNodeInfo> fieldNodeIter,
84+
final PrimitiveIterator.OfLong bufferInfoIter,
85+
final DataInput is,
86+
final WritableChunk<Values> outChunk,
87+
final int outOffset,
88+
final int totalRows) throws IOException;
89+
90+
/**
91+
*
92+
* @param options
93+
* @param typeInfo
94+
* @param fieldNodeIter
95+
* @param bufferInfoIter
96+
* @param is
97+
* @param outChunk
98+
* @param offset
99+
* @param totalRows
100+
* @return
101+
* @throws IOException
102+
*/
103+
default WritableChunk<Values> extractChunkFromInputStream(
104+
final StreamReaderOptions options,
105+
final ChunkTypeInfo typeInfo,
106+
final Iterator<ChunkInputStreamGenerator.FieldNodeInfo> fieldNodeIter,
107+
final PrimitiveIterator.OfLong bufferInfoIter,
108+
final DataInput is,
109+
final WritableChunk<Values> outChunk,
110+
final int offset,
111+
final int totalRows) throws IOException {
112+
return extractChunkFromInputStream(options, 1, typeInfo, fieldNodeIter, bufferInfoIter, is, outChunk, offset,
113+
totalRows);
114+
}
115+
116+
}

0 commit comments

Comments
 (0)