org.apache.lucene.store
Class MMapDirectory

java.lang.Object
  extended by org.apache.lucene.store.Directory
      extended by org.apache.lucene.store.FSDirectory
          extended by org.apache.lucene.store.MMapDirectory

public class MMapDirectory
extends FSDirectory

File-based Directory implementation that uses mmap for reading, and SimpleFSDirectory.SimpleFSIndexOutput for writing.

NOTE: memory mapping uses up a portion of the virtual memory address space in your process equal to the size of the file being mapped. Before using this class, be sure your have plenty of virtual address space, e.g. by using a 64 bit JRE, or a 32 bit JRE with indexes that are guaranteed to fit within the address space. On 32 bit platforms also consult setMaxChunkSize(int) if you have problems with mmap failing because of fragmented address space. If you get an OutOfMemoryException, it is recommended to reduce the chunk size, until it works.

Due to this bug in Sun's JRE, MMapDirectory's IndexInput.close() is unable to close the underlying OS file handle. Only when GC finally collects the underlying objects, which could be quite some time later, will the file handle be closed.

This will consume additional transient disk usage: on Windows, attempts to delete or overwrite the files will result in an exception; on other platforms, which typically have a "delete on last close" semantics, while such operations will succeed, the bytes are still consuming space on disk. For many applications this limitation is not a problem (e.g. if you have plenty of disk space, and you don't rely on overwriting files on Windows) but it's still an important limitation to be aware of.

This class supplies the workaround mentioned in the bug report (disabled by default, see setUseUnmap(boolean)), which may fail on non-Sun JVMs. It forcefully unmaps the buffer on close by using an undocumented internal cleanup functionality. UNMAP_SUPPORTED is true, if the workaround can be enabled (with no guarantees).

NOTE: Accessing this class either directly or indirectly from a thread while it's interrupted can close the underlying channel immediately if at the same time the thread is blocked on IO. The channel will remain closed and subsequent access to MMapDirectory will throw a ClosedChannelException.


Nested Class Summary
 
Nested classes/interfaces inherited from class org.apache.lucene.store.FSDirectory
FSDirectory.FSIndexInput, FSDirectory.FSIndexOutput
 
Field Summary
static boolean UNMAP_SUPPORTED
          true, if this platform supports unmapping mmapped files.
 
Fields inherited from class org.apache.lucene.store.FSDirectory
DEFAULT_READ_CHUNK_SIZE, directory, LOCK_DIR
 
Fields inherited from class org.apache.lucene.store.Directory
isOpen, lockFactory
 
Constructor Summary
MMapDirectory(File path)
          Create a new MMapDirectory for the named location and NativeFSLockFactory.
MMapDirectory(File path, LockFactory lockFactory)
          Create a new MMapDirectory for the named location.
 
Method Summary
 IndexOutput createOutput(String name)
          Creates an IndexOutput for the file with the given name.
 int getMaxChunkSize()
          Returns the current mmap chunk size.
 boolean getUseUnmap()
          Returns true, if the unmap workaround is enabled.
 IndexInput openInput(String name, int bufferSize)
          Creates an IndexInput for the file with the given name.
 void setMaxChunkSize(int maxBBuf)
          Sets the maximum chunk size (default is Integer.MAX_VALUE for 64 bit JVMs and 256 MiBytes for 32 bit JVMs) used for memory mapping.
 void setUseUnmap(boolean useUnmapHack)
          This method enables the workaround for unmapping the buffers from address space after closing IndexInput, that is mentioned in the bug report.
 
Methods inherited from class org.apache.lucene.store.FSDirectory
close, deleteFile, fileExists, fileLength, fileModified, fileModified, getDirectory, getDirectory, getDirectory, getDirectory, getDirectory, getDirectory, getDisableLocks, getFile, getLockID, getReadChunkSize, initOutput, list, listAll, listAll, open, open, openInput, renameFile, setDisableLocks, setReadChunkSize, sync, toString, touchFile
 
Methods inherited from class org.apache.lucene.store.Directory
clearLock, copy, ensureOpen, getLockFactory, makeLock, setLockFactory
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

UNMAP_SUPPORTED

public static final boolean UNMAP_SUPPORTED
true, if this platform supports unmapping mmapped files.

Constructor Detail

MMapDirectory

public MMapDirectory(File path,
                     LockFactory lockFactory)
              throws IOException
Create a new MMapDirectory for the named location.

Parameters:
path - the path of the directory
lockFactory - the lock factory to use, or null for the default (NativeFSLockFactory);
Throws:
IOException

MMapDirectory

public MMapDirectory(File path)
              throws IOException
Create a new MMapDirectory for the named location and NativeFSLockFactory.

Parameters:
path - the path of the directory
Throws:
IOException
Method Detail

setUseUnmap

public void setUseUnmap(boolean useUnmapHack)
This method enables the workaround for unmapping the buffers from address space after closing IndexInput, that is mentioned in the bug report. This hack may fail on non-Sun JVMs. It forcefully unmaps the buffer on close by using an undocumented internal cleanup functionality.

NOTE: Enabling this is completely unsupported by Java and may lead to JVM crashes if IndexInput is closed while another thread is still accessing it (SIGSEGV).

Throws:
IllegalArgumentException - if UNMAP_SUPPORTED is false and the workaround cannot be enabled.

getUseUnmap

public boolean getUseUnmap()
Returns true, if the unmap workaround is enabled.

See Also:
setUseUnmap(boolean)

setMaxChunkSize

public void setMaxChunkSize(int maxBBuf)
Sets the maximum chunk size (default is Integer.MAX_VALUE for 64 bit JVMs and 256 MiBytes for 32 bit JVMs) used for memory mapping. Especially on 32 bit platform, the address space can be very fragmented, so large index files cannot be mapped. Using a lower chunk size makes the directory implementation a little bit slower (as the correct chunk must be resolved on each seek) but the chance is higher that mmap does not fail. On 64 bit Java platforms, this parameter should always be Integer.MAX_VALUE, as the address space is big enough.


getMaxChunkSize

public int getMaxChunkSize()
Returns the current mmap chunk size.

See Also:
setMaxChunkSize(int)

openInput

public IndexInput openInput(String name,
                            int bufferSize)
                     throws IOException
Creates an IndexInput for the file with the given name.

Overrides:
openInput in class FSDirectory
Throws:
IOException

createOutput

public IndexOutput createOutput(String name)
                         throws IOException
Creates an IndexOutput for the file with the given name.

Overrides:
createOutput in class FSDirectory
Throws:
IOException


Copyright © 2000-2010 Apache Software Foundation. All Rights Reserved.