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 @@ -140,6 +140,107 @@ void foldReducesSlicedRange() {
}
}

@Nested
class Bool {
@Test
void getBooleanShiftsByOffset() {
try (Arena arena = Arena.ofConfined()) {
// Given — packed bits [F, T, T, F]
BoolArray inner = boolArray(arena, false, true, true, false);
var sut = new OffsetBoolArray(new DType.Bool(false), 2, inner, 1L);

// When / Then
assertThat(sut.getBoolean(0)).isTrue(); // inner[1]
assertThat(sut.getBoolean(1)).isTrue(); // inner[2]
assertThat(sut.length()).isEqualTo(2);
}
}
}

@Nested
class Int {
@Test
void getIntShiftsByOffset() {
try (Arena arena = Arena.ofConfined()) {
// Given
IntArray inner = intArray(arena, 10, 20, 30, 40);
var sut = new OffsetIntArray(new DType.Primitive(PType.I32, false), 2, inner, 2L);

// When / Then
assertThat(sut.getInt(0)).isEqualTo(30);
assertThat(sut.getInt(1)).isEqualTo(40);
}
}
}

@Nested
class Long {
@Test
void getLongShiftsByOffset() {
try (Arena arena = Arena.ofConfined()) {
// Given
LongArray inner = longArray(arena, 5L, 6L, 7L, 8L);
var sut = new OffsetLongArray(new DType.Primitive(PType.I64, false), 2, inner, 1L);

// When / Then
assertThat(sut.getLong(0)).isEqualTo(6L);
assertThat(sut.getLong(1)).isEqualTo(7L);
}
}
}

@Nested
class Double {
@Test
void getDoubleShiftsByOffset() {
try (Arena arena = Arena.ofConfined()) {
// Given
DoubleArray inner = doubleArray(arena, 1.5, 2.5, 3.5);
var sut = new OffsetDoubleArray(new DType.Primitive(PType.F64, false), 2, inner, 1L);

// When / Then
assertThat(sut.getDouble(0)).isEqualTo(2.5);
assertThat(sut.getDouble(1)).isEqualTo(3.5);
}
}
}

private static BoolArray boolArray(Arena arena, boolean... vs) {
MemorySegment seg = arena.allocate((vs.length + 7) / 8);
for (int i = 0; i < vs.length; i++) {
if (vs[i]) {
long bi = i >>> 3;
byte b = seg.get(ValueLayout.JAVA_BYTE, bi);
seg.set(ValueLayout.JAVA_BYTE, bi, (byte) ((b & 0xff) | (1 << (i & 7))));
}
}
return new MaterializedBoolArray(new DType.Bool(false), vs.length, seg.asReadOnly());
}

private static IntArray intArray(Arena arena, int... vs) {
MemorySegment seg = arena.allocate(vs.length * 4L, 4);
for (int i = 0; i < vs.length; i++) {
seg.setAtIndex(ValueLayout.JAVA_INT, i, vs[i]);
}
return new MaterializedIntArray(new DType.Primitive(PType.I32, false), vs.length, seg.asReadOnly());
}

private static LongArray longArray(Arena arena, long... vs) {
MemorySegment seg = arena.allocate(vs.length * 8L, 8);
for (int i = 0; i < vs.length; i++) {
seg.setAtIndex(ValueLayout.JAVA_LONG, i, vs[i]);
}
return new MaterializedLongArray(new DType.Primitive(PType.I64, false), vs.length, seg.asReadOnly());
}

private static DoubleArray doubleArray(Arena arena, double... vs) {
MemorySegment seg = arena.allocate(vs.length * 8L, 8);
for (int i = 0; i < vs.length; i++) {
seg.setAtIndex(ValueLayout.JAVA_DOUBLE, i, vs[i]);
}
return new MaterializedDoubleArray(new DType.Primitive(PType.F64, false), vs.length, seg.asReadOnly());
}

private static ByteArray byteArray(Arena arena, byte... vs) {
MemorySegment seg = arena.allocate(vs.length, 1);
for (int i = 0; i < vs.length; i++) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.github.dfa1.vortex.reader.array;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

class RleArraysTest {

@Test
void chunkValueCount_middleChunk_usesNextOffset() {
// Given — two chunks, pool [0,3,5); firstOffset 0
long[] offsets = {0, 3};

// When
int count = RleArrays.chunkValueCount(0, 2, offsets, 0L, 5L);

// Then — offsets[1] - offsets[0] = 3
assertThat(count).isEqualTo(3);
}

@Test
void chunkValueCount_lastChunk_usesValuesLen() {
// Given — last chunk falls back to the total pool length
long[] offsets = {0, 3};

// When
int count = RleArrays.chunkValueCount(1, 2, offsets, 0L, 5L);

// Then — valuesLen(5) - offsets[1](3) = 2
assertThat(count).isEqualTo(2);
}

@Test
void chunkValueCount_subtractsFirstOffset() {
// Given — pool origin shifted by firstOffset 10
long[] offsets = {10, 13};

// When / Then — both branches still measure the local span
assertThat(RleArrays.chunkValueCount(0, 2, offsets, 10L, 5L)).isEqualTo(3);
assertThat(RleArrays.chunkValueCount(1, 2, offsets, 10L, 5L)).isEqualTo(2);
}
}