Index: lucene/src/java/org/apache/lucene/store/MMapDirectory.java
===================================================================
--- lucene/src/java/org/apache/lucene/store/MMapDirectory.java (revision 998311)
+++ lucene/src/java/org/apache/lucene/store/MMapDirectory.java (working copy)
@@ -78,7 +78,7 @@
*
*/
public class MMapDirectory extends FSDirectory {
- private boolean useUnmapHack = false;
+ private boolean useUnmapHack = UNMAP_SUPPORTED;
private int maxBBuf = Constants.JRE_IS_64BIT ? Integer.MAX_VALUE : (256 * 1024 * 1024);
/** Create a new MMapDirectory for the named location.
@@ -100,22 +100,89 @@
public MMapDirectory(File path) throws IOException {
super(path, null);
}
+
+ private enum Platform {
+ UNSUPPORTED {
+ @Override
+ final void cleanMapping(final ByteBuffer buffer) {
+ // do nothing
+ }
+ },
+
+ SUN {
+ @Override
+ final void cleanMapping(final ByteBuffer buffer) throws IOException {
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Void run() throws Exception {
+ final Method getCleanerMethod = buffer.getClass()
+ .getMethod("cleaner");
+ getCleanerMethod.setAccessible(true);
+ final Object cleaner = getCleanerMethod.invoke(buffer);
+ if (cleaner != null) {
+ cleaner.getClass().getMethod("clean")
+ .invoke(cleaner);
+ }
+ return null;
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ final IOException ioe = new IOException("unable to unmap the mapped buffer");
+ ioe.initCause(e.getCause());
+ throw ioe;
+ }
+ }
+ },
+
+ HARMONY {
+ @Override
+ final void cleanMapping(final ByteBuffer buffer) throws IOException {
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Void run() throws Exception {
+ final Method freeMethod = buffer.getClass()
+ .getMethod("free");
+ freeMethod.setAccessible(true);
+ freeMethod.invoke(buffer);
+ return null;
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ final IOException ioe = new IOException("unable to unmap the mapped buffer");
+ ioe.initCause(e.getCause());
+ throw ioe;
+ }
+ }
+ };
+
+ abstract void cleanMapping(final ByteBuffer buffer) throws IOException;
+ };
/**
* true, if this platform supports unmapping mmapped files.
*/
public static final boolean UNMAP_SUPPORTED;
+ private static final Platform PLATFORM;
static {
- boolean v;
+ Platform platform;
+ // Sun VM case
try {
Class.forName("sun.misc.Cleaner");
Class.forName("java.nio.DirectByteBuffer")
.getMethod("cleaner");
- v = true;
- } catch (Exception e) {
- v = false;
+ platform = Platform.SUN;
+ } catch (Exception e1) {
+ // Apache Harmony
+ try {
+ Class.forName("java.nio.DirectByteBuffer")
+ .getMethod("free");
+ platform = Platform.HARMONY;
+ } catch (Exception e2) {
+ platform = Platform.UNSUPPORTED;
+ }
}
- UNMAP_SUPPORTED = v;
+ PLATFORM = platform;
+ UNMAP_SUPPORTED = PLATFORM != Platform.UNSUPPORTED;
}
/**
@@ -143,37 +210,8 @@
public boolean getUseUnmap() {
return useUnmapHack;
}
-
+
/**
- * Try to unmap the buffer, this method silently fails if no support
- * for that in the JVM. On Windows, this leads to the fact,
- * that mmapped files cannot be modified or deleted.
- */
- final void cleanMapping(final ByteBuffer buffer) throws IOException {
- if (useUnmapHack) {
- try {
- AccessController.doPrivileged(new PrivilegedExceptionAction