[hibernate-commits] Hibernate SVN: r15991 - in search/trunk: src/java/org/hibernate/search/store and 1 other directory.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Tue Feb 17 14:34:06 EST 2009
Author: sannegrinovero
Date: 2009-02-17 14:34:06 -0500 (Tue, 17 Feb 2009)
New Revision: 15991
Modified:
search/trunk/doc/reference/en/modules/configuration.xml
search/trunk/src/java/org/hibernate/search/store/DirectoryProviderHelper.java
search/trunk/src/java/org/hibernate/search/store/FSDirectoryProvider.java
search/trunk/src/java/org/hibernate/search/store/FSMasterDirectoryProvider.java
search/trunk/src/java/org/hibernate/search/store/FSSlaveDirectoryProvider.java
Log:
HSEARCH-284: Be able to configure a LockFactory
Modified: search/trunk/doc/reference/en/modules/configuration.xml
===================================================================
--- search/trunk/doc/reference/en/modules/configuration.xml 2009-02-17 17:27:48 UTC (rev 15990)
+++ search/trunk/doc/reference/en/modules/configuration.xml 2009-02-17 19:34:06 UTC (rev 15991)
@@ -58,6 +58,16 @@
</thead>
<tbody>
+ <row>
+ <entry>org.hibernate.search.store.RAMDirectoryProvider</entry>
+
+ <entry>Memory based directory, the directory will be uniquely
+ identified (in the same deployment unit) by the
+ <literal>@Indexed.index</literal> element</entry>
+
+ <entry>none</entry>
+ </row>
+
<row>
<entry>org.hibernate.search.store.FSDirectoryProvider</entry>
@@ -66,7 +76,9 @@
<entry><para><literal>indexBase</literal> : Base
directory</para><para><literal>indexName</literal>: override
- @Indexed.index (useful for sharded indexes)</para></entry>
+ @Indexed.index (useful for sharded indexes)</para><para><literal>
+ locking_strategy</literal> : optional, see <xref linkend="search-configuration-directory-lockfactories" />
+ </para></entry>
</row>
<row>
@@ -97,7 +109,9 @@
(the copy will take place every refresh seconds).</para><para>
<literal>buffer_size_on_copy</literal>: The amount of MegaBytes to
move in a single low level copy instruction; defaults to
- 16MB.</para></entry>
+ 16MB.</para><para><literal>
+ locking_strategy</literal> : optional, see <xref linkend="search-configuration-directory-lockfactories" />
+ </para></entry>
</row>
<row>
@@ -128,18 +142,11 @@
(the copy will take place every refresh seconds).</para><para>
<literal>buffer_size_on_copy</literal>: The amount of MegaBytes to
move in a single low level copy instruction; defaults to
- 16MB.</para></entry>
+ 16MB.</para><para><literal>
+ locking_strategy</literal> : optional, see <xref linkend="search-configuration-directory-lockfactories" />
+ </para></entry>
</row>
- <row>
- <entry>org.hibernate.search.store.RAMDirectoryProvider</entry>
-
- <entry>Memory based directory, the directory will be uniquely
- identified (in the same deployment unit) by the
- <literal>@Indexed.index</literal> element</entry>
-
- <entry>none</entry>
- </row>
</tbody>
</tgroup>
</table>
@@ -843,4 +850,78 @@
</tgroup>
</table>
</section>
+
+ <section id="search-configuration-directory-lockfactories" revision="1">
+ <title>LockFactory configuration</title>
+ <para>Lucene Directories have default locking strategies which work well for most cases,
+ but it's possible to specify for each index managed by Hibernate Search which LockingFactory
+ you want to use.</para><para>Some of these locking strategies require a filesystem level lock and may be used
+ even on RAM based indexes, but this is not recommended and of no practical use.</para>
+ <para>To select a locking factory, set the <literal>hibernate.search.<index>.locking_strategy</literal> option to
+ one of <literal>simple</literal>, <literal>native</literal>, <literal>single</literal>
+ or <literal>none</literal>.
+
+ <table id="search-configuration-directory-lockfactories-table">
+ <title>List of available LockFactory implementations</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry align="center">name</entry>
+ <entry align="center">Class</entry>
+ <entry align="center">Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>simple</entry>
+ <entry>org.apache.lucene.store.SimpleFSLockFactory</entry>
+ <entry>
+ <para>Safe implementation based on Java's File API, it marks the usage of the index by creating a marker file.</para>
+ <para>If for some reason you had to kill your application, you will need to remove this file before restarting it.</para>
+ <para>This is the default implementation for <literal>FSDirectoryProvider</literal>,<literal>FSMasterDirectoryProvider</literal> and
+ <literal>FSSlaveDirectoryProvider</literal>.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>native</entry>
+ <entry>org.apache.lucene.store.NativeFSLockFactory</entry>
+ <entry>
+ <para>As does <literal>simple</literal> this also marks the usage of the index by creating a marker file, but this one
+ is using native OS file locks so that even if your application crashes the locks will be cleaned up.</para>
+ <para>This implementation has known problems on NFS.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>single</entry>
+ <entry>org.apache.lucene.store.SingleInstanceLockFactory</entry>
+ <entry>
+ <para>This LockFactory doesn't use a file marker but is a Java object lock held in memory; therefore
+ it's possible to use it only when you are sure the index is not going to be shared by any other process.</para>
+ <para>This is the default implementation for <literal>RAMDirectoryProvider</literal>.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>none</entry>
+ <entry>org.apache.lucene.store.NoLockFactory</entry>
+ <entry>
+ <para>All changes to this index are not coordinated by any lock; test your application carefully
+ and make sure you know what it means.</para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </para>Configuration example:
+ <programlisting>hibernate.search.default simple
+hibernate.search.Animals native</programlisting>
+ <para>
+ </para>
+
+ <para>If you need more flexibility it is possible to use your own LockFactory when implementing a custom DirectoryProvider.</para>
+
+ </section>
+
</chapter>
Modified: search/trunk/src/java/org/hibernate/search/store/DirectoryProviderHelper.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/store/DirectoryProviderHelper.java 2009-02-17 17:27:48 UTC (rev 15990)
+++ search/trunk/src/java/org/hibernate/search/store/DirectoryProviderHelper.java 2009-02-17 19:34:06 UTC (rev 15991)
@@ -9,6 +9,11 @@
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.FSDirectory;
+import org.apache.lucene.store.LockFactory;
+import org.apache.lucene.store.NativeFSLockFactory;
+import org.apache.lucene.store.NoLockFactory;
+import org.apache.lucene.store.SimpleFSLockFactory;
+import org.apache.lucene.store.SingleInstanceLockFactory;
import org.slf4j.Logger;
import org.hibernate.annotations.common.util.StringHelper;
@@ -68,13 +73,15 @@
}
/**
- * Creates an FSDirectory in provided directory if not already existing.
+ * Creates an FSDirectory in provided directory and initializes
+ * an index if not already existing.
* @param indexDir The directory where to write a new index
* @return the created FSDirectory
* @throws IOException
*/
- public static FSDirectory createFSIndex(File indexDir) throws IOException {
- FSDirectory fsDirectory = FSDirectory.getDirectory( indexDir );
+ public static FSDirectory createFSIndex(File indexDir, Properties dirConfiguration) throws IOException {
+ LockFactory lockFactory = createLockFactory(indexDir, dirConfiguration);
+ FSDirectory fsDirectory = FSDirectory.getDirectory( indexDir, lockFactory );
if ( ! IndexReader.indexExists( fsDirectory ) ) {
log.debug( "Initialize index: '{}'", indexDir.getAbsolutePath() );
IndexWriter.MaxFieldLength fieldLength = new IndexWriter.MaxFieldLength( IndexWriter.DEFAULT_MAX_FIELD_LENGTH );
@@ -83,6 +90,39 @@
}
return fsDirectory;
}
+
+ /**
+ * Creates a LockFactory as selected in the configuration for the
+ * DirectoryProvider.
+ * The SimpleFSLockFactory and NativeFSLockFactory need a File to know
+ * were to stock the filesystem based locks; other implementations
+ * ignore this parameter.
+ * @param indexDir the directory to use to store locks, if needed by implementation
+ * @param dirConfiguration the configuration of current DirectoryProvider
+ * @return the LockFactory as configured, or a SimpleFSLockFactory
+ * in case of configuration errors or as a default.
+ * @throws IOException
+ */
+ public static LockFactory createLockFactory(File indexDir, Properties dirConfiguration) throws IOException {
+ String lockFactoryName = dirConfiguration.getProperty( "locking_strategy", "simple" );
+ if ( "simple".equals( lockFactoryName ) ) {
+ return new SimpleFSLockFactory( indexDir );
+ }
+ else if ( "native".equals( lockFactoryName ) ) {
+ return new NativeFSLockFactory( indexDir );
+ }
+ else if ( "single".equals( lockFactoryName ) ) {
+ return new SingleInstanceLockFactory();
+ }
+ else if ( "none".equals( lockFactoryName ) ) {
+ return new NoLockFactory();
+ }
+ else {
+ log.warn( "Invalid configuration setting for option locking_strategy \"{}\"; option ignored!",
+ lockFactoryName );
+ return new SimpleFSLockFactory( indexDir );
+ }
+ }
/**
* Verify the index directory exists and is writable,
Modified: search/trunk/src/java/org/hibernate/search/store/FSDirectoryProvider.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/store/FSDirectoryProvider.java 2009-02-17 17:27:48 UTC (rev 15990)
+++ search/trunk/src/java/org/hibernate/search/store/FSDirectoryProvider.java 2009-02-17 19:34:06 UTC (rev 15991)
@@ -41,7 +41,7 @@
try {
indexName = indexDir.getCanonicalPath();
//this is cheap so it's not done in start()
- directory = DirectoryProviderHelper.createFSIndex( indexDir );
+ directory = DirectoryProviderHelper.createFSIndex( indexDir, properties );
}
catch (IOException e) {
throw new SearchException( "Unable to initialize index: " + directoryProviderName, e );
Modified: search/trunk/src/java/org/hibernate/search/store/FSMasterDirectoryProvider.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/store/FSMasterDirectoryProvider.java 2009-02-17 17:27:48 UTC (rev 15990)
+++ search/trunk/src/java/org/hibernate/search/store/FSMasterDirectoryProvider.java 2009-02-17 19:34:06 UTC (rev 15991)
@@ -60,7 +60,7 @@
log.debug( "Index directory: {}", indexDir.getPath() );
try {
indexName = indexDir.getCanonicalPath();
- directory = DirectoryProviderHelper.createFSIndex( indexDir );
+ directory = DirectoryProviderHelper.createFSIndex( indexDir, properties );
}
catch (IOException e) {
throw new SearchException( "Unable to initialize index: " + directoryProviderName, e );
Modified: search/trunk/src/java/org/hibernate/search/store/FSSlaveDirectoryProvider.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/store/FSSlaveDirectoryProvider.java 2009-02-17 17:27:48 UTC (rev 15990)
+++ search/trunk/src/java/org/hibernate/search/store/FSSlaveDirectoryProvider.java 2009-02-17 19:34:06 UTC (rev 15991)
@@ -75,8 +75,8 @@
int readCurrentState = current; //Unneeded value, but ensure visibility of state protected by memory barrier
int currentToBe = 0;
try {
- directory1 = DirectoryProviderHelper.createFSIndex( new File( indexDir, "1" ) );
- directory2 = DirectoryProviderHelper.createFSIndex( new File( indexDir, "2" ) );
+ directory1 = DirectoryProviderHelper.createFSIndex( new File( indexDir, "1" ), properties );
+ directory2 = DirectoryProviderHelper.createFSIndex( new File( indexDir, "2" ), properties );
File currentMarker = new File( indexDir, "current1" );
File current2Marker = new File( indexDir, "current2" );
if ( currentMarker.exists() ) {
More information about the hibernate-commits
mailing list