Skip to content

Commit 513fc09

Browse files
dfa1claude
andcommitted
perf: hoist all ValueLayout instances to static final
The big-file benchmark fix (commit da10f65) demonstrated a 7.2x speedup from promoting one inline `ValueLayout.JAVA_LONG_UNALIGNED .withOrder(LE)` to a class-level static final. The same anti-pattern was duplicated across most codecs and the scan iterator. Each call site was building a fresh ValueLayout instance, preventing the JIT from constant-folding the underlying VarHandle and unblocking auto-vectorisation of the surrounding loop. Sweep every main-code occurrence and convert to `private static final ValueLayout.OfXxx LE_XXX = ...`: - PType.valueLayout(): return shared instances instead of building one per call (factory was on the hot path for any caller routing by ptype) - SparseCodec.readUnsignedIdx / readElem switches - FrameOfReferenceCodec.applyReference hot loops (I16/I32/I64) - AlpCodec.readUnsigned (LE_SHORT field was missing alongside the existing LE_INT/LE_LONG/LE_FLOAT/LE_DOUBLE set) - ConstantCodec offset-writer loop - DictCodec.expandU16/expandU32/readCode - FsstCodec.readUnsigned U16 branch - ScanIterator.dict-layout reconstruction (outOffLayout, readUnsigned) and readFlatStats stats-tail read VortexReader and FsstCodec already had the right pattern for a subset of layouts — extended to cover the remaining branches so no codec drops back into the per-call instantiation trap. Tests left untouched: not on the hot path, and the inline form is easier to read inside one-shot test fixtures. CLAUDE.md / the review-performance skill already document the rule; this commit brings the codebase in line with both. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 65c9c5f commit 513fc09

8 files changed

Lines changed: 60 additions & 58 deletions

File tree

