Memory Mapped file segment (file is empty)

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Jun 25 13:53:05 UTC 2020


On 25/06/2020 11:02, Johannes Lichtenberger wrote:
> Thanks, is it already available in a JDK 14 binary or should I wait 
> till october?

You might try here:

https://jdk.java.net/15/

> Furthermore, regarding the usage itself, is this okay to get a 
> byte-array from the memory mapped file or should I use some sort of 
> MemoryLayout...?
>
> final byte[]page =new byte[dataLength];
>
> final VarHandle byteVarHandle =MemoryHandles.varHandle(byte.class,ByteOrder.nativeOrder());
>
> for (int i =0; i <dataLength; i++) {
>    // 4 (dataLength) + 1 = 5 in offset, as the loop starts with 0 we have 
> to add one to the offset page[i] = (byte)byteVarHandle.get(baseAddress.addOffset(5 + i), i);
> }

For now this is ok, we do not support mapping complex layouts to arrays 
(we might consider it in the future).

Worth mentioning - the above code will not perform very well; it would 
be better to create an indexed var handle from the layout of the element 
you want to access. E.g.

VarHandle intHandle = 
MemoryLayout.ofSequence(MemoryLayouts.JAVA_INT).varHandle(int.class, 
PathElement.sequenceElement());

And then use the handle in a loop, like this:

for (int i = 0; i < n ; i++) {
    intHandle.get(baseAddress, (long)i);
}


> And from what I understand about memory mapped files -- not related to 
> your API -- but in general it makes sense to map the whole 
> "database"-file and not just a small page-portion, right? As it will 
> fetch the page on-demand into the non heap memory location.

In the Java 15 API you can map a smaller portion of a file (by passing 
an offset and a size); this was possible with the ByteBuffer API, but 
that option was partially omitted in the segment API.

I think when it comes to mapped files, mileage can vary - I believe some 
of my colleagues (and people in this very mailing list) are much more 
knowledgeable than I am when it comes to fine tuning the size of mapped 
memory regions :-)


> Another thing, which might be sonsense as of now is this I guess:
> https://github.com/sirixdb/sirix/blob/7bdbd5d17a034f02902f8f7dd0ef7012d89c81fb/bundles/sirix-core/src/main/java/org/sirix/io/memorymapped/MemoryMappedFileWriter.java#L140 
>
> First, an (on-heap) byte-array is produced, such that a database 
> page-fragment is serialized with all its records to it. Basically, the 
> DataOutput interface is used to serialize/deserialize stuff in-memory, 
> do compression, encryption... Changing this might be more work, and I 
> guess it's okay.
> Then, I think I can skip the ByteBuffer (just copied from the 
> RandomAccessFile based implementation), then copying the byte buffer 
> again to the memory mapped file segment.

Yep - it seems to me that you should be able to use the memory access 
API directly here.

Maurizio

> Kind regards
> Johannes
>
> Am Do., 25. Juni 2020 um 11:26 Uhr schrieb Maurizio Cimadamore 
> <maurizio.cimadamore at oracle.com <mailto:maurizio.cimadamore at oracle.com>>:
>
>     Hi Johannes,
>     the specific condition you are talking about has been rectified in
>     the
>     upcoming Java 15.
>
>     The new code should be doing something like this:
>
>     ```
>     if (bytesSize < 0) throw new IllegalArgumentException("Requested
>     bytes
>     size must be >= 0.");
>     if (bytesOffset < 0) throw new IllegalArgumentException("Requested
>     bytes
>     offset must be >= 0.");
>     ```
>
>     So, hopefully, your code should work against the latest version of
>     the API
>
>     Maurizio
>
>     On 25/06/2020 08:24, Johannes Lichtenberger wrote:
>     > Hi Paul,
>     >
>     > that's great. I guess usually there's a -dev and a -user
>     Mailinglist,
>     > that's why I thought it's for internal development topics.
>     >
>     > I'm using AdpotOpenJDK, because I wanted to try Shenandoah,
>     which is at
>     > least not in the Oracle binaries.
>     >
>     > IMPLEMENTOR="AdoptOpenJDK"
>     > IMPLEMENTOR_VERSION="AdoptOpenJDK"
>     > JAVA_VERSION="14.0.1"
>     > JAVA_VERSION_DATE="2020-04-14"
>     >
>     > BTW: My OS is Linux/Ubuntu.
>     >
>     > Kind regards
>     > Johannes
>     >
>     > Am Do., 25. Juni 2020 um 02:04 Uhr schrieb Paul Sandoz <
>     > paul.sandoz at oracle.com <mailto:paul.sandoz at oracle.com>>:
>     >
>     >> Hi Johannes,
>     >>
>     >> This is the correct list. Feedback on the API and its usability
>     is very
>     >> important, as well as whether the implementation works as expected.
>     >>
>     >> This was fixed in https://bugs.openjdk.java.net/browse/JDK-8246095
>     >>
>     >>
>     >>
>     https://github.com/openjdk/panama-foreign/blob/foreign-memaccess/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/MappedMemorySegmentImpl.java#L102
>     >>
>     >> What JDK build are you using?
>     >>
>     >> Paul.
>     >>
>     >> On Jun 24, 2020, at 3:48 PM, Johannes Lichtenberger <
>     >> lichtenberger.johannes at gmail.com
>     <mailto:lichtenberger.johannes at gmail.com>> wrote:
>     >>
>     >> Hi,
>     >>
>     >> I guess that's not the right mailinglist to ask for help with
>     the API, but
>     >> maybe you can point me at least somewhere.
>     >>
>     >> Currently I face the problem, that I can't get a memory segment
>     on an empty
>     >> file when I want to memory map a file. However, a writer would
>     write to the
>     >> memory mapped file.
>     >>
>     >> I want to be able to swap a rather old RandomAccessFile based
>     >> implementation with a memory mapped file implementation. The
>     two classes
>     >> (actually three, but only the FileReader and FileWriter
>     matters) are rather
>     >> simple.
>     >>
>     >> The old package:
>     >>
>     >>
>     >>
>     https://github.com/sirixdb/sirix/tree/master/bundles/sirix-core/src/main/java/org/sirix/io/file
>     >>
>     >>
>     >> and the new package
>     >>
>     >>
>     >>
>     https://github.com/sirixdb/sirix/tree/master/bundles/sirix-core/src/main/java/org/sirix/io/memorymapped
>     >>
>     >> This line fails if the underlying file size is 0:
>     >>
>     >>
>     >>
>     https://github.com/sirixdb/sirix/blob/7bdbd5d17a034f02902f8f7dd0ef7012d89c81fb/bundles/sirix-core/src/main/java/org/sirix/io/memorymapped/MemoryMappedFileWriter.java#L83
>     >>
>     >> Stacktrace  (Precondition fails, so I'm not using the API in
>     the intended
>     >> way):
>     >>
>     >> java.lang.IllegalArgumentException: Requested bytes size must
>     be > 0.
>     >>
>     >> at
>     >>
>     >>
>     jdk.incubator.foreign/jdk.internal.foreign.Utils.makeMappedSegment(Utils.java:140)
>     >> at
>     >>
>     >>
>     jdk.incubator.foreign/jdk.incubator.foreign.MemorySegment.mapFromPath(MemorySegment.java:398)
>     >> at
>     >>
>     >>
>     org.sirix.io.memorymapped.MemoryMappedFileWriter.<init>(MemoryMappedFileWriter.java:83)
>     >>
>     >>
>     >> So, it might be easiest to write a more or less direct
>     conversion to the
>     >> Foreign Memory API. Maybe someone can help or point me to a helpful
>     >> Mailinglist/Forum/whatever.
>     >>
>     >> Kind regards
>     >> Johannes
>     >>
>     >>
>     >>
>


More information about the panama-dev mailing list