Skip to content

Commit 0acaf5b

Browse files
committed
test(reader): migrate DateTimeParts + LazyRunEnd tests to TestArrays
1 parent f50b5b4 commit 0acaf5b

2 files changed

Lines changed: 106 additions & 162 deletions

File tree

Lines changed: 44 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
package io.github.dfa1.vortex.reader.array;
22

3-
import io.github.dfa1.vortex.core.DType;
4-
import io.github.dfa1.vortex.core.PType;
53
import org.junit.jupiter.api.Test;
64

7-
import java.lang.foreign.Arena;
8-
import java.lang.foreign.MemorySegment;
9-
import java.lang.foreign.ValueLayout;
10-
5+
import static io.github.dfa1.vortex.encoding.DTypes.I64;
6+
import static io.github.dfa1.vortex.reader.array.TestArrays.ints;
7+
import static io.github.dfa1.vortex.reader.array.TestArrays.longs;
118
import static org.assertj.core.api.Assertions.assertThat;
129

1310
/// Unit tests for {@link LazyDateTimePartsLongArray}. Verifies the
@@ -16,80 +13,56 @@
1613
/// that lets each child use whatever signed-integer ptype the encoder picked.
1714
class LazyDateTimePartsLongArrayTest {
1815

19-
private static final DType I64 = new DType.Primitive(PType.I64, false);
20-
private static final DType I32 = new DType.Primitive(PType.I32, false);
21-
// Decoder constructs records carrying the parent Extension dtype; use I64 here
22-
// as a stand-in since the record never inspects dtype semantics directly.
23-
2416
@Test
2517
void millisecondsReassembly() {
26-
// Given 2 rows of arbitrary (days, seconds_in_day, subseconds) for ms unit.
27-
// unitsPerSecond = 1_000; unitsPerDay = 86_400_000.
28-
// Row 0: days=20_000 -> 2024-12-31 area, seconds=12345, subseconds=678 -> 1_728_012_345_678
29-
try (Arena arena = Arena.ofConfined()) {
30-
LongArray days = longArray(arena, 20_000L, 0L);
31-
LongArray seconds = longArray(arena, 12_345L, 0L);
32-
LongArray subseconds = longArray(arena, 678L, 0L);
33-
long unitsPerSecond = 1_000L;
34-
long unitsPerDay = 86_400L * unitsPerSecond;
35-
36-
var sut = new LazyDateTimePartsLongArray(I64, 2,
37-
days, seconds, subseconds, unitsPerDay, unitsPerSecond);
38-
39-
assertThat(sut.getLong(0)).isEqualTo(
40-
20_000L * unitsPerDay + 12_345L * unitsPerSecond + 678L);
41-
assertThat(sut.getLong(1)).isZero();
42-
}
18+
// Given 2 rows of (days, seconds_in_day, subseconds) for ms unit:
19+
// unitsPerSecond = 1_000; unitsPerDay = 86_400_000; row 0 -> 1_728_012_345_678
20+
LongArray days = longs(20_000L, 0L);
21+
LongArray seconds = longs(12_345L, 0L);
22+
LongArray subseconds = longs(678L, 0L);
23+
long unitsPerSecond = 1_000L;
24+
long unitsPerDay = 86_400L * unitsPerSecond;
25+
26+
// When
27+
var sut = new LazyDateTimePartsLongArray(I64, 2,
28+
days, seconds, subseconds, unitsPerDay, unitsPerSecond);
29+
30+
// Then
31+
assertThat(sut.getLong(0)).isEqualTo(
32+
20_000L * unitsPerDay + 12_345L * unitsPerSecond + 678L);
33+
assertThat(sut.getLong(1)).isZero();
4334
}
4435

4536
@Test
4637
void widensFromNarrowerChildPtypes() {
47-
// Days as I32, seconds as I32, subseconds as I64 — encoder is free to pick.
48-
try (Arena arena = Arena.ofConfined()) {
49-
IntArray days = intArray(arena, 1);
50-
IntArray seconds = intArray(arena, 2);
51-
LongArray subseconds = longArray(arena, 3L);
52-
long ups = 1_000_000_000L; // nanos
53-
long upd = 86_400L * ups;
54-
55-
var sut = new LazyDateTimePartsLongArray(I64, 1,
56-
days, seconds, subseconds, upd, ups);
57-
58-
assertThat(sut.getLong(0)).isEqualTo(1L * upd + 2L * ups + 3L);
59-
}
38+
// Given days/seconds as I32, subseconds as I64 — encoder is free to pick widths
39+
IntArray days = ints(1);
40+
IntArray seconds = ints(2);
41+
LongArray subseconds = longs(3L);
42+
long ups = 1_000_000_000L; // nanos
43+
long upd = 86_400L * ups;
44+
45+
// When
46+
var sut = new LazyDateTimePartsLongArray(I64, 1, days, seconds, subseconds, upd, ups);
47+
48+
// Then
49+
assertThat(sut.getLong(0)).isEqualTo(1L * upd + 2L * ups + 3L);
6050
}
6151

6252
@Test
6353
void foldSumsAllRows() {
64-
try (Arena arena = Arena.ofConfined()) {
65-
LongArray days = longArray(arena, 1L, 2L, 3L);
66-
LongArray seconds = longArray(arena, 0L, 0L, 0L);
67-
LongArray subseconds = longArray(arena, 0L, 0L, 0L);
68-
long ups = 1L;
69-
long upd = 86_400L;
70-
71-
var sut = new LazyDateTimePartsLongArray(I64, 3,
72-
days, seconds, subseconds, upd, ups);
73-
74-
long sum = sut.fold(0L, Long::sum);
75-
// 1*86400 + 2*86400 + 3*86400 = 6*86400
76-
assertThat(sum).isEqualTo(6L * upd);
77-
}
78-
}
79-
80-
private static LongArray longArray(Arena arena, long... vs) {
81-
MemorySegment seg = arena.allocate(vs.length * 8L, 8);
82-
for (int i = 0; i < vs.length; i++) {
83-
seg.setAtIndex(ValueLayout.JAVA_LONG, i, vs[i]);
84-
}
85-
return new MaterializedLongArray(I64, vs.length, seg.asReadOnly());
86-
}
87-
88-
private static IntArray intArray(Arena arena, int... vs) {
89-
MemorySegment seg = arena.allocate(vs.length * 4L, 4);
90-
for (int i = 0; i < vs.length; i++) {
91-
seg.setAtIndex(ValueLayout.JAVA_INT, i, vs[i]);
92-
}
93-
return new MaterializedIntArray(I32, vs.length, seg.asReadOnly());
54+
// Given
55+
LongArray days = longs(1L, 2L, 3L);
56+
LongArray seconds = longs(0L, 0L, 0L);
57+
LongArray subseconds = longs(0L, 0L, 0L);
58+
long ups = 1L;
59+
long upd = 86_400L;
60+
var sut = new LazyDateTimePartsLongArray(I64, 3, days, seconds, subseconds, upd, ups);
61+
62+
// When
63+
long result = sut.fold(0L, Long::sum);
64+
65+
// Then — 1*86400 + 2*86400 + 3*86400 = 6*86400
66+
assertThat(result).isEqualTo(6L * upd);
9467
}
9568
}
Lines changed: 62 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,114 +1,101 @@
11
package io.github.dfa1.vortex.reader.decode;
22

3-
import io.github.dfa1.vortex.core.DType;
4-
import io.github.dfa1.vortex.core.PType;
53
import io.github.dfa1.vortex.reader.array.Array;
64
import io.github.dfa1.vortex.reader.array.IntArray;
5+
import io.github.dfa1.vortex.reader.array.LazyRunEndIntArray;
6+
import io.github.dfa1.vortex.reader.array.LazyRunEndLongArray;
77
import io.github.dfa1.vortex.reader.array.LongArray;
8-
import io.github.dfa1.vortex.reader.array.MaterializedIntArray;
9-
import io.github.dfa1.vortex.reader.array.MaterializedLongArray;
108
import org.junit.jupiter.api.Nested;
119
import org.junit.jupiter.api.Test;
1210

13-
import java.lang.foreign.Arena;
14-
import java.lang.foreign.MemorySegment;
15-
import java.lang.foreign.ValueLayout;
1611
import java.util.ArrayList;
1712

13+
import static io.github.dfa1.vortex.encoding.DTypes.I32;
14+
import static io.github.dfa1.vortex.encoding.DTypes.I64;
15+
import static io.github.dfa1.vortex.reader.array.TestArrays.ints;
16+
import static io.github.dfa1.vortex.reader.array.TestArrays.longs;
1817
import static org.assertj.core.api.Assertions.assertThat;
1918

2019
/// Unit tests for the lazy run-end records nested in [RunEndEncodingDecoder].
2120
/// Covers scalar dispatch via binary-search-on-runEnds, forEach run-walking,
2221
/// fold reduction, and the offset slicing semantics.
2322
class LazyRunEndArrayTest {
2423

25-
private static final DType I64 = new DType.Primitive(PType.I64, false);
26-
private static final DType I32 = new DType.Primitive(PType.I32, false);
27-
2824
@Nested
2925
class LongDispatch {
3026

3127
@Test
3228
void getLongMapsThroughRuns() {
3329
// Given runs: [0..3)=10, [3..5)=20, [5..8)=30
34-
try (Arena arena = Arena.ofConfined()) {
35-
LongArray values = longArray(arena, 10L, 20L, 30L);
36-
Array runEnds = intArray(arena, 3, 5, 8);
37-
var sut = new io.github.dfa1.vortex.reader.array.LazyRunEndLongArray(I64, 8L, values, runEnds, 0L);
38-
39-
// When/Then
40-
assertThat(sut.getLong(0)).isEqualTo(10L);
41-
assertThat(sut.getLong(2)).isEqualTo(10L);
42-
assertThat(sut.getLong(3)).isEqualTo(20L);
43-
assertThat(sut.getLong(4)).isEqualTo(20L);
44-
assertThat(sut.getLong(5)).isEqualTo(30L);
45-
assertThat(sut.getLong(7)).isEqualTo(30L);
46-
}
30+
LongArray values = longs(10L, 20L, 30L);
31+
Array runEnds = ints(3, 5, 8);
32+
var sut = new LazyRunEndLongArray(I64, 8L, values, runEnds, 0L);
33+
34+
// When / Then
35+
assertThat(sut.getLong(0)).isEqualTo(10L);
36+
assertThat(sut.getLong(2)).isEqualTo(10L);
37+
assertThat(sut.getLong(3)).isEqualTo(20L);
38+
assertThat(sut.getLong(4)).isEqualTo(20L);
39+
assertThat(sut.getLong(5)).isEqualTo(30L);
40+
assertThat(sut.getLong(7)).isEqualTo(30L);
4741
}
4842

4943
@Test
5044
void forEachLongWalksRuns() {
5145
// Given runs: [0..2)=1, [2..3)=2, [3..6)=3
52-
try (Arena arena = Arena.ofConfined()) {
53-
LongArray values = longArray(arena, 1L, 2L, 3L);
54-
Array runEnds = intArray(arena, 2, 3, 6);
55-
var sut = new io.github.dfa1.vortex.reader.array.LazyRunEndLongArray(I64, 6L, values, runEnds, 0L);
56-
57-
// When
58-
var seen = new ArrayList<Long>();
59-
sut.forEachLong(seen::add);
60-
61-
// Then
62-
assertThat(seen).containsExactly(1L, 1L, 2L, 3L, 3L, 3L);
63-
}
46+
LongArray values = longs(1L, 2L, 3L);
47+
Array runEnds = ints(2, 3, 6);
48+
var sut = new LazyRunEndLongArray(I64, 6L, values, runEnds, 0L);
49+
50+
// When
51+
var seen = new ArrayList<Long>();
52+
sut.forEachLong(seen::add);
53+
54+
// Then
55+
assertThat(seen).containsExactly(1L, 1L, 2L, 3L, 3L, 3L);
6456
}
6557

6658
@Test
6759
void foldSumsCorrectly() {
6860
// Given runs: [0..2)=5, [2..5)=10
69-
try (Arena arena = Arena.ofConfined()) {
70-
LongArray values = longArray(arena, 5L, 10L);
71-
Array runEnds = intArray(arena, 2, 5);
72-
var sut = new io.github.dfa1.vortex.reader.array.LazyRunEndLongArray(I64, 5L, values, runEnds, 0L);
61+
LongArray values = longs(5L, 10L);
62+
Array runEnds = ints(2, 5);
63+
var sut = new LazyRunEndLongArray(I64, 5L, values, runEnds, 0L);
7364

74-
// When
75-
long sum = sut.fold(0L, Long::sum);
65+
// When
66+
long result = sut.fold(0L, Long::sum);
7667

77-
// Then 2*5 + 3*10 = 40
78-
assertThat(sum).isEqualTo(40L);
79-
}
68+
// Then — 2*5 + 3*10 = 40
69+
assertThat(result).isEqualTo(40L);
8070
}
8171

8272
@Test
8373
void offsetSkipsLeadingRuns() {
84-
// Given runs: [0..3)=1, [3..5)=2, [5..8)=3
85-
// With offset=3, logical row 0 should map to absolute 3 → value 2
86-
try (Arena arena = Arena.ofConfined()) {
87-
LongArray values = longArray(arena, 1L, 2L, 3L);
88-
Array runEnds = intArray(arena, 3, 5, 8);
89-
var sut = new io.github.dfa1.vortex.reader.array.LazyRunEndLongArray(I64, 5L, values, runEnds, 3L);
90-
91-
// When/Then
92-
assertThat(sut.getLong(0)).isEqualTo(2L);
93-
assertThat(sut.getLong(1)).isEqualTo(2L);
94-
assertThat(sut.getLong(2)).isEqualTo(3L);
95-
assertThat(sut.getLong(4)).isEqualTo(3L);
96-
}
74+
// Given runs: [0..3)=1, [3..5)=2, [5..8)=3; offset=3 maps logical 0 -> abs 3 -> value 2
75+
LongArray values = longs(1L, 2L, 3L);
76+
Array runEnds = ints(3, 5, 8);
77+
var sut = new LazyRunEndLongArray(I64, 5L, values, runEnds, 3L);
78+
79+
// When / Then
80+
assertThat(sut.getLong(0)).isEqualTo(2L);
81+
assertThat(sut.getLong(1)).isEqualTo(2L);
82+
assertThat(sut.getLong(2)).isEqualTo(3L);
83+
assertThat(sut.getLong(4)).isEqualTo(3L);
9784
}
9885

9986
@Test
10087
void offsetForEachStartsAtOffset() {
101-
try (Arena arena = Arena.ofConfined()) {
102-
LongArray values = longArray(arena, 1L, 2L, 3L);
103-
Array runEnds = intArray(arena, 3, 5, 8);
104-
var sut = new io.github.dfa1.vortex.reader.array.LazyRunEndLongArray(I64, 5L, values, runEnds, 3L);
88+
// Given runs [0..3)=1,[3..5)=2,[5..8)=3 with offset 3
89+
LongArray values = longs(1L, 2L, 3L);
90+
Array runEnds = ints(3, 5, 8);
91+
var sut = new LazyRunEndLongArray(I64, 5L, values, runEnds, 3L);
10592

106-
var seen = new ArrayList<Long>();
107-
sut.forEachLong(seen::add);
93+
// When
94+
var seen = new ArrayList<Long>();
95+
sut.forEachLong(seen::add);
10896

109-
// logical [0..5) over runs starting at abs=3: 2,2,3,3,3
110-
assertThat(seen).containsExactly(2L, 2L, 3L, 3L, 3L);
111-
}
97+
// Then — logical [0..5) over runs starting at abs=3: 2,2,3,3,3
98+
assertThat(seen).containsExactly(2L, 2L, 3L, 3L, 3L);
11299
}
113100
}
114101

@@ -117,31 +104,15 @@ class IntDispatch {
117104

118105
@Test
119106
void getIntMapsThroughRuns() {
120-
try (Arena arena = Arena.ofConfined()) {
121-
IntArray values = intArray(arena, 100, 200);
122-
Array runEnds = intArray(arena, 3, 5);
123-
var sut = new io.github.dfa1.vortex.reader.array.LazyRunEndIntArray(I32, 5L, values, runEnds, 0L);
124-
125-
assertThat(sut.getInt(0)).isEqualTo(100);
126-
assertThat(sut.getInt(3)).isEqualTo(200);
127-
assertThat(sut.getInt(4)).isEqualTo(200);
128-
}
129-
}
130-
}
131-
132-
private static LongArray longArray(Arena arena, long... values) {
133-
MemorySegment seg = arena.allocate(values.length * 8L, 8);
134-
for (int i = 0; i < values.length; i++) {
135-
seg.setAtIndex(ValueLayout.JAVA_LONG, i, values[i]);
136-
}
137-
return new MaterializedLongArray(I64, values.length, seg.asReadOnly());
138-
}
139-
140-
private static IntArray intArray(Arena arena, int... values) {
141-
MemorySegment seg = arena.allocate(values.length * 4L, 4);
142-
for (int i = 0; i < values.length; i++) {
143-
seg.setAtIndex(ValueLayout.JAVA_INT, i, values[i]);
107+
// Given runs: [0..3)=100, [3..5)=200
108+
IntArray values = ints(100, 200);
109+
Array runEnds = ints(3, 5);
110+
var sut = new LazyRunEndIntArray(I32, 5L, values, runEnds, 0L);
111+
112+
// When / Then
113+
assertThat(sut.getInt(0)).isEqualTo(100);
114+
assertThat(sut.getInt(3)).isEqualTo(200);
115+
assertThat(sut.getInt(4)).isEqualTo(200);
144116
}
145-
return new MaterializedIntArray(I32, values.length, seg.asReadOnly());
146117
}
147118
}

0 commit comments

Comments
 (0)