17
17
*/
18
18
package com .graphhopper .storage ;
19
19
20
- import com .graphhopper .util .Constants ;
21
20
import com .graphhopper .util .Helper ;
22
21
import org .slf4j .Logger ;
23
22
import org .slf4j .LoggerFactory ;
56
55
*/
57
56
public final class MMapDataAccess extends AbstractDataAccess {
58
57
59
- private static final Logger LOGGER = LoggerFactory .getLogger (MMapDataAccess .class );
60
-
61
58
private final boolean allowWrites ;
62
59
private RandomAccessFile raFile ;
63
60
private final List <MappedByteBuffer > segments = new ArrayList <>();
@@ -67,96 +64,35 @@ public final class MMapDataAccess extends AbstractDataAccess {
67
64
this .allowWrites = allowWrites ;
68
65
}
69
66
70
- public static boolean jreIsMinimumJava9 () {
71
- final StringTokenizer st = new StringTokenizer (System .getProperty ("java.specification.version" ), "." );
72
- int JVM_MAJOR_VERSION = Integer .parseInt (st .nextToken ());
73
- int JVM_MINOR_VERSION ;
74
- if (st .hasMoreTokens ()) {
75
- JVM_MINOR_VERSION = Integer .parseInt (st .nextToken ());
76
- } else {
77
- JVM_MINOR_VERSION = 0 ;
78
- }
79
- return JVM_MAJOR_VERSION > 1 || (JVM_MAJOR_VERSION == 1 && JVM_MINOR_VERSION >= 9 );
80
- }
81
-
82
67
public static void cleanMappedByteBuffer (final ByteBuffer buffer ) {
83
68
// TODO avoid reflection on every call
84
69
try {
85
70
AccessController .doPrivileged (new PrivilegedExceptionAction <Object >() {
86
71
@ Override
87
72
public Object run () throws Exception {
88
- if (jreIsMinimumJava9 ()) {
89
- // >=JDK9 class sun.misc.Unsafe { void invokeCleaner(ByteBuffer buf) }
90
- final Class <?> unsafeClass = Class .forName ("sun.misc.Unsafe" );
91
- // fetch the unsafe instance and bind it to the virtual MethodHandle
92
- final Field f = unsafeClass .getDeclaredField ("theUnsafe" );
93
- f .setAccessible (true );
94
- final Object theUnsafe = f .get (null );
95
- final Method method = unsafeClass .getDeclaredMethod ("invokeCleaner" , ByteBuffer .class );
96
- try {
97
- method .invoke (theUnsafe , buffer );
98
- return null ;
99
- } catch (Throwable t ) {
100
- throw new RuntimeException (t );
101
- }
102
- }
103
-
104
- if (buffer .getClass ().getSimpleName ().equals ("MappedByteBufferAdapter" )) {
105
- if (!Constants .ANDROID )
106
- throw new RuntimeException ("MappedByteBufferAdapter only supported for Android at the moment" );
107
-
108
- // For Android 4.1 call ((MappedByteBufferAdapter)buffer).free() see #914
109
- Class <?> directByteBufferClass = Class .forName ("java.nio.MappedByteBufferAdapter" );
110
- callBufferFree (buffer , directByteBufferClass );
111
- } else {
112
- // <=JDK8 class DirectByteBuffer { sun.misc.Cleaner cleaner(Buffer buf) }
113
- // then call sun.misc.Cleaner.clean
114
- final Class <?> directByteBufferClass = Class .forName ("java.nio.DirectByteBuffer" );
115
- try {
116
- final Method dbbCleanerMethod = directByteBufferClass .getMethod ("cleaner" );
117
- dbbCleanerMethod .setAccessible (true );
118
- // call: cleaner = ((DirectByteBuffer)buffer).cleaner()
119
- final Object cleaner = dbbCleanerMethod .invoke (buffer );
120
- if (cleaner != null ) {
121
- final Class <?> cleanerMethodReturnType = dbbCleanerMethod .getReturnType ();
122
- final Method cleanMethod = cleanerMethodReturnType .getDeclaredMethod ("clean" );
123
- cleanMethod .setAccessible (true );
124
- // call: ((sun.misc.Cleaner)cleaner).clean()
125
- cleanMethod .invoke (cleaner );
126
- }
127
- } catch (NoSuchMethodException ex2 ) {
128
- if (Constants .ANDROID )
129
- // For Android 5.1.1 call ((DirectByteBuffer)buffer).free() see #933
130
- callBufferFree (buffer , directByteBufferClass );
131
- else
132
- // ignore if method cleaner or clean is not available
133
- LOGGER .warn ("NoSuchMethodException | " + System .getProperty ("java.version" ), ex2 );
134
- }
73
+ // >=JDK9 class sun.misc.Unsafe { void invokeCleaner(ByteBuffer buf) }
74
+ final Class <?> unsafeClass = Class .forName ("sun.misc.Unsafe" );
75
+ // fetch the unsafe instance and bind it to the virtual MethodHandle
76
+ final Field f = unsafeClass .getDeclaredField ("theUnsafe" );
77
+ f .setAccessible (true );
78
+ final Object theUnsafe = f .get (null );
79
+ final Method method = unsafeClass .getDeclaredMethod ("invokeCleaner" , ByteBuffer .class );
80
+ try {
81
+ method .invoke (theUnsafe , buffer );
82
+ return null ;
83
+ } catch (Throwable t ) {
84
+ throw new RuntimeException (t );
135
85
}
136
-
137
- return null ;
138
86
}
139
87
});
140
88
} catch (PrivilegedActionException e ) {
141
89
throw new RuntimeException ("Unable to unmap the mapped buffer" , e );
142
90
}
143
91
}
144
92
145
- private static void callBufferFree (ByteBuffer buffer , Class <?> directByteBufferClass )
146
- throws InvocationTargetException , IllegalAccessException {
147
- try {
148
- final Method dbbFreeMethod = directByteBufferClass .getMethod ("free" );
149
- dbbFreeMethod .setAccessible (true );
150
- dbbFreeMethod .invoke (buffer );
151
- } catch (NoSuchMethodException ex2 ) {
152
- LOGGER .warn ("NoSuchMethodException | " + System .getProperty ("java.version" ), ex2 );
153
- }
154
- }
155
-
156
93
private void initRandomAccessFile () {
157
- if (raFile != null ) {
94
+ if (raFile != null )
158
95
return ;
159
- }
160
96
161
97
try {
162
98
// raFile necessary for loadExisting and create
0 commit comments