[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.&lt;index&gt;.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