Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import io.github.dfa1.vortex.core.VortexException;
import io.github.dfa1.vortex.encoding.EncodingId;
import io.github.dfa1.vortex.reader.array.Array;
import io.github.dfa1.vortex.reader.array.ArraySegments;
import io.github.dfa1.vortex.reader.array.BoolArray;
import io.github.dfa1.vortex.reader.array.ByteArray;
import io.github.dfa1.vortex.reader.array.ChunkedBoolArray;
Expand Down Expand Up @@ -641,11 +640,8 @@ private Array decodeDictLayout(Layout dictLayout, DType dtype, SegmentAllocator
/// @param codes the decoded codes array
/// @param codesPType code ptype reported by the dict layout metadata
/// @param n claimed dict row count
// ArraySegments is deprecated-for-removal; this guard is its only caller and moves to
// the decode-limits layer with it.
@SuppressWarnings("removal")
private static void validateDictCodesCapacity(Array codes, PType codesPType, long n) {
Optional<MemorySegment> maybeSeg = ArraySegments.trySegment(codes);
Optional<MemorySegment> maybeSeg = codes.segmentIfPresent();
if (maybeSeg.isEmpty()) {
return;
}
Expand Down
21 changes: 21 additions & 0 deletions reader/src/main/java/io/github/dfa1/vortex/reader/array/Array.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentAllocator;
import java.util.Optional;

/// Decoded columnar data. Concrete subtypes specialise element access for the JIT;
/// each covers a specific dtype family.
Expand Down Expand Up @@ -77,4 +78,24 @@ static Array limited(Array arr, long rows) {
}
return arr.length() <= rows ? arr : arr.limited(rows);
}

/// Returns this array's primary backing segment if it is already segment-backed,
/// otherwise empty — a non-allocating probe.
///
/// Unlike [#materialize(java.lang.foreign.SegmentAllocator)], this never allocates or
/// decodes: lazy and composite arrays return empty rather than being materialised. The
/// default is empty; segment-backed types (the `Materialized*` records, `VarBinArray`,
/// `GenericArray`, `LazyDecimalArray`) override to return their existing buffer, and
/// [MaskedArray] delegates to its inner data. The scan layer's dictionary zip-bomb guard
/// uses it to inspect a codes buffer's real size without expanding an oversized claimed
/// row count.
///
/// **Vortex-internal.** Application code should prefer the typed accessors on concrete
/// subtypes ([LongArray#getLong(long)], [IntArray#getInt(long)], …) or
/// [#materialize(java.lang.foreign.SegmentAllocator)].
///
/// @return the primary [MemorySegment], or empty if this array has no segment backing
default Optional<MemorySegment> segmentIfPresent() {
return Optional.empty();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteOrder;
import java.util.Optional;

/// Fallback [Array] for dtypes that lack a dedicated concrete subtype.
///
Expand Down Expand Up @@ -74,10 +75,6 @@ public GenericArray limited(long rows) {
return new GenericArray(dtype, rows, buffers, children);
}

MemorySegment buffer(int i) {
return buffers[i];
}

/// Returns the primary (index 0) raw buffer directly — no copy or allocation.
///
/// @param arena unused; the existing buffer is returned as-is
Expand All @@ -87,6 +84,14 @@ public MemorySegment materialize(SegmentAllocator arena) {
return buffers[0];
}

/// Returns the primary (index 0) raw buffer — already materialised, no allocation.
///
/// @return the first backing [MemorySegment]
@Override
public Optional<MemorySegment> segmentIfPresent() {
return Optional.of(buffers[0]);
}

/// Decodes the decimal value at row `i` from a single-buffer layout.
///
/// The buffer holds one little-endian two's-complement integer per row. Element
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteOrder;
import java.util.Optional;

/// Lazy `vortex.decimal` array.
///
Expand Down Expand Up @@ -82,4 +83,12 @@ public Array limited(long rows) {
public MemorySegment materialize(SegmentAllocator arena) {
return buf;
}

/// Returns the backing buffer directly — already materialised, no allocation.
///
/// @return the backing little-endian two's-complement segment
@Override
public Optional<MemorySegment> segmentIfPresent() {
return Optional.of(buf);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentAllocator;
import java.util.Optional;

/// Decoded `vortex.masked` array: a non-nullable child paired with an optional validity bitmap.
///
Expand Down Expand Up @@ -66,14 +67,21 @@ public Array limited(long rows) {
}

/// Materialises the inner (data) payload, ignoring the validity mask — the
/// segment returned is the data buffer only. This matches the prior
/// `ArraySegments` behaviour of unwrapping a masked array to its inner data;
/// callers that need validity must read [#validity()] separately.
/// segment returned is the data buffer only. Unwraps to the inner array's own
/// materialisation; callers that need validity must read [#validity()] separately.
///
/// @param arena allocator used to materialise lazy inner variants
/// @return the inner payload's primary [MemorySegment]
@Override
public MemorySegment materialize(SegmentAllocator arena) {
return child.materialize(arena);
}

/// Probes the inner (data) payload's backing segment, ignoring the validity mask.
///
/// @return the inner array's segment if segment-backed, otherwise empty
@Override
public Optional<MemorySegment> segmentIfPresent() {
return child.segmentIfPresent();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentAllocator;
import java.lang.foreign.ValueLayout;
import java.util.Optional;

/// Buffer-backed [BoolArray] — the fallback used when an encoding decoder
/// either materialises the output eagerly or has no lazy variant of its own.
Expand Down Expand Up @@ -36,10 +37,6 @@ public long length() {
return length;
}

MemorySegment buffer() {
return buffer;
}

/// Returns the backing buffer directly — already an LSB-first packed bitmap,
/// matching the format produced by [BoolArray#materialize(SegmentAllocator)],
/// so no copy or allocation is needed.
Expand All @@ -51,6 +48,11 @@ public MemorySegment materialize(SegmentAllocator arena) {
return buffer;
}

@Override
public Optional<MemorySegment> segmentIfPresent() {
return Optional.of(buffer);
}

@Override
public boolean getBoolean(long i) {
byte b = buffer.get(ValueLayout.JAVA_BYTE, i >>> 3);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentAllocator;
import java.lang.foreign.ValueLayout;
import java.util.Optional;
import java.util.function.LongBinaryOperator;

/// Buffer-backed [ByteArray] — the fallback used when an encoding decoder
Expand Down Expand Up @@ -40,10 +41,6 @@ public long length() {
return length;
}

MemorySegment buffer() {
return buffer;
}

/// Returns the backing buffer directly — already a contiguous one-byte-per-element
/// segment, so no copy or allocation is needed.
///
Expand All @@ -54,6 +51,11 @@ public MemorySegment materialize(SegmentAllocator arena) {
return buffer;
}

@Override
public Optional<MemorySegment> segmentIfPresent() {
return Optional.of(buffer);
}

@Override
public byte getByte(long i) {
return buffer.get(ValueLayout.JAVA_BYTE, length == elementCount ? i : i % elementCount);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentAllocator;
import java.util.Optional;
import java.util.function.DoubleBinaryOperator;
import java.util.function.DoubleConsumer;

Expand Down Expand Up @@ -39,10 +40,6 @@ public long length() {
return length;
}

MemorySegment buffer() {
return buffer;
}

/// Returns the backing buffer directly — already a contiguous little-endian
/// `f64` segment, so no copy or allocation is needed.
///
Expand All @@ -53,6 +50,11 @@ public MemorySegment materialize(SegmentAllocator arena) {
return buffer;
}

@Override
public Optional<MemorySegment> segmentIfPresent() {
return Optional.of(buffer);
}

@Override
public double getDouble(long i) {
return buffer.getAtIndex(PTypeIO.LE_DOUBLE, length == elementCount ? i : i % elementCount);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentAllocator;
import java.util.Optional;

/// Buffer-backed [Float16Array] — the fallback used when an encoding decoder
/// either materialises the output eagerly or has no lazy variant of its own.
Expand Down Expand Up @@ -36,10 +37,6 @@ public long length() {
return length;
}

MemorySegment buffer() {
return buffer;
}

/// Returns the backing buffer directly — already a contiguous little-endian
/// half-precision segment (2 bytes per element), so no copy or allocation is needed.
///
Expand All @@ -50,6 +47,11 @@ public MemorySegment materialize(SegmentAllocator arena) {
return buffer;
}

@Override
public Optional<MemorySegment> segmentIfPresent() {
return Optional.of(buffer);
}

@Override
public float getFloat(long i) {
return Float.float16ToFloat(buffer.getAtIndex(PTypeIO.LE_SHORT, i));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentAllocator;
import java.util.Optional;
import java.util.function.DoubleBinaryOperator;

/// Buffer-backed [FloatArray] — the fallback used when an encoding decoder
Expand Down Expand Up @@ -39,10 +40,6 @@ public long length() {
return length;
}

MemorySegment buffer() {
return buffer;
}

/// Returns the backing buffer directly — already a contiguous little-endian
/// `f32` segment, so no copy or allocation is needed.
///
Expand All @@ -53,6 +50,11 @@ public MemorySegment materialize(SegmentAllocator arena) {
return buffer;
}

@Override
public Optional<MemorySegment> segmentIfPresent() {
return Optional.of(buffer);
}

@Override
public float getFloat(long i) {
return buffer.getAtIndex(PTypeIO.LE_FLOAT, length == elementCount ? i : i % elementCount);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentAllocator;
import java.util.Optional;
import java.util.function.IntBinaryOperator;
import java.util.function.IntConsumer;

Expand Down Expand Up @@ -40,10 +41,6 @@ public long length() {
return length;
}

MemorySegment buffer() {
return buffer;
}

/// Returns the backing buffer directly — already a contiguous little-endian
/// `i32` segment, so no copy or allocation is needed.
///
Expand All @@ -54,6 +51,11 @@ public MemorySegment materialize(SegmentAllocator arena) {
return buffer;
}

@Override
public Optional<MemorySegment> segmentIfPresent() {
return Optional.of(buffer);
}

@Override
public int getInt(long i) {
return buffer.getAtIndex(PTypeIO.LE_INT, length == elementCount ? i : i % elementCount);
Expand Down
Loading