11package io .github .dfa1 .vortex .reader .decode ;
22
3- import io .github .dfa1 .vortex .core .DType ;
4- import io .github .dfa1 .vortex .core .PType ;
53import io .github .dfa1 .vortex .reader .array .Array ;
64import 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 ;
77import 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 ;
108import org .junit .jupiter .api .Nested ;
119import org .junit .jupiter .api .Test ;
1210
13- import java .lang .foreign .Arena ;
14- import java .lang .foreign .MemorySegment ;
15- import java .lang .foreign .ValueLayout ;
1611import 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 ;
1817import 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.
2322class 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