Skip to content

Commit 65817e2

Browse files
dfa1claude
andcommitted
refactor(encoding): centralize LE ValueLayout constants in PTypeIO
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1800dbf commit 65817e2

22 files changed

Lines changed: 155 additions & 254 deletions

TODO.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22

33
## Encodings
44

5-
- [ ] following code is copied over multiple classes => let's move them in PTypeIO
6-
private static final ValueLayout.OfShort LE_SHORT = ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
7-
private static final ValueLayout.OfInt LE_INT = ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
85
- [ ] in one case F32 and F64 are accepted but only F64 is really implemented
96
- [ ] the classes are very long of complex, most likely we should group the impl detail in private static inner classes Encoder/Decoder
107

core/src/main/java/io/github/dfa1/vortex/core/array/DoubleArray.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,15 @@
22

33
import io.github.dfa1.vortex.core.ArrayStats;
44
import io.github.dfa1.vortex.core.DType;
5+
import io.github.dfa1.vortex.encoding.PTypeIO;
56

67
import java.lang.foreign.MemorySegment;
7-
import java.lang.foreign.ValueLayout;
8-
import java.nio.ByteOrder;
98
import java.util.function.DoubleBinaryOperator;
109
import java.util.function.DoubleConsumer;
1110

12-
/// Concrete [Array] for F64 primitive columns. Hoists a single `MemorySegment`,
13-
/// length, and a `static final` LE double layout for JIT constant-folding and
14-
/// auto-vectorisation.
11+
/// Concrete [Array] for F64 primitive columns.
1512
public final class DoubleArray implements Array {
1613

17-
private static final ValueLayout.OfDouble LAYOUT =
18-
ValueLayout.JAVA_DOUBLE_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
19-
2014
private final DType dtype;
2115
private final long length;
2216
private final MemorySegment buffer;
@@ -53,14 +47,14 @@ public MemorySegment buffer(int i) {
5347
}
5448

5549
public double getDouble(long i) {
56-
return buffer.getAtIndex(LAYOUT, i);
50+
return buffer.getAtIndex(PTypeIO.LE_DOUBLE, i);
5751
}
5852

5953
public void forEachDouble(DoubleConsumer c) {
6054
MemorySegment buf = buffer;
6155
long n = length;
6256
for (long i = 0; i < n; i++) {
63-
c.accept(buf.getAtIndex(LAYOUT, i));
57+
c.accept(buf.getAtIndex(PTypeIO.LE_DOUBLE, i));
6458
}
6559
}
6660

@@ -69,7 +63,7 @@ public double fold(double identity, DoubleBinaryOperator op) {
6963
long n = length;
7064
double result = identity;
7165
for (long i = 0; i < n; i++) {
72-
result = op.applyAsDouble(result, buf.getAtIndex(LAYOUT, i));
66+
result = op.applyAsDouble(result, buf.getAtIndex(PTypeIO.LE_DOUBLE, i));
7367
}
7468
return result;
7569
}

core/src/main/java/io/github/dfa1/vortex/core/array/Float16Array.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,15 @@
22

33
import io.github.dfa1.vortex.core.ArrayStats;
44
import io.github.dfa1.vortex.core.DType;
5+
import io.github.dfa1.vortex.encoding.PTypeIO;
56

67
import java.lang.foreign.MemorySegment;
7-
import java.lang.foreign.ValueLayout;
8-
import java.nio.ByteOrder;
98

109
/// Concrete [Array] for F16 (IEEE 754 half-precision) columns.
1110
/// Wire format: little-endian shorts (2 bytes/element). Element access
1211
/// widens to `float` via [Float#float16ToFloat].
1312
public final class Float16Array implements Array {
1413

15-
private static final ValueLayout.OfShort LAYOUT =
16-
ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
17-
1814
private final DType dtype;
1915
private final long length;
2016
private final MemorySegment buffer;
@@ -51,6 +47,6 @@ public MemorySegment buffer(int i) {
5147
}
5248

5349
public float getFloat(long i) {
54-
return Float.float16ToFloat(buffer.getAtIndex(LAYOUT, i));
50+
return Float.float16ToFloat(buffer.getAtIndex(PTypeIO.LE_SHORT, i));
5551
}
5652
}

core/src/main/java/io/github/dfa1/vortex/core/array/FloatArray.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,13 @@
22

33
import io.github.dfa1.vortex.core.ArrayStats;
44
import io.github.dfa1.vortex.core.DType;
5+
import io.github.dfa1.vortex.encoding.PTypeIO;
56

67
import java.lang.foreign.MemorySegment;
7-
import java.lang.foreign.ValueLayout;
8-
import java.nio.ByteOrder;
98

10-
/// Concrete [Array] for F32 primitive columns. Hoists a single `MemorySegment`,
11-
/// length, and a `static final` LE float layout for JIT constant-folding.
9+
/// Concrete [Array] for F32 primitive columns.
1210
public final class FloatArray implements Array {
1311

14-
private static final ValueLayout.OfFloat LAYOUT =
15-
ValueLayout.JAVA_FLOAT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
16-
1712
private final DType dtype;
1813
private final long length;
1914
private final MemorySegment buffer;
@@ -50,6 +45,6 @@ public MemorySegment buffer(int i) {
5045
}
5146

5247
public float getFloat(long i) {
53-
return buffer.getAtIndex(LAYOUT, i);
48+
return buffer.getAtIndex(PTypeIO.LE_FLOAT, i);
5449
}
5550
}

core/src/main/java/io/github/dfa1/vortex/core/array/IntArray.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,13 @@
22

33
import io.github.dfa1.vortex.core.ArrayStats;
44
import io.github.dfa1.vortex.core.DType;
5+
import io.github.dfa1.vortex.encoding.PTypeIO;
56
import java.lang.foreign.MemorySegment;
6-
import java.lang.foreign.ValueLayout;
7-
import java.nio.ByteOrder;
87
import java.util.function.IntConsumer;
98

10-
/// Concrete [Array] for I32/U32 primitive columns. Hoists a single
11-
/// `MemorySegment`, length, and a `static final` LE int layout so the JIT can
12-
/// constant-fold the VarHandle and auto-vectorise hot loops.
9+
/// Concrete [Array] for I32/U32 primitive columns.
1310
public final class IntArray implements Array {
1411

15-
private static final ValueLayout.OfInt LAYOUT =
16-
ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
17-
1812
private final DType dtype;
1913
private final long length;
2014
private final MemorySegment buffer;
@@ -51,14 +45,14 @@ public MemorySegment buffer(int i) {
5145
}
5246

5347
public int getInt(long i) {
54-
return buffer.getAtIndex(LAYOUT, i);
48+
return buffer.getAtIndex(PTypeIO.LE_INT, i);
5549
}
5650

5751
public void forEachInt(IntConsumer c) {
5852
MemorySegment buf = buffer;
5953
long n = length;
6054
for (long i = 0; i < n; i++) {
61-
c.accept(buf.getAtIndex(LAYOUT, i));
55+
c.accept(buf.getAtIndex(PTypeIO.LE_INT, i));
6256
}
6357
}
6458
}

core/src/main/java/io/github/dfa1/vortex/core/array/LongArray.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,15 @@
22

33
import io.github.dfa1.vortex.core.ArrayStats;
44
import io.github.dfa1.vortex.core.DType;
5+
import io.github.dfa1.vortex.encoding.PTypeIO;
56

67
import java.lang.foreign.MemorySegment;
7-
import java.lang.foreign.ValueLayout;
8-
import java.nio.ByteOrder;
98
import java.util.function.LongBinaryOperator;
109
import java.util.function.LongConsumer;
1110

12-
/// Concrete [Array] for I64/U64 primitive columns. Hoists a single
13-
/// `MemorySegment`, length, and a `static final` LE long layout so the JIT can
14-
/// constant-fold the VarHandle and auto-vectorise hot loops.
11+
/// Concrete [Array] for I64/U64 primitive columns.
1512
public final class LongArray implements Array {
1613

17-
private static final ValueLayout.OfLong LAYOUT =
18-
ValueLayout.JAVA_LONG_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
19-
2014
private final DType dtype;
2115
private final long length;
2216
private final MemorySegment buffer;
@@ -53,14 +47,14 @@ public MemorySegment buffer(int i) {
5347
}
5448

5549
public long getLong(long i) {
56-
return buffer.getAtIndex(LAYOUT, i);
50+
return buffer.getAtIndex(PTypeIO.LE_LONG, i);
5751
}
5852

5953
public void forEachLong(LongConsumer c) {
6054
MemorySegment buf = buffer;
6155
long n = length;
6256
for (long i = 0; i < n; i++) {
63-
c.accept(buf.getAtIndex(LAYOUT, i));
57+
c.accept(buf.getAtIndex(PTypeIO.LE_LONG, i));
6458
}
6559
}
6660

@@ -69,7 +63,7 @@ public long fold(long identity, LongBinaryOperator op) {
6963
long n = length;
7064
long result = identity;
7165
for (long i = 0; i < n; i++) {
72-
result = op.applyAsLong(result, buf.getAtIndex(LAYOUT, i));
66+
result = op.applyAsLong(result, buf.getAtIndex(PTypeIO.LE_LONG, i));
7367
}
7468
return result;
7569
}

core/src/main/java/io/github/dfa1/vortex/core/array/ShortArray.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,13 @@
33
import io.github.dfa1.vortex.core.ArrayStats;
44
import io.github.dfa1.vortex.core.DType;
55
import io.github.dfa1.vortex.core.PType;
6+
import io.github.dfa1.vortex.encoding.PTypeIO;
67

78
import java.lang.foreign.MemorySegment;
8-
import java.lang.foreign.ValueLayout;
9-
import java.nio.ByteOrder;
109

1110
/// Concrete [Array] for I16/U16 primitive columns.
1211
public final class ShortArray implements Array {
1312

14-
private static final ValueLayout.OfShort LAYOUT =
15-
ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
16-
1713
private final DType dtype;
1814
private final long length;
1915
private final MemorySegment buffer;
@@ -50,11 +46,11 @@ public MemorySegment buffer(int i) {
5046
}
5147

5248
public short getShort(long i) {
53-
return buffer.getAtIndex(LAYOUT, i);
49+
return buffer.getAtIndex(PTypeIO.LE_SHORT, i);
5450
}
5551

5652
public int getInt(long i) {
57-
short raw = buffer.getAtIndex(LAYOUT, i);
53+
short raw = buffer.getAtIndex(PTypeIO.LE_SHORT, i);
5854
boolean unsigned = dtype instanceof DType.Primitive p && p.ptype() == PType.U16;
5955
return unsigned ? Short.toUnsignedInt(raw) : raw;
6056
}

core/src/main/java/io/github/dfa1/vortex/core/array/VarBinArray.java

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
import io.github.dfa1.vortex.core.DType;
55
import io.github.dfa1.vortex.core.PType;
66
import io.github.dfa1.vortex.core.VortexException;
7+
import io.github.dfa1.vortex.encoding.PTypeIO;
78

89
import java.lang.foreign.MemorySegment;
910
import java.lang.foreign.ValueLayout;
10-
import java.nio.ByteOrder;
1111
import java.util.function.IntConsumer;
1212

1313
/// Concrete [Array] for variable-length binary / UTF-8 string columns.
@@ -25,10 +25,6 @@
2525
/// all accessors resolve through the dictionary without materializing strings.
2626
public final class VarBinArray implements Array {
2727

28-
private static final ValueLayout.OfShort LE_SHORT = ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
29-
private static final ValueLayout.OfInt LE_INT = ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
30-
private static final ValueLayout.OfLong LE_LONG = ValueLayout.JAVA_LONG_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
31-
3228
private final DType dtype;
3329
private final long length;
3430
private final MemorySegment bytes;
@@ -156,37 +152,37 @@ public void forEachByteLength(IntConsumer c) {
156152
long n = length;
157153
if (offsetsPtype == PType.I32 || offsetsPtype == PType.U32) {
158154
for (long i = 0; i < n; i++) {
159-
c.accept(seg.getAtIndex(LE_INT, i + 1) - seg.getAtIndex(LE_INT, i));
155+
c.accept(seg.getAtIndex(PTypeIO.LE_INT, i + 1) - seg.getAtIndex(PTypeIO.LE_INT, i));
160156
}
161157
} else {
162158
for (long i = 0; i < n; i++) {
163-
c.accept((int) (seg.getAtIndex(LE_LONG, i + 1) - seg.getAtIndex(LE_LONG, i)));
159+
c.accept((int) (seg.getAtIndex(PTypeIO.LE_LONG, i + 1) - seg.getAtIndex(PTypeIO.LE_LONG, i)));
164160
}
165161
}
166162
}
167163

168164
private long readOffset(long i) {
169165
if (offsetsPtype == PType.I32 || offsetsPtype == PType.U32) {
170-
return offsetsSeg.getAtIndex(LE_INT, i);
166+
return offsetsSeg.getAtIndex(PTypeIO.LE_INT, i);
171167
}
172-
return offsetsSeg.getAtIndex(LE_LONG, i);
168+
return offsetsSeg.getAtIndex(PTypeIO.LE_LONG, i);
173169
}
174170

175171
private long dictReadCode(long i) {
176172
return switch (dictCodesPType) {
177173
case U8 -> Byte.toUnsignedLong(dictCodesSegs.get(ValueLayout.JAVA_BYTE, i));
178-
case U16 -> Short.toUnsignedLong(dictCodesSegs.getAtIndex(LE_SHORT, i));
179-
case U32 -> Integer.toUnsignedLong(dictCodesSegs.getAtIndex(LE_INT, i));
180-
case I32 -> dictCodesSegs.getAtIndex(LE_INT, i);
181-
case I64, U64 -> dictCodesSegs.getAtIndex(LE_LONG, i);
174+
case U16 -> Short.toUnsignedLong(dictCodesSegs.getAtIndex(PTypeIO.LE_SHORT, i));
175+
case U32 -> Integer.toUnsignedLong(dictCodesSegs.getAtIndex(PTypeIO.LE_INT, i));
176+
case I32 -> dictCodesSegs.getAtIndex(PTypeIO.LE_INT, i);
177+
case I64, U64 -> dictCodesSegs.getAtIndex(PTypeIO.LE_LONG, i);
182178
default -> throw new VortexException("unsupported codes ptype: " + dictCodesPType);
183179
};
184180
}
185181

186182
private long dictReadOff(long i) {
187183
if (dictValOffPType == PType.I32 || dictValOffPType == PType.U32) {
188-
return dictValOffsets.getAtIndex(LE_INT, i);
184+
return dictValOffsets.getAtIndex(PTypeIO.LE_INT, i);
189185
}
190-
return dictValOffsets.getAtIndex(LE_LONG, i);
186+
return dictValOffsets.getAtIndex(PTypeIO.LE_LONG, i);
191187
}
192188
}

0 commit comments

Comments
 (0)