Skip to content

Commit a5ce838

Browse files
dfa1claude
andcommitted
refactor(reader): replace hand-rolled index guards with Objects.checkIndex (ADR 0003 Phase E)
The ~14 consumer-access getters in the Lazy*/Generic array families and ExtensionStorage hand-rolled the same bounds check: if (i < 0 || i >= length) { throw new IndexOutOfBoundsException("index " + i + " out of bounds for length " + length); } Collapse each onto the JDK built-in Objects.checkIndex(i, length). This is the consumer-access carve-out from ADR 0003 Phase E: a caller's bad accessor index is consumer misuse and correctly stays IndexOutOfBoundsException (cf. List.get), distinct from the untrusted-parse offsets that route through IoBounds and throw VortexException. Objects.checkIndex is an @IntrinsicCandidate, so the JIT inlines it to the same check — no regression on these scalar accessors. 12 files, 14 guards. reader 679 green; checkstyle + javadoc clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 3bcd988 commit a5ce838

12 files changed

Lines changed: 27 additions & 42 deletions

reader/src/main/java/io/github/dfa1/vortex/reader/array/GenericArray.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.math.BigDecimal;
1010
import java.math.BigInteger;
1111
import java.nio.ByteOrder;
12+
import java.util.Objects;
1213
import java.util.Optional;
1314

1415
/// Fallback [Array] for dtypes that lack a dedicated concrete subtype.
@@ -109,9 +110,7 @@ public Optional<MemorySegment> segmentIfPresent() {
109110
/// shape isn't the single-buffer layout
110111
/// @throws IndexOutOfBoundsException if `i` is outside `[0, length())`
111112
public BigDecimal getDecimal(long i) {
112-
if (i < 0 || i >= length) {
113-
throw new IndexOutOfBoundsException("index " + i + " out of bounds for length " + length);
114-
}
113+
Objects.checkIndex(i, length);
115114
if (!(dtype instanceof DType.Decimal d)) {
116115
throw new VortexException("getDecimal called on non-decimal dtype: " + dtype);
117116
}

reader/src/main/java/io/github/dfa1/vortex/reader/array/LazyConstantBoolArray.java

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

33
import io.github.dfa1.vortex.core.DType;
44

5+
import java.util.Objects;
6+
57
/// Metadata-only [BoolArray] for `vortex.constant` columns.
68
///
79
/// Holds a single boolean value broadcast across `length` logical rows. No
@@ -16,9 +18,7 @@ public record LazyConstantBoolArray(DType dtype, long length, boolean value) imp
1618

1719
@Override
1820
public boolean getBoolean(long i) {
19-
if (i < 0 || i >= length) {
20-
throw new IndexOutOfBoundsException("index " + i + " out of bounds for length " + length);
21-
}
21+
Objects.checkIndex(i, length);
2222
return value;
2323
}
2424

reader/src/main/java/io/github/dfa1/vortex/reader/array/LazyConstantByteArray.java

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

6+
import java.util.Objects;
67
import java.util.function.LongBinaryOperator;
78

89
/// Metadata-only [ByteArray] for `vortex.constant` columns.
@@ -19,17 +20,13 @@ public record LazyConstantByteArray(DType dtype, long length, byte value) implem
1920

2021
@Override
2122
public byte getByte(long i) {
22-
if (i < 0 || i >= length) {
23-
throw new IndexOutOfBoundsException("index " + i + " out of bounds for length " + length);
24-
}
23+
Objects.checkIndex(i, length);
2524
return value;
2625
}
2726

2827
@Override
2928
public int getInt(long i) {
30-
if (i < 0 || i >= length) {
31-
throw new IndexOutOfBoundsException("index " + i + " out of bounds for length " + length);
32-
}
29+
Objects.checkIndex(i, length);
3330
boolean unsigned = dtype instanceof DType.Primitive p && p.ptype() == PType.U8;
3431
return unsigned ? Byte.toUnsignedInt(value) : (int) value;
3532
}

reader/src/main/java/io/github/dfa1/vortex/reader/array/LazyConstantDecimalArray.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.lang.foreign.ValueLayout;
1010
import java.math.BigDecimal;
1111
import java.math.BigInteger;
12+
import java.util.Objects;
1213

1314
/// Metadata-only decimal array for `vortex.constant` columns.
1415
///
@@ -27,9 +28,7 @@ public record LazyConstantDecimalArray(DType dtype, long length, BigDecimal valu
2728
/// @param i row index, `0 <= i < length`
2829
/// @return the constant [java.math.BigDecimal] value
2930
public BigDecimal getDecimal(long i) {
30-
if (i < 0 || i >= length) {
31-
throw new IndexOutOfBoundsException("index " + i + " out of bounds for length " + length);
32-
}
31+
Objects.checkIndex(i, length);
3332
return value;
3433
}
3534

reader/src/main/java/io/github/dfa1/vortex/reader/array/LazyConstantDoubleArray.java

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

33
import io.github.dfa1.vortex.core.DType;
44

5+
import java.util.Objects;
56
import java.util.function.DoubleBinaryOperator;
67
import java.util.function.DoubleConsumer;
78

@@ -17,9 +18,7 @@ public record LazyConstantDoubleArray(DType dtype, long length, double value) im
1718

1819
@Override
1920
public double getDouble(long i) {
20-
if (i < 0 || i >= length) {
21-
throw new IndexOutOfBoundsException("index " + i + " out of bounds for length " + length);
22-
}
21+
Objects.checkIndex(i, length);
2322
return value;
2423
}
2524

reader/src/main/java/io/github/dfa1/vortex/reader/array/LazyConstantFloatArray.java

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

33
import io.github.dfa1.vortex.core.DType;
44

5+
import java.util.Objects;
56
import java.util.function.DoubleBinaryOperator;
67

78
/// Metadata-only [FloatArray] for `vortex.constant` columns.
@@ -16,9 +17,7 @@ public record LazyConstantFloatArray(DType dtype, long length, float value) impl
1617

1718
@Override
1819
public float getFloat(long i) {
19-
if (i < 0 || i >= length) {
20-
throw new IndexOutOfBoundsException("index " + i + " out of bounds for length " + length);
21-
}
20+
Objects.checkIndex(i, length);
2221
return value;
2322
}
2423

reader/src/main/java/io/github/dfa1/vortex/reader/array/LazyConstantIntArray.java

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

33
import io.github.dfa1.vortex.core.DType;
44

5+
import java.util.Objects;
56
import java.util.function.IntBinaryOperator;
67
import java.util.function.IntConsumer;
78

@@ -18,9 +19,7 @@ public record LazyConstantIntArray(DType dtype, long length, int value) implemen
1819

1920
@Override
2021
public int getInt(long i) {
21-
if (i < 0 || i >= length) {
22-
throw new IndexOutOfBoundsException("index " + i + " out of bounds for length " + length);
23-
}
22+
Objects.checkIndex(i, length);
2423
return value;
2524
}
2625

reader/src/main/java/io/github/dfa1/vortex/reader/array/LazyConstantLongArray.java

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

33
import io.github.dfa1.vortex.core.DType;
44

5+
import java.util.Objects;
56
import java.util.function.LongBinaryOperator;
67
import java.util.function.LongConsumer;
78

@@ -22,9 +23,7 @@ public record LazyConstantLongArray(DType dtype, long length, long value) implem
2223

2324
@Override
2425
public long getLong(long i) {
25-
if (i < 0 || i >= length) {
26-
throw new IndexOutOfBoundsException("index " + i + " out of bounds for length " + length);
27-
}
26+
Objects.checkIndex(i, length);
2827
return value;
2928
}
3029

reader/src/main/java/io/github/dfa1/vortex/reader/array/LazyConstantShortArray.java

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

6+
import java.util.Objects;
67
import java.util.function.LongBinaryOperator;
78

89
/// Metadata-only [ShortArray] for `vortex.constant` columns.
@@ -19,17 +20,13 @@ public record LazyConstantShortArray(DType dtype, long length, short value) impl
1920

2021
@Override
2122
public short getShort(long i) {
22-
if (i < 0 || i >= length) {
23-
throw new IndexOutOfBoundsException("index " + i + " out of bounds for length " + length);
24-
}
23+
Objects.checkIndex(i, length);
2524
return value;
2625
}
2726

2827
@Override
2928
public int getInt(long i) {
30-
if (i < 0 || i >= length) {
31-
throw new IndexOutOfBoundsException("index " + i + " out of bounds for length " + length);
32-
}
29+
Objects.checkIndex(i, length);
3330
boolean unsigned = dtype instanceof DType.Primitive p && p.ptype() == PType.U16;
3431
return unsigned ? Short.toUnsignedInt(value) : (int) value;
3532
}

reader/src/main/java/io/github/dfa1/vortex/reader/array/LazyDecimalArray.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.math.BigDecimal;
1010
import java.math.BigInteger;
1111
import java.nio.ByteOrder;
12+
import java.util.Objects;
1213
import java.util.Optional;
1314

1415
/// Lazy `vortex.decimal` array.
@@ -40,9 +41,7 @@ public record LazyDecimalArray(DType dtype, long length, MemorySegment buf, int
4041
/// @throws VortexException if the dtype isn't a [DType.Decimal]
4142
/// @throws IndexOutOfBoundsException if `i` is outside `[0, length())`
4243
public BigDecimal getDecimal(long i) {
43-
if (i < 0 || i >= length) {
44-
throw new IndexOutOfBoundsException("index " + i + " out of bounds for length " + length);
45-
}
44+
Objects.checkIndex(i, length);
4645
if (!(dtype instanceof DType.Decimal d)) {
4746
throw new VortexException("LazyDecimalArray: non-decimal dtype " + dtype);
4847
}

0 commit comments

Comments
 (0)