153. Introducing layout reshaping
Let’s suppose that we have the following nested model (the exact same model as in Problem 151):
SequenceLayout innerSeq
= MemoryLayout.sequenceLayout(5, ValueLayout.JAVA_DOUBLE);
SequenceLayout outerSeq
= MemoryLayout.sequenceLayout(10, innerSeq);
Next, we define a VarHandle via PathElement and we populate this model accordingly with some random data (you can see the code listed in Problem 151).Our goal is to reshape this model to look as follows:
SequenceLayout innerSeq
= MemoryLayout.sequenceLayout(25, ValueLayout.JAVA_DOUBLE);
SequenceLayout outerSeq
= MemoryLayout.sequenceLayout(2, innerSeq);
So, instead of having 10 sequences of 5 double values each, we want 25 sequences of 2 double values each. In order to accomplish this reshaping goal, we can rely on the reshape(long… elementCounts) method. This method takes the elements of this sequence layout and re-arranges them into a multi-dimensional sequence layout conforming to the given list of element counts per sequence. So, in our case, we do it as follows:
SequenceLayout reshaped = outerSeq.reshape(25, 2);
You can see the complete example in the bundled code.
154. Introducing layout spreader
Let’s suppose that we have the following nested model (the exact same model as in Problem 151):
SequenceLayout innerSeq
= MemoryLayout.sequenceLayout(5, ValueLayout.JAVA_DOUBLE);
SequenceLayout outerSeq
= MemoryLayout.sequenceLayout(10, innerSeq);
Next, we define a VarHandle via PathElement and we populate this model accordingly with some random data (you can see the code listed in Problem 151).Next, let’s assume that we want to extract the third double value from the seventh sequence (count starts from 0). Among the approaches, we can rely on sliceHandle() introduced in Problem 151 as follows:
MethodHandle mHandle = outerSeq.sliceHandle(
PathElement.sequenceElement(),
PathElement.sequenceElement());
MemorySegment ms = (MemorySegment)
mHandle.invokeExact(segment, 7L, 3L);
System.out.println(ms.get(ValueLayout.JAVA_DOUBLE, 0));
Another approach consists of using an array-spreading method handle. In other words, by calling the asSpreader(Class<?> arrayType, int arrayLength) method we can obtain a spreader-array that contains the positional-arguments that we want to pass over and has a length equal to the given arrayLength. Since we have two pass over long arguments (7L and 3L) we need a long[] array of length 2:
MemorySegment ms = (MemorySegment) mHandle
.asSpreader(Long[].class, 2)
.invokeExact(segment, new Long[]{7L, 3L});
You may also be interested in asCollector(Class<?> arrayType, int arrayLength) which is basically the opposite of asSpreader(). You give a list of arguments and this method collects them in an array-collecting.