core/src/main/java/io/github/dfa1/vortex/core/PType.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ public enum PType {
88
I8, I16, I32, I64,
99
F16, F32, F64;
1010

11+
private static final ValueLayout.OfShort LE_SHORT = ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
12+
private static final ValueLayout.OfInt LE_INT = ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
13+
private static final ValueLayout.OfLong LE_LONG = ValueLayout.JAVA_LONG_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
14+
private static final ValueLayout.OfFloat LE_FLOAT = ValueLayout.JAVA_FLOAT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
15+
private static final ValueLayout.OfDouble LE_DOUBLE = ValueLayout.JAVA_DOUBLE_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
16+
1117
public int byteSize() {
1218
return switch (this) {
1319
case U8, I8 -> 1;
@@ -26,15 +32,16 @@ public boolean isSigned() {
2632
|| this == F16 || this == F32 || this == F64;
2733
}
2834

29-
/// Little-endian, unaligned `ValueLayout` for this ptype.
35+
/// Little-endian, unaligned `ValueLayout` for this ptype. Returns a shared `static final`
36+
/// instance so the JIT can constant-fold the VarHandle and vectorise hot loops.
3037
public ValueLayout valueLayout() {
3138
return switch (this) {
3239
case I8, U8 -> ValueLayout.JAVA_BYTE;
33-
case I16, U16 -> ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
34-
case I32, U32 -> ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
35-
case I64, U64 -> ValueLayout.JAVA_LONG_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
36-
case F32 -> ValueLayout.JAVA_FLOAT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
37-
case F64 -> ValueLayout.JAVA_DOUBLE_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
40+
case I16, U16 -> LE_SHORT;
41+
case I32, U32 -> LE_INT;
42+
case I64, U64 -> LE_LONG;
43+
case F32 -> LE_FLOAT;
44+
case F64 -> LE_DOUBLE;
3845
case F16 -> throw new UnsupportedOperationException("F16 not supported"); // TODO: implement F16
3946
};
4047
}

core/src/main/java/io/github/dfa1/vortex/encoding/AlpCodec.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public final class AlpCodec implements Codec {
4949
1e-0f, 1e-1f, 1e-2f, 1e-3f, 1e-4f, 1e-5f, 1e-6f, 1e-7f, 1e-8f, 1e-9f, 1e-10f
5050
};
5151

52+
private static final ValueLayout.OfShort LE_SHORT = ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
5253
private static final ValueLayout.OfLong LE_LONG = ValueLayout.JAVA_LONG_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
5354
private static final ValueLayout.OfDouble LE_DOUBLE = ValueLayout.JAVA_DOUBLE_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
5455
private static final ValueLayout.OfInt LE_INT = ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
@@ -67,12 +68,9 @@ private static Array decodeChildAs(DecodeContext parent, int childIdx, DType dty
6768
private static long readUnsigned(MemorySegment seg, long i, PType ptype) {
6869
return switch (ptype) {
6970
case U8 -> Byte.toUnsignedLong(seg.get(ValueLayout.JAVA_BYTE, i));
70-
case U16 -> Short.toUnsignedLong(
71-
seg.get(ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN), i * 2));
72-
case U32 -> Integer.toUnsignedLong(
73-
seg.get(ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN), i * 4));
74-
case U64 -> seg.get(
75-
ValueLayout.JAVA_LONG_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN), i * 8);
71+
case U16 -> Short.toUnsignedLong(seg.get(LE_SHORT, i * 2));
72+
case U32 -> Integer.toUnsignedLong(seg.get(LE_INT, i * 4));
73+
case U64 -> seg.get(LE_LONG, i * 8);
7674
default -> throw new IllegalStateException("vortex.alp: non-unsigned patch index ptype " + ptype);
7775
};
7876
}

core/src/main/java/io/github/dfa1/vortex/encoding/ConstantCodec.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
/// <p>Decode: fill an output buffer of {@code rowCount} elements with the constant value.
2222
public final class ConstantCodec implements Codec {
2323

24+
private static final ValueLayout.OfInt LE_INT = ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
25+
2426
private static long scalarToRawBits(ScalarProtos.ScalarValue scalar, PType ptype) {
2527
return switch (scalar.getKindCase()) {
2628
case INT64_VALUE -> scalar.getInt64Value();
@@ -105,10 +107,9 @@ private static Array decodeString(DecodeContext ctx, ScalarProtos.ScalarValue sc
105107

106108
// Offsets: n+1 I32 values, alternating start/end of the single string.
107109
MemorySegment offsetsSeg = ctx.arena().allocate((n + 1) * 4L, 4);
108-
var layout = ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
109110
for (long i = 0; i <= n; i++) {
110111
// even index → 0 (start), odd → strLen (end); wraps back to 0 for the next string's start
111-
offsetsSeg.setAtIndex(layout, i, (i % 2 == 0) ? 0 : strLen);
112+
offsetsSeg.setAtIndex(LE_INT, i, (i % 2 == 0) ? 0 : strLen);
112113
}
113114

114115
Array offsets = new Array(new DType.Primitive(PType.I32, false), n + 1,

core/src/main/java/io/github/dfa1/vortex/encoding/DictCodec.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
/// Node tree: DictNode{ children=[ValuesNode{buf=0},CodesNode{buf=1}] }.
2222
public final class DictCodec implements Codec {
2323

24+
private static final ValueLayout.OfShort LE_SHORT = ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
25+
private static final ValueLayout.OfInt LE_INT = ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
26+
2427
private static Array decodeChildAs(DecodeContext parent, int childIdx, DType dtype, long rowCount) {
2528
ArrayNode childNode = parent.node().children()[childIdx];
2629
DecodeContext childCtx = new DecodeContext(
@@ -145,9 +148,8 @@ private static void expandU16(
145148
MemorySegment codes, MemorySegment values, MemorySegment out,
146149
long rowCount, int elemSize
147150
) {
148-
var layout = ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
149151
for (long i = 0, outOff = 0; i < rowCount; i++, outOff += elemSize) {
150-
long code = Short.toUnsignedLong(codes.get(layout, i * 2));
152+
long code = Short.toUnsignedLong(codes.get(LE_SHORT, i * 2));
151153
MemorySegment.copy(values, code * elemSize, out, outOff, elemSize);
152154
}
153155
}
@@ -156,20 +158,17 @@ private static void expandU32(
156158
MemorySegment codes, MemorySegment values, MemorySegment out,
157159
long rowCount, int elemSize
158160
) {
159-
var layout = ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
160161
for (long i = 0, outOff = 0; i < rowCount; i++, outOff += elemSize) {
161-
long code = Integer.toUnsignedLong(codes.get(layout, i * 4));
162+
long code = Integer.toUnsignedLong(codes.get(LE_INT, i * 4));
162163
MemorySegment.copy(values, code * elemSize, out, outOff, elemSize);
163164
}
164165
}
165166

166167
private static long readCode(MemorySegment buf, PType codePType, long i) {
167168
return switch (codePType) {
168169
case U8 -> Byte.toUnsignedLong(buf.get(ValueLayout.JAVA_BYTE, i));
169-
case U16 -> Short.toUnsignedLong(
170-
buf.get(ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN), i * 2));
171-
case U32 -> Integer.toUnsignedLong(
172-
buf.get(ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN), i * 4));
170+
case U16 -> Short.toUnsignedLong(buf.get(LE_SHORT, i * 2));
171+
case U32 -> Integer.toUnsignedLong(buf.get(LE_INT, i * 4));
173172
default -> throw new IllegalStateException("unexpected code type: " + codePType);
174173
};
175174
}

core/src/main/java/io/github/dfa1/vortex/encoding/FrameOfReferenceCodec.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
/// Decode: {@code output[i] = encoded[i] + reference} (wrapping arithmetic).
2222
public final class FrameOfReferenceCodec implements Codec {
2323

24+
private static final ValueLayout.OfShort LE_SHORT = ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
25+
private static final ValueLayout.OfInt LE_INT = ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
26+
private static final ValueLayout.OfLong LE_LONG = ValueLayout.JAVA_LONG_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
27+
2428
private static long referenceValue(ScalarProtos.ScalarValue scalar) {
2529
return switch (scalar.getKindCase()) {
2630
case INT64_VALUE -> scalar.getInt64Value();
@@ -42,24 +46,21 @@ private static MemorySegment applyReference(MemorySegment src, long n, PType pty
4246
}
4347
}
4448
case I16, U16 -> {
45-
var layout = ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
4649
for (long off = 0, end = n * 2; off < end; off += 2) {
47-
short v = src.get(layout, off);
48-
dst.set(layout, off, (short) (v + (short) ref));
50+
short v = src.get(LE_SHORT, off);
51+
dst.set(LE_SHORT, off, (short) (v + (short) ref));
4952
}
5053
}
5154
case I32, U32 -> {
52-
var layout = ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
5355
for (long off = 0, end = n * 4; off < end; off += 4) {
54-
int v = src.get(layout, off);
55-
dst.set(layout, off, v + (int) ref);
56+
int v = src.get(LE_INT, off);
57+
dst.set(LE_INT, off, v + (int) ref);
5658
}
5759
}
5860
case I64, U64 -> {
59-
var layout = ValueLayout.JAVA_LONG_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
6061
for (long off = 0, end = n * 8; off < end; off += 8) {
61-
long v = src.get(layout, off);
62-
dst.set(layout, off, v + ref);
62+
long v = src.get(LE_LONG, off);
63+
dst.set(LE_LONG, off, v + ref);
6364
}
6465
}
6566
default -> throw new UnsupportedOperationException(

core/src/main/java/io/github/dfa1/vortex/encoding/FsstCodec.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public final class FsstCodec implements Codec {
3030

3131
private static final ValueLayout.OfLong LE_LONG = ValueLayout.JAVA_LONG_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
3232
private static final ValueLayout.OfInt LE_INT = ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
33+
private static final ValueLayout.OfShort LE_SHORT = ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
3334

3435
@Override
3536
public CodecId encodingId() {
@@ -131,8 +132,7 @@ private static long decompressString(
131132
private static long readUnsigned(MemorySegment seg, long idx, PType ptype) {
132133
return switch (ptype) {
133134
case U8 -> Byte.toUnsignedLong(seg.get(ValueLayout.JAVA_BYTE, idx));
134-
case U16 -> Short.toUnsignedLong(seg.get(
135-
ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN), idx * 2));
135+
case U16 -> Short.toUnsignedLong(seg.get(LE_SHORT, idx * 2));
136136
case U32 -> Integer.toUnsignedLong(seg.getAtIndex(LE_INT, idx));
137137
case I32 -> seg.getAtIndex(LE_INT, idx);
138138
case I64, U64 -> seg.getAtIndex(LE_LONG, idx);

core/src/main/java/io/github/dfa1/vortex/encoding/SparseCodec.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
/// {@code output[indices[i] - offset] = values[i]} for each patch.
2727
public final class SparseCodec implements Codec {
2828

29+
private static final ValueLayout.OfShort LE_SHORT = ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
30+
private static final ValueLayout.OfInt LE_INT = ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
31+
private static final ValueLayout.OfLong LE_LONG = ValueLayout.JAVA_LONG_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
32+
2933
private static Array decodeChildWithDtype(DecodeContext parent, int childIdx, DType dtype, long rowCount) {
3034
ArrayNode childNode = parent.node().children()[childIdx];
3135
DecodeContext childCtx = new DecodeContext(
@@ -70,24 +74,19 @@ private static void applyPatches(
7074
private static long readUnsignedIdx(MemorySegment seg, long i, PType ptype) {
7175
return switch (ptype) {
7276
case U8 -> Byte.toUnsignedLong(seg.get(ValueLayout.JAVA_BYTE, i));
73-
case U16 -> Short.toUnsignedLong(
74-
seg.get(ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN), i * 2));
75-
case U32 -> Integer.toUnsignedLong(
76-
seg.get(ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN), i * 4));
77-
case U64 -> seg.get(ValueLayout.JAVA_LONG_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN), i * 8);
77+
case U16 -> Short.toUnsignedLong(seg.get(LE_SHORT, i * 2));
78+
case U32 -> Integer.toUnsignedLong(seg.get(LE_INT, i * 4));
79+
case U64 -> seg.get(LE_LONG, i * 8);
7880
default -> throw new IllegalStateException("vortex.sparse: non-unsigned index ptype " + ptype);
7981
};
8082
}
8183

8284
private static long readElem(MemorySegment seg, long i, PType ptype) {
8385
return switch (ptype) {
8486
case I8, U8 -> Byte.toUnsignedLong(seg.get(ValueLayout.JAVA_BYTE, i));
85-
case I16, U16 -> Short.toUnsignedLong(
86-
seg.get(ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN), i * 2));
87-
case I32, U32 -> Integer.toUnsignedLong(
88-
seg.get(ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN), i * 4));
89-
case I64, U64, F32, F64 ->
90-
seg.get(ValueLayout.JAVA_LONG_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN), i * 8);
87+
case I16, U16 -> Short.toUnsignedLong(seg.get(LE_SHORT, i * 2));
88+
case I32, U32 -> Integer.toUnsignedLong(seg.get(LE_INT, i * 4));
89+
case I64, U64, F32, F64 -> seg.get(LE_LONG, i * 8);
9190
default -> throw new UnsupportedOperationException("vortex.sparse: unsupported ptype " + ptype);
9291
};
9392
}

reader/src/main/java/io/github/dfa1/vortex/scan/ScanIterator.java

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
/// ```
3333
public final class ScanIterator implements AutoCloseable {
3434

35+
private static final ValueLayout.OfShort LE_SHORT = ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
36+
private static final ValueLayout.OfInt LE_INT = ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
37+
private static final ValueLayout.OfLong LE_LONG = ValueLayout.JAVA_LONG_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
38+
3539
private final VortexReader file;
3640
private final ScanOptions options;
3741
private final Arena arena;
@@ -275,8 +279,6 @@ private static Array expandDictStrings(
275279
PType valOffPType = ((DType.Primitive) values.child(0).dtype()).ptype();
276280
MemorySegment codesSegs = codes.buffer(0);
277281

278-
var outOffLayout = ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
279-
280282
// First pass: total output byte length
281283
long totalBytes = 0L;
282284
for (long i = 0; i < n; i++) {
@@ -288,7 +290,7 @@ private static Array expandDictStrings(
288290

289291
MemorySegment outBytes = arena.allocate(totalBytes > 0 ? totalBytes : 1);
290292
MemorySegment outOffsets = arena.allocate((n + 1) * 4L, 4);
291-
outOffsets.setAtIndex(outOffLayout, 0, 0);
293+
outOffsets.setAtIndex(LE_INT, 0, 0);
292294

293295
long bytePos = 0L;
294296
for (long i = 0; i < n; i++) {
@@ -300,7 +302,7 @@ private static Array expandDictStrings(
300302
MemorySegment.copy(valBytes, start, outBytes, bytePos, strLen);
301303
bytePos += strLen;
302304
}
303-
outOffsets.setAtIndex(outOffLayout, i + 1, (int) bytePos);
305+
outOffsets.setAtIndex(LE_INT, i + 1, (int) bytePos);
304306
}
305307

306308
Array offsetArr = new Array(new DType.Primitive(PType.I32, false), n + 1,
@@ -314,14 +316,10 @@ private static Array expandDictStrings(
314316
private static long readUnsigned(MemorySegment seg, long idx, PType ptype) {
315317
return switch (ptype) {
316318
case U8 -> Byte.toUnsignedLong(seg.get(ValueLayout.JAVA_BYTE, idx));
317-
case U16 -> Short.toUnsignedLong(seg.get(
318-
ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN), idx * 2));
319-
case U32 -> Integer.toUnsignedLong(seg.getAtIndex(
320-
ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN), idx));
321-
case I32 -> seg.getAtIndex(
322-
ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN), idx);
323-
case I64, U64 -> seg.getAtIndex(
324-
ValueLayout.JAVA_LONG_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN), idx);
319+
case U16 -> Short.toUnsignedLong(seg.get(LE_SHORT, idx * 2));
320+
case U32 -> Integer.toUnsignedLong(seg.getAtIndex(LE_INT, idx));
321+
case I32 -> seg.getAtIndex(LE_INT, idx);
322+
case I64, U64 -> seg.getAtIndex(LE_LONG, idx);
325323
default -> throw new IllegalArgumentException("dict layout: unsupported ptype " + ptype);
326324
};
327325
}
@@ -385,8 +383,7 @@ private ArrayStats readFlatStats(Layout flat) {
385383

386384
// Stats FlatBuffer lives in the segment's last 4+fbLen bytes; reading the whole
387385
// segment as a ByteBuffer would fail for segments larger than 2 GB (ByteBuffer cap).
388-
var leInt = ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
389-
int fbLen = seg.get(leInt, segLen - 4);
386+
int fbLen = seg.get(LE_INT, segLen - 4);
390387
long fbStart = segLen - 4L - fbLen;
391388
ByteBuffer fbBuf = seg.asSlice(fbStart, fbLen).asByteBuffer().order(ByteOrder.LITTLE_ENDIAN);
392389
var fbArray = io.github.dfa1.vortex.fbs.Array.getRootAsArray(fbBuf);

0 commit comments

Comments
 (0)