Index: lucene/core/src/java/org/apache/lucene/store/ByteBufferIndexInput.java =================================================================== --- lucene/core/src/java/org/apache/lucene/store/ByteBufferIndexInput.java (revision 1441327) +++ lucene/core/src/java/org/apache/lucene/store/ByteBufferIndexInput.java (working copy) @@ -51,14 +51,15 @@ private ByteBuffer curBuf; // redundant for speed: buffers[curBufIndex] private boolean isClone = false; - private final WeakIdentityMap clones = WeakIdentityMap.newConcurrentHashMap(); + private final WeakIdentityMap clones; - ByteBufferIndexInput(String resourceDescription, ByteBuffer[] buffers, long length, int chunkSizePower) throws IOException { + ByteBufferIndexInput(String resourceDescription, ByteBuffer[] buffers, long length, int chunkSizePower, boolean trackClones) throws IOException { super(resourceDescription); this.buffers = buffers; this.length = length; this.chunkSizePower = chunkSizePower; this.chunkSizeMask = (1L << chunkSizePower) - 1L; + this.clones = trackClones ? WeakIdentityMap.newConcurrentHashMap() : null; assert chunkSizePower >= 0 && chunkSizePower <= 30; assert (length >>> chunkSizePower) < Integer.MAX_VALUE; @@ -231,7 +232,9 @@ clone.length = length; // register the new clone in our clone list to clean it up on closing: - this.clones.put(clone, Boolean.TRUE); + if (clones != null) { + this.clones.put(clone, Boolean.TRUE); + } return clone; } @@ -272,17 +275,21 @@ // make local copy, then un-set early final ByteBuffer[] bufs = buffers; unsetBuffers(); - clones.remove(this); + if (clones != null) { + clones.remove(this); + } if (isClone) return; // for extra safety unset also all clones' buffers: - for (Iterator it = this.clones.keyIterator(); it.hasNext();) { - final ByteBufferIndexInput clone = it.next(); - assert clone.isClone; - clone.unsetBuffers(); + if (clones != null) { + for (Iterator it = this.clones.keyIterator(); it.hasNext();) { + final ByteBufferIndexInput clone = it.next(); + assert clone.isClone; + clone.unsetBuffers(); + } + this.clones.clear(); } - this.clones.clear(); for (final ByteBuffer b : bufs) { freeBuffer(b); Index: lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java =================================================================== --- lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java (revision 1441327) +++ lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java (working copy) @@ -178,36 +178,6 @@ } /** - * 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() { - @Override - public Object 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; - } - } - } - - /** * Returns the current mmap chunk size. * @see #MMapDirectory(File, LockFactory, int) */ @@ -246,14 +216,42 @@ } private final class MMapIndexInput extends ByteBufferIndexInput { + private final boolean useUnmapHack; MMapIndexInput(String resourceDescription, RandomAccessFile raf) throws IOException { - super(resourceDescription, map(raf, 0, raf.length()), raf.length(), chunkSizePower); + super(resourceDescription, map(raf, 0, raf.length()), raf.length(), chunkSizePower, getUseUnmap()); + this.useUnmapHack = getUseUnmap(); } + /** + * 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. + */ @Override - protected void freeBuffer(ByteBuffer buffer) throws IOException { - cleanMapping(buffer); + protected void freeBuffer(final ByteBuffer buffer) throws IOException { + if (useUnmapHack) { + try { + AccessController.doPrivileged(new PrivilegedExceptionAction() { + @Override + 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; + } + } } }