You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ignite.apache.org by "NSAmelchev (via GitHub)" <gi...@apache.org> on 2023/10/02 10:11:38 UTC

Re: [PR] IGNITE-20515 Fix MappedFile.map for JDK 14 and newer. [ignite]

NSAmelchev commented on code in PR #10961:
URL: https://github.com/apache/ignite/pull/10961#discussion_r1342507741


##########
modules/core/src/main/java/org/apache/ignite/internal/mem/file/MappedFile.java:
##########
@@ -141,14 +134,166 @@ public static long map(RandomAccessFile f, int mode, long start, long size) thro
      * @param size Size of the mapped file.
      */
     public static void unmap(long addr, long size) {
-        try {
-            unmap0.invoke(null, addr, size);
+        mapper.unmap(addr, size);
+    }
+
+    /** */
+    private static Mapper pickMapper() {
+        int javaVersion = majorJavaVersion(jdkVersion());
+
+        if (javaVersion >= 19)
+            return new JDK19Mapper();
+
+        if (javaVersion >= 14)
+            return new JDK14Mapper();
+
+        return new LegacyMapper();
+    }
+
+    /** */
+    private interface Mapper {
+        /** */
+        long map(RandomAccessFile f, int mode, long start, long size) throws IOException;
+
+        /** */
+        void unmap(long addr, long size);
+    }
+
+    /** */
+    private static class LegacyMapper implements Mapper {
+        /** */
+        private static final Method map0 = U.findNonPublicMethod(FileChannelImpl.class, "map0", int.class, long.class, long.class);
+
+        /** */
+        private static final Method unmap0 = U.findNonPublicMethod(FileChannelImpl.class, "unmap0", long.class, long.class);
+
+
+        /** {@inheritDoc} */
+        @Override public long map(RandomAccessFile f, int mode, long start, long size) throws IOException {
+            try {
+                return (Long)map0.invoke(f.getChannel(), mode, start, size);
+            }
+            catch (IllegalAccessException e) {
+                throw new IllegalStateException(e);
+            }
+            catch (InvocationTargetException e) {
+                Throwable target = e.getTargetException();
+                throw (target instanceof IOException) ? (IOException)target : new IOException(target);
+            }
+        }
+
+        /** {@inheritDoc} */
+        @Override public void unmap(long addr, long size) {
+            try {
+                unmap0.invoke(null, addr, size);
+            }
+            catch (IllegalAccessException e) {
+                throw new IllegalStateException(e);
+            }
+            catch (InvocationTargetException e) {
+                throw new IllegalStateException(e.getTargetException());
+            }
         }
-        catch (IllegalAccessException e) {
-            throw new IllegalStateException(e);
+    }
+
+    /** */
+    private static class JDK14Mapper extends LegacyMapper {
+        /** Method {@link FileChannelImpl#map0} has additional parameter since JDK 14, isSync, {@code false} by default. */
+        private static final Method map0 = U.findNonPublicMethod(FileChannelImpl.class, "map0", int.class, long.class,
+                long.class, boolean.class);
+
+        /** {@inheritDoc} */
+        @Override public long map(RandomAccessFile f, int mode, long start, long size) throws IOException {
+            try {
+                return (Long)map0.invoke(f.getChannel(), mode, start, size, false);
+            }
+            catch (IllegalAccessException e) {
+                throw new IllegalStateException(e);
+            }
+            catch (InvocationTargetException e) {
+                Throwable target = e.getTargetException();
+                throw (target instanceof IOException) ? (IOException)target : new IOException(target);
+            }
         }
-        catch (InvocationTargetException e) {
-            throw new IllegalStateException(e.getTargetException());
+    }
+
+    /** */
+    private static class JDK19Mapper implements Mapper {
+        /**  */
+        private static final Method map;
+
+        /** */
+        private static final Method unmap;
+
+        /** */
+        private static final Object dispatcher;
+
+        static {
+            try {
+                // These methods are still in {@link FileChannelImpl} class in JDK 19.
+                Method map0 = U.findNonPublicMethod(FileChannelImpl.class, "map0", FileDescriptor.class, int.class,
+                        long.class, long.class, boolean.class);
+
+                Method unmap0 = U.findNonPublicMethod(FileChannelImpl.class, "unmap0", long.class, long.class);
+
+                if (map0 != null && unmap0 != null) {
+                    map = map0;
+                    unmap = unmap0;
+                    dispatcher = null;
+                }
+                else {
+                    // That methods are moved to {@link sun.nio.ch.FileDispatcher}.
+                    Class<?> fileDispatcherCls = Class.forName("sun.nio.ch.FileDispatcher");
+
+                    dispatcher = U.staticField(FileChannelImpl.class, "nd");
+
+                    map = U.findNonPublicMethod(fileDispatcherCls, "map", FileDescriptor.class, int.class,
+                            long.class, long.class, boolean.class);
+
+                    unmap = U.findNonPublicMethod(fileDispatcherCls, "unmap", long.class, long.class);
+
+                }
+            }
+            catch (ClassNotFoundException | IgniteCheckedException e) {
+                throw new ExceptionInInitializerError(e);
+            }
+        }
+
+        /** {@inheritDoc} */
+        @Override public long map(RandomAccessFile f, int mode, long start, long size) throws IOException {
+            try {
+                Object fd = U.field(f.getChannel(), "fd");
+
+                if (dispatcher != null) {
+                    return (Long)map.invoke(dispatcher, fd, mode, start, size, false);
+                }
+                else
+                    return (Long)map.invoke(f.getChannel(), fd, mode, start, size, false);
+

Review Comment:
   Unnecessary line break



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@ignite.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org