4646
4747public class TestSegmentCopy {
4848
49- @ Test (dataProvider = "slices" )
50- public void testByteCopy (SegmentSlice s1 , SegmentSlice s2 ) {
51- int size = Math .min (s1 .byteSize (), s2 .byteSize ());
52- //prepare source and target segments
53- for (int i = 0 ; i < size ; i ++) {
54- Type .BYTE .set (s2 , i , 0 );
55- }
56- for (int i = 0 ; i < size ; i ++) {
57- Type .BYTE .set (s1 , i , i );
58- }
59- //perform copy
60- MemorySegment .copy (s1 .segment , 0 , s2 .segment , 0 , size );
61- //check that copy actually worked
62- for (int i = 0 ; i < size ; i ++) {
63- Type .BYTE .check (s2 , i , i );
49+ static final int TEST_BYTE_SIZE = 16 ;
50+
51+ @ Test (dataProvider = "segmentKinds" )
52+ public void testByteCopy (SegmentKind kind1 , SegmentKind kind2 ) {
53+ MemorySegment s1 = kind1 .makeSegment (TEST_BYTE_SIZE );
54+ MemorySegment s2 = kind2 .makeSegment (TEST_BYTE_SIZE );
55+
56+ // for all offsets
57+ for (int s1Offset = 0 ; s1Offset < s1 .byteSize (); s1Offset ++) {
58+ for (int s2Offset = 0 ; s2Offset < s2 .byteSize (); s2Offset ++) {
59+ long slice1ByteSize = s1 .byteSize () - s1Offset ;
60+ long slice2ByteSize = s2 .byteSize () - s2Offset ;
61+
62+ long copySize = Math .min (slice1ByteSize , slice2ByteSize );
63+
64+ //prepare source slice
65+ for (int i = 0 ; i < copySize ; i ++) {
66+ Type .BYTE .set (s1 , s1Offset , i , i );
67+ }
68+ //perform copy
69+ MemorySegment .copy (s1 , Type .BYTE .layout , s1Offset , s2 , Type .BYTE .layout , s2Offset , copySize );
70+ //check that copy actually worked
71+ for (int i = 0 ; i < copySize ; i ++) {
72+ Type .BYTE .check (s2 , s2Offset , i , i );
73+ }
74+ }
6475 }
6576 }
6677
67- @ Test (dataProvider = "slices" )
68- public void testElementCopy (SegmentSlice s1 , SegmentSlice s2 ) {
69- if (s1 .type .carrier != s2 .type .carrier ) return ;
70- int size = Math .min (s1 .elementSize (), s2 .elementSize ());
71- //prepare source and target segments
72- for (int i = 0 ; i < size ; i ++) {
73- s2 .set (i , 0 );
74- }
75- for (int i = 0 ; i < size ; i ++) {
76- s1 .set (i , i );
77- }
78- //perform copy
79- MemorySegment .copy (s1 .segment , s1 .type .layout , 0 , s2 .segment , s2 .type .layout , 0 , size );
80- //check that copy actually worked
81- for (int i = 0 ; i < size ; i ++) {
82- s2 .check (i , i );
78+ @ Test (dataProvider = "segmentKindsAndTypes" )
79+ public void testElementCopy (SegmentKind kind1 , SegmentKind kind2 , Type type1 , Type type2 ) {
80+ MemorySegment s1 = kind1 .makeSegment (TEST_BYTE_SIZE );
81+ MemorySegment s2 = kind2 .makeSegment (TEST_BYTE_SIZE );
82+
83+ // for all offsets
84+ for (int s1Offset = 0 ; s1Offset < s1 .byteSize (); s1Offset ++) {
85+ for (int s2Offset = 0 ; s2Offset < s2 .byteSize (); s2Offset ++) {
86+ long slice1ByteSize = s1 .byteSize () - s1Offset ;
87+ long slice2ByteSize = s2 .byteSize () - s2Offset ;
88+
89+ long slice1ElementSize = slice1ByteSize / type1 .size ();
90+ long slice2ElementSize = slice2ByteSize / type2 .size ();
91+
92+ long copySize = Math .min (slice1ElementSize , slice2ElementSize );
93+
94+ //prepare source slice
95+ for (int i = 0 ; i < copySize ; i ++) {
96+ type1 .set (s1 , s1Offset , i , i );
97+ }
98+ //perform copy
99+ MemorySegment .copy (s1 , type1 .layout , s1Offset , s2 , type2 .layout , s2Offset , copySize );
100+ //check that copy actually worked
101+ for (int i = 0 ; i < copySize ; i ++) {
102+ type2 .check (s2 , s2Offset , i , i );
103+ }
104+ }
83105 }
84106 }
85107
@@ -99,19 +121,19 @@ enum Type {
99121 // Byte
100122 BYTE (byte .class , JAVA_BYTE , i -> (byte )i ),
101123 //LE
102- SHORT_LE (short .class , ValueLayout .JAVA_SHORT . withBitAlignment ( 8 ) .withOrder (ByteOrder .LITTLE_ENDIAN ), i -> (short )i ),
103- CHAR_LE (char .class , ValueLayout .JAVA_CHAR . withBitAlignment ( 8 ) .withOrder (ByteOrder .LITTLE_ENDIAN ), i -> (char )i ),
104- INT_LE (int .class , ValueLayout .JAVA_INT . withBitAlignment ( 8 ) .withOrder (ByteOrder .LITTLE_ENDIAN ), i -> i ),
105- FLOAT_LE (float .class , ValueLayout .JAVA_FLOAT . withBitAlignment ( 8 ) .withOrder (ByteOrder .LITTLE_ENDIAN ), i -> (float )i ),
106- LONG_LE (long .class , ValueLayout .JAVA_LONG . withBitAlignment ( 8 ) .withOrder (ByteOrder .LITTLE_ENDIAN ), i -> (long )i ),
107- DOUBLE_LE (double .class , ValueLayout .JAVA_DOUBLE . withBitAlignment ( 8 ) .withOrder (ByteOrder .LITTLE_ENDIAN ), i -> (double )i ),
124+ SHORT_LE (short .class , ValueLayout .JAVA_SHORT_UNALIGNED .withOrder (ByteOrder .LITTLE_ENDIAN ), i -> (short )i ),
125+ CHAR_LE (char .class , ValueLayout .JAVA_CHAR_UNALIGNED .withOrder (ByteOrder .LITTLE_ENDIAN ), i -> (char )i ),
126+ INT_LE (int .class , ValueLayout .JAVA_INT_UNALIGNED .withOrder (ByteOrder .LITTLE_ENDIAN ), i -> i ),
127+ FLOAT_LE (float .class , ValueLayout .JAVA_FLOAT_UNALIGNED .withOrder (ByteOrder .LITTLE_ENDIAN ), i -> (float )i ),
128+ LONG_LE (long .class , ValueLayout .JAVA_LONG_UNALIGNED .withOrder (ByteOrder .LITTLE_ENDIAN ), i -> (long )i ),
129+ DOUBLE_LE (double .class , ValueLayout .JAVA_DOUBLE_UNALIGNED .withOrder (ByteOrder .LITTLE_ENDIAN ), i -> (double )i ),
108130 //BE
109- SHORT_BE (short .class , ValueLayout .JAVA_SHORT . withBitAlignment ( 8 ) .withOrder (ByteOrder .BIG_ENDIAN ), i -> (short )i ),
110- CHAR_BE (char .class , ValueLayout .JAVA_CHAR . withBitAlignment ( 8 ) .withOrder (ByteOrder .BIG_ENDIAN ), i -> (char )i ),
111- INT_BE (int .class , ValueLayout .JAVA_INT . withBitAlignment ( 8 ) .withOrder (ByteOrder .BIG_ENDIAN ), i -> i ),
112- FLOAT_BE (float .class , ValueLayout .JAVA_FLOAT . withBitAlignment ( 8 ) .withOrder (ByteOrder .BIG_ENDIAN ), i -> (float )i ),
113- LONG_BE (long .class , ValueLayout .JAVA_LONG . withBitAlignment ( 8 ) .withOrder (ByteOrder .BIG_ENDIAN ), i -> (long )i ),
114- DOUBLE_BE (double .class , ValueLayout .JAVA_DOUBLE . withBitAlignment ( 8 ) .withOrder (ByteOrder .BIG_ENDIAN ), i -> (double )i );
131+ SHORT_BE (short .class , ValueLayout .JAVA_SHORT_UNALIGNED .withOrder (ByteOrder .BIG_ENDIAN ), i -> (short )i ),
132+ CHAR_BE (char .class , ValueLayout .JAVA_CHAR_UNALIGNED .withOrder (ByteOrder .BIG_ENDIAN ), i -> (char )i ),
133+ INT_BE (int .class , ValueLayout .JAVA_INT_UNALIGNED .withOrder (ByteOrder .BIG_ENDIAN ), i -> i ),
134+ FLOAT_BE (float .class , ValueLayout .JAVA_FLOAT_UNALIGNED .withOrder (ByteOrder .BIG_ENDIAN ), i -> (float )i ),
135+ LONG_BE (long .class , ValueLayout .JAVA_LONG_UNALIGNED .withOrder (ByteOrder .BIG_ENDIAN ), i -> (long )i ),
136+ DOUBLE_BE (double .class , ValueLayout .JAVA_DOUBLE_UNALIGNED .withOrder (ByteOrder .BIG_ENDIAN ), i -> (double )i );
115137
116138 final ValueLayout layout ;
117139 final IntFunction <Object > valueConverter ;
@@ -124,97 +146,61 @@ <Z> Type(Class<Z> carrier, ValueLayout layout, IntFunction<Z> valueConverter) {
124146 this .valueConverter = (IntFunction <Object >)valueConverter ;
125147 }
126148
127- int size () {
128- return ( int ) layout .byteSize ();
149+ long size () {
150+ return layout .byteSize ();
129151 }
130152
131153 VarHandle handle () {
132154 return MethodHandles .memorySegmentViewVarHandle (layout );
133155 }
134156
135- void set (SegmentSlice slice , int index , int val ) {
136- handle ().set (slice . segment , index * size (), valueConverter .apply (val ));
157+ void set (MemorySegment segment , long offset , int index , int val ) {
158+ handle ().set (segment , offset + ( index * size () ), valueConverter .apply (val ));
137159 }
138160
139- void check (SegmentSlice slice , int index , int val ) {
140- assertEquals (handle ().get (slice . segment , index * size ()), valueConverter .apply (val ));
161+ void check (MemorySegment segment , long offset , int index , int val ) {
162+ assertEquals (handle ().get (segment , offset + ( index * size () )), valueConverter .apply (val ));
141163 }
142164 }
143165
144- static class SegmentSlice {
145-
146- enum Kind {
147- NATIVE (i -> Arena .ofAuto ().allocate (i , 1 )),
148- ARRAY (i -> MemorySegment .ofArray (new byte [i ]));
149-
150- final IntFunction <MemorySegment > segmentFactory ;
151-
152- Kind (IntFunction <MemorySegment > segmentFactory ) {
153- this .segmentFactory = segmentFactory ;
154- }
166+ enum SegmentKind {
167+ NATIVE (i -> Arena .ofAuto ().allocate (i , 1 )),
168+ ARRAY (i -> MemorySegment .ofArray (new byte [i ]));
155169
156- MemorySegment makeSegment (int elems ) {
157- return segmentFactory .apply (elems );
158- }
159- }
160-
161- final Kind kind ;
162- final Type type ;
163- final int first ;
164- final int last ;
165- final MemorySegment segment ;
166-
167- public SegmentSlice (Kind kind , Type type , int first , int last , MemorySegment segment ) {
168- this .kind = kind ;
169- this .type = type ;
170- this .first = first ;
171- this .last = last ;
172- this .segment = segment ;
173- }
170+ final IntFunction <MemorySegment > segmentFactory ;
174171
175- void set ( int index , int val ) {
176- type . set ( this , index , val ) ;
172+ SegmentKind ( IntFunction < MemorySegment > segmentFactory ) {
173+ this . segmentFactory = segmentFactory ;
177174 }
178175
179- void check (int index , int val ) {
180- type .check (this , index , val );
181- }
182-
183- int byteSize () {
184- return last - first + 1 ;
185- }
186-
187- int elementSize () {
188- return byteSize () / type .size ();
176+ MemorySegment makeSegment (int size ) {
177+ return segmentFactory .apply (size );
189178 }
179+ }
190180
191- @ Override
192- public String toString () {
193- return String .format ("SegmentSlice{%s, %d, %d}" , type , first , last );
181+ @ DataProvider
182+ static Object [][] segmentKinds () {
183+ List <Object []> cases = new ArrayList <>();
184+ for (SegmentKind kind1 : SegmentKind .values ()) {
185+ for (SegmentKind kind2 : SegmentKind .values ()) {
186+ cases .add (new Object [] {kind1 , kind2 });
187+ }
194188 }
189+ return cases .toArray (Object [][]::new );
195190 }
196191
197- @ DataProvider (name = "slices" )
198- static Object [][] elementSlices () {
199- List <SegmentSlice > slices = new ArrayList <>();
200- for (SegmentSlice .Kind kind : SegmentSlice .Kind .values ()) {
201- MemorySegment segment = kind .makeSegment (16 );
202- //compute all slices
203- for (Type type : Type .values ()) {
204- for (int index = 0 ; index < 16 ; index += type .size ()) {
205- MemorySegment first = segment .asSlice (0 , index );
206- slices .add (new SegmentSlice (kind , type , 0 , index - 1 , first ));
207- MemorySegment second = segment .asSlice (index );
208- slices .add (new SegmentSlice (kind , type , index , 15 , second ));
192+ @ DataProvider
193+ static Object [][] segmentKindsAndTypes () {
194+ List <Object []> cases = new ArrayList <>();
195+ for (Object [] segmentKinds : segmentKinds ()) {
196+ for (Type type1 : Type .values ()) {
197+ for (Type type2 : Type .values ()) {
198+ if (type1 .layout .carrier () == type2 .layout .carrier ()) {
199+ cases .add (new Object []{segmentKinds [0 ], segmentKinds [1 ], type1 , type2 });
200+ }
209201 }
210202 }
211203 }
212- Object [][] sliceArray = new Object [slices .size () * slices .size ()][];
213- for (int i = 0 ; i < slices .size () ; i ++) {
214- for (int j = 0 ; j < slices .size () ; j ++) {
215- sliceArray [i * slices .size () + j ] = new Object [] { slices .get (i ), slices .get (j ) };
216- }
217- }
218- return sliceArray ;
204+ return cases .toArray (Object [][]::new );
219205 }
220206}
0 commit comments