Class FSDirectory
- java.lang.Object
-
- org.apache.lucene.store.Directory
-
- org.apache.lucene.store.BaseDirectory
-
- org.apache.lucene.store.FSDirectory
-
- All Implemented Interfaces:
java.io.Closeable,java.lang.AutoCloseable
- Direct Known Subclasses:
MMapDirectory,NativeUnixDirectory,NIOFSDirectory,RAFDirectory,SimpleFSDirectory,WindowsDirectory
public abstract class FSDirectory extends BaseDirectory
Base class for Directory implementations that store index files in the file system. There are currently three core subclasses:SimpleFSDirectoryis a straightforward implementation using Files.newByteChannel. However, it has poor concurrent performance (multiple threads will bottleneck) as it synchronizes when multiple threads read from the same file.NIOFSDirectoryuses java.nio's FileChannel's positional io when reading to avoid synchronization when reading from the same file. Unfortunately, due to a Windows-only Sun JRE bug this is a poor choice for Windows, but on all other platforms this is the preferred choice. Applications usingThread.interrupt()orFuture.cancel(boolean)should useRAFDirectoryinstead. SeeNIOFSDirectoryjava doc for details.MMapDirectoryuses memory-mapped IO when reading. This is a good choice if you have plenty of virtual memory relative to your index size, eg if you are running on a 64 bit JRE, or you are running on a 32 bit JRE but your index sizes are small enough to fit into the virtual memory space. Java has currently the limitation of not being able to unmap files from user code. The files are unmapped, when GC releases the byte buffers. Due to this bug in Sun's JRE, MMapDirectory'sIndexInput.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 a (possibly dangerous) workaround mentioned in the bug report, which may fail on non-Sun JVMs.
Unfortunately, because of system peculiarities, there is no single overall best implementation. Therefore, we've added the
open(java.nio.file.Path)method, to allow Lucene to choose the best FSDirectory implementation given your environment, and the known limitations of each implementation. For users who have no reason to prefer a specific implementation, it's best to simply useopen(java.nio.file.Path). For all others, you should instantiate the desired implementation directly.NOTE: Accessing one of the above subclasses 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 the index will throw a
ClosedChannelException. Applications usingThread.interrupt()orFuture.cancel(boolean)should use the slower legacyRAFDirectoryfrom themiscLucene module instead.The locking implementation is by default
NativeFSLockFactory, but can be changed by passing in a customLockFactoryinstance.- See Also:
Directory
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description (package private) classFSDirectory.FSIndexOutput
-
Field Summary
Fields Modifier and Type Field Description protected java.nio.file.Pathdirectoryprivate java.util.concurrent.atomic.AtomicLongnextTempFileCounterUsed to generate temp file names increateTempOutput(java.lang.String, java.lang.String, org.apache.lucene.store.IOContext).private java.util.concurrent.atomic.AtomicIntegeropsSinceLastDeleteprivate java.util.Set<java.lang.String>pendingDeletesMaps files that we are trying to delete (or we tried already but failed) before attempting to delete that key.-
Fields inherited from class org.apache.lucene.store.BaseDirectory
isOpen, lockFactory
-
-
Constructor Summary
Constructors Modifier Constructor Description protectedFSDirectory(java.nio.file.Path path, LockFactory lockFactory)Create a new FSDirectory for the named location (ctor for subclasses).
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description voidclose()Closes the directory.IndexOutputcreateOutput(java.lang.String name, IOContext context)Creates a new, empty file in the directory and returns anIndexOutputinstance for appending data to this file.IndexOutputcreateTempOutput(java.lang.String prefix, java.lang.String suffix, IOContext context)Creates a new, empty, temporary file in the directory and returns anIndexOutputinstance for appending data to this file.voiddeleteFile(java.lang.String name)Removes an existing file in the directory.voiddeletePendingFiles()Try to delete any pending files that we had previously tried to delete but failed because we are on Windows and the files were still held open.protected voidensureCanRead(java.lang.String name)longfileLength(java.lang.String name)Returns the byte length of a file in the directory.protected voidfsync(java.lang.String name)java.nio.file.PathgetDirectory()java.util.Set<java.lang.String>getPendingDeletions()Returns a set of files currently pending deletion in this directory.java.lang.String[]listAll()Returns names of all files stored in this directory.static java.lang.String[]listAll(java.nio.file.Path dir)Lists all files (including subdirectories) in the directory.private static java.lang.String[]listAll(java.nio.file.Path dir, java.util.Set<java.lang.String> skipNames)private voidmaybeDeletePendingFiles()static FSDirectoryopen(java.nio.file.Path path)Creates an FSDirectory instance, trying to pick the best implementation given the current environment.static FSDirectoryopen(java.nio.file.Path path, LockFactory lockFactory)Just likeopen(Path), but allows you to also specify a customLockFactory.private voidprivateDeleteFile(java.lang.String name, boolean isPendingDelete)voidrename(java.lang.String source, java.lang.String dest)Renamessourcefile todestfile wheredestmust not already exist in the directory.voidsync(java.util.Collection<java.lang.String> names)Ensures that any writes to these files are moved to stable storage (made durable).voidsyncMetaData()Ensures that directory metadata, such as recent file renames, are moved to stable storage.java.lang.StringtoString()-
Methods inherited from class org.apache.lucene.store.BaseDirectory
ensureOpen, obtainLock
-
Methods inherited from class org.apache.lucene.store.Directory
copyFrom, getTempFileName, openChecksumInput, openInput
-
-
-
-
Field Detail
-
directory
protected final java.nio.file.Path directory
-
pendingDeletes
private final java.util.Set<java.lang.String> pendingDeletes
Maps files that we are trying to delete (or we tried already but failed) before attempting to delete that key.
-
opsSinceLastDelete
private final java.util.concurrent.atomic.AtomicInteger opsSinceLastDelete
-
nextTempFileCounter
private final java.util.concurrent.atomic.AtomicLong nextTempFileCounter
Used to generate temp file names increateTempOutput(java.lang.String, java.lang.String, org.apache.lucene.store.IOContext).
-
-
Constructor Detail
-
FSDirectory
protected FSDirectory(java.nio.file.Path path, LockFactory lockFactory) throws java.io.IOExceptionCreate a new FSDirectory for the named location (ctor for subclasses). The directory is created at the named location if it does not yet exist.FSDirectoryresolves the given Path to a canonical / real path to ensure it can correctly lock the index directory and no other process can interfere with changing possible symlinks to the index directory inbetween. If you want to use symlinks and change them dynamically, close allIndexWritersand create a newFSDirectoryinstance.- Parameters:
path- the path of the directorylockFactory- the lock factory to use, or null for the default (NativeFSLockFactory);- Throws:
java.io.IOException- if there is a low-level I/O error
-
-
Method Detail
-
open
public static FSDirectory open(java.nio.file.Path path) throws java.io.IOException
Creates an FSDirectory instance, trying to pick the best implementation given the current environment. The directory returned uses theNativeFSLockFactory. The directory is created at the named location if it does not yet exist.FSDirectoryresolves the given Path when calling this method to a canonical / real path to ensure it can correctly lock the index directory and no other process can interfere with changing possible symlinks to the index directory inbetween. If you want to use symlinks and change them dynamically, close allIndexWritersand create a newFSDirectoryinstance.Currently this returns
MMapDirectoryfor Linux, MacOSX, Solaris, and Windows 64-bit JREs,NIOFSDirectoryfor other non-Windows JREs, andSimpleFSDirectoryfor other JREs on Windows. It is highly recommended that you consult the implementation's documentation for your platform before using this method.NOTE: this method may suddenly change which implementation is returned from release to release, in the event that higher performance defaults become possible; if the precise implementation is important to your application, please instantiate it directly, instead. For optimal performance you should consider using
MMapDirectoryon 64 bit JVMs.See above
- Throws:
java.io.IOException
-
open
public static FSDirectory open(java.nio.file.Path path, LockFactory lockFactory) throws java.io.IOException
Just likeopen(Path), but allows you to also specify a customLockFactory.- Throws:
java.io.IOException
-
listAll
public static java.lang.String[] listAll(java.nio.file.Path dir) throws java.io.IOExceptionLists all files (including subdirectories) in the directory.- Throws:
java.io.IOException- if there was an I/O error during listing
-
listAll
private static java.lang.String[] listAll(java.nio.file.Path dir, java.util.Set<java.lang.String> skipNames) throws java.io.IOException- Throws:
java.io.IOException
-
listAll
public java.lang.String[] listAll() throws java.io.IOExceptionDescription copied from class:DirectoryReturns names of all files stored in this directory. The output must be in sorted (UTF-16, java'sString.compareTo(java.lang.String)) order.
-
fileLength
public long fileLength(java.lang.String name) throws java.io.IOExceptionDescription copied from class:DirectoryReturns the byte length of a file in the directory. This method must throw eitherNoSuchFileExceptionorFileNotFoundExceptionifnamepoints to a non-existing file.- Specified by:
fileLengthin classDirectory- Parameters:
name- the name of an existing file.- Throws:
java.io.IOException- in case of I/O error
-
createOutput
public IndexOutput createOutput(java.lang.String name, IOContext context) throws java.io.IOException
Description copied from class:DirectoryCreates a new, empty file in the directory and returns anIndexOutputinstance for appending data to this file. This method must throwFileAlreadyExistsExceptionif the file already exists.- Specified by:
createOutputin classDirectory- Parameters:
name- the name of the file to create.- Throws:
java.io.IOException- in case of I/O error
-
createTempOutput
public IndexOutput createTempOutput(java.lang.String prefix, java.lang.String suffix, IOContext context) throws java.io.IOException
Description copied from class:DirectoryCreates a new, empty, temporary file in the directory and returns anIndexOutputinstance for appending data to this file. The temporary file name (accessible viaIndexOutput.getName()) will start withprefix, end withsuffixand have a reserved file extension.tmp.- Specified by:
createTempOutputin classDirectory- Throws:
java.io.IOException
-
ensureCanRead
protected void ensureCanRead(java.lang.String name) throws java.io.IOException- Throws:
java.io.IOException
-
sync
public void sync(java.util.Collection<java.lang.String> names) throws java.io.IOExceptionDescription copied from class:DirectoryEnsures that any writes to these files are moved to stable storage (made durable). Lucene uses this to properly commit changes to the index, to prevent a machine/OS crash from corrupting the index.- Specified by:
syncin classDirectory- Throws:
java.io.IOException- See Also:
Directory.syncMetaData()
-
rename
public void rename(java.lang.String source, java.lang.String dest) throws java.io.IOExceptionDescription copied from class:DirectoryRenamessourcefile todestfile wheredestmust not already exist in the directory. It is permitted for this operation to not be truly atomic, for example bothsourceanddestcan be visible temporarily inDirectory.listAll(). However, the implementation of this method must ensure the content ofdestappears as the entiresourceatomically. So oncedestis visible for readers, the entire content of previoussourceis visible. This method is used by IndexWriter to publish commits.
-
syncMetaData
public void syncMetaData() throws java.io.IOExceptionDescription copied from class:DirectoryEnsures that directory metadata, such as recent file renames, are moved to stable storage.- Specified by:
syncMetaDatain classDirectory- Throws:
java.io.IOException- See Also:
Directory.sync(Collection)
-
close
public void close() throws java.io.IOExceptionDescription copied from class:DirectoryCloses the directory.
-
getDirectory
public java.nio.file.Path getDirectory()
- Returns:
- the underlying filesystem directory
-
toString
public java.lang.String toString()
- Overrides:
toStringin classBaseDirectory
-
fsync
protected void fsync(java.lang.String name) throws java.io.IOException- Throws:
java.io.IOException
-
deleteFile
public void deleteFile(java.lang.String name) throws java.io.IOExceptionDescription copied from class:DirectoryRemoves an existing file in the directory. This method must throw eitherNoSuchFileExceptionorFileNotFoundExceptionifnamepoints to a non-existing file.- Specified by:
deleteFilein classDirectory- Parameters:
name- the name of an existing file.- Throws:
java.io.IOException- in case of I/O error
-
deletePendingFiles
public void deletePendingFiles() throws java.io.IOExceptionTry to delete any pending files that we had previously tried to delete but failed because we are on Windows and the files were still held open.- Throws:
java.io.IOException
-
maybeDeletePendingFiles
private void maybeDeletePendingFiles() throws java.io.IOException- Throws:
java.io.IOException
-
privateDeleteFile
private void privateDeleteFile(java.lang.String name, boolean isPendingDelete) throws java.io.IOException- Throws:
java.io.IOException
-
getPendingDeletions
public java.util.Set<java.lang.String> getPendingDeletions() throws java.io.IOExceptionDescription copied from class:DirectoryReturns a set of files currently pending deletion in this directory.- Specified by:
getPendingDeletionsin classDirectory- Throws:
java.io.IOException
-
-