[hibernate-commits] Hibernate SVN: r15156 - in search/trunk: src/java/org/hibernate/search/backend and 3 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon Sep 8 10:07:27 EDT 2008


Author: epbernard
Date: 2008-09-08 10:07:27 -0400 (Mon, 08 Sep 2008)
New Revision: 15156

Added:
   search/trunk/src/test/org/hibernate/search/test/reader/SharedBufferedReaderPerfTest.java
Modified:
   search/trunk/doc/reference/en/modules/query.xml
   search/trunk/src/java/org/hibernate/search/backend/OptimizeLuceneWork.java
   search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java
   search/trunk/src/java/org/hibernate/search/reader/NotSharedReaderProvider.java
   search/trunk/src/java/org/hibernate/search/reader/ReaderProvider.java
   search/trunk/src/java/org/hibernate/search/reader/SharedReaderProvider.java
   search/trunk/src/java/org/hibernate/search/reader/SharingBufferReaderProvider.java
   search/trunk/src/test/org/hibernate/search/test/reader/ReaderPerfTestCase.java
Log:
HSEARCH-235 add ReaderProvider.destroy() called during SearchFactory.close()

Modified: search/trunk/doc/reference/en/modules/query.xml
===================================================================
--- search/trunk/doc/reference/en/modules/query.xml	2008-09-05 15:26:25 UTC (rev 15155)
+++ search/trunk/doc/reference/en/modules/query.xml	2008-09-08 14:07:27 UTC (rev 15156)
@@ -606,7 +606,7 @@
     <literal>hibernate.search.filter.cache_strategy</literal>.</para>
 
     <para>The described filter cache mechanism should not be confused with
-    caching the actual filter results. In Lucene it is common practise to wrap
+    caching the actual filter results. In Lucene it is common practice to wrap
     filters using the <classname>IndexReader</classname> around a
     <classname>CachingWrapperFilter.</classname> The wrapper will cache the
     <classname>BitSet</classname> returned from the

Modified: search/trunk/src/java/org/hibernate/search/backend/OptimizeLuceneWork.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/backend/OptimizeLuceneWork.java	2008-09-05 15:26:25 UTC (rev 15155)
+++ search/trunk/src/java/org/hibernate/search/backend/OptimizeLuceneWork.java	2008-09-08 14:07:27 UTC (rev 15156)
@@ -4,6 +4,10 @@
 import java.io.Serializable;
 
 /**
+ * A unit of work triggering an optimize operation
+ * This work does not propagate to a cluster: it should be filtered before being sent to
+ * the network
+ *
  * @author Andrew Hahn
  * @author Emmanuel Bernard
  */

Modified: search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java	2008-09-05 15:26:25 UTC (rev 15155)
+++ search/trunk/src/java/org/hibernate/search/impl/SearchFactoryImpl.java	2008-09-08 14:07:27 UTC (rev 15156)
@@ -147,6 +147,14 @@
 			catch (Exception e) {
 				log.error( "Worker raises an exception on close()", e );
 			}
+
+			try {
+				readerProvider.destroy();
+			}
+			catch (Exception e) {
+				log.error( "ReaderProvider raises an exception on destroy()", e );
+			}
+
 			//TODO move to DirectoryProviderFactory for cleaner
 			for (DirectoryProvider dp : getDirectoryProviders() ) {
 				try {

Modified: search/trunk/src/java/org/hibernate/search/reader/NotSharedReaderProvider.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/reader/NotSharedReaderProvider.java	2008-09-05 15:26:25 UTC (rev 15155)
+++ search/trunk/src/java/org/hibernate/search/reader/NotSharedReaderProvider.java	2008-09-08 14:07:27 UTC (rev 15156)
@@ -47,4 +47,7 @@
 
 	public void initialize(Properties props, SearchFactoryImplementor searchFactoryImplementor) {
 	}
+
+	public void destroy() {
+	}
 }

Modified: search/trunk/src/java/org/hibernate/search/reader/ReaderProvider.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/reader/ReaderProvider.java	2008-09-05 15:26:25 UTC (rev 15155)
+++ search/trunk/src/java/org/hibernate/search/reader/ReaderProvider.java	2008-09-08 14:07:27 UTC (rev 15156)
@@ -30,5 +30,14 @@
 	 */
 	void closeReader(IndexReader reader);
 
+	/**
+	 * inialize the reader provider before its use
+	 */
 	void initialize(Properties props, SearchFactoryImplementor searchFactoryImplementor);
+
+	/**
+	 * called when a SearchFactory is destroyed. This method typically releases resources
+	 * This method is guaranteed to be executed after readers are released by queries (assuming no user error). 
+	 */
+	void destroy();
 }

Modified: search/trunk/src/java/org/hibernate/search/reader/SharedReaderProvider.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/reader/SharedReaderProvider.java	2008-09-05 15:26:25 UTC (rev 15155)
+++ search/trunk/src/java/org/hibernate/search/reader/SharedReaderProvider.java	2008-09-08 14:07:27 UTC (rev 15156)
@@ -40,7 +40,7 @@
 	 */
 	private Map<DirectoryProvider, Lock> perDirectoryProviderManipulationLocks;
 	/**
-	 * Contain the active (ie non obsolete IndexReader for a given Directory
+	 * Contains the active (ie non obsolete IndexReader for a given Directory
 	 * There may be no entry (warm up)
 	 * <p/>
 	 * protected by semaphoreIndexReaderLock
@@ -217,67 +217,76 @@
 		}
 
 		for (IndexReader subReader : readers) {
-			ReaderData readerData;
-			//TODO can we avoid that lock?
+			closeInternalReader( trace, subReader, false );
+		}
+	}
+
+	private void closeInternalReader(boolean trace, IndexReader subReader, boolean finalClose) {
+		ReaderData readerData;
+		//TODO can we avoid that lock?
+		semaphoreIndexReaderLock.lock();
+		try {
+			readerData = searchIndexReaderSemaphores.get( subReader );
+		}
+		finally {
+			semaphoreIndexReaderLock.unlock();
+		}
+
+		if ( readerData == null ) {
+			log.error( "Trying to close a Lucene IndexReader not present: {}", subReader.directory() );
+			//TODO should we try to close?
+			return;
+		}
+
+		//acquire the locks in the same order as everywhere else
+		Lock directoryProviderLock = perDirectoryProviderManipulationLocks.get( readerData.provider );
+		boolean closeReader = false;
+		directoryProviderLock.lock();
+		try {
+			boolean isActive;
+			isActive = activeSearchIndexReaders.get( readerData.provider ) == subReader;
+			if ( trace ) log.trace( "Indexreader not active: {}", subReader );
 			semaphoreIndexReaderLock.lock();
 			try {
 				readerData = searchIndexReaderSemaphores.get( subReader );
-			}
-			finally {
-				semaphoreIndexReaderLock.unlock();
-			}
+				if ( readerData == null ) {
+					log.error( "Trying to close a Lucene IndexReader not present: {}" + subReader.directory() );
+					//TODO should we try to close?
+					return;
+				}
 
-			if ( readerData == null ) {
-				log.error( "Trying to close a Lucene IndexReader not present: {}", subReader.directory() );
-				//TODO should we try to close?
-				continue;
-			}
-
-			//acquire the locks in the same order as everywhere else
-			Lock directoryProviderLock = perDirectoryProviderManipulationLocks.get( readerData.provider );
-			boolean closeReader = false;
-			directoryProviderLock.lock();
-			try {
-				boolean isActive;
-				isActive = activeSearchIndexReaders.get( readerData.provider ) == subReader;
-				if ( trace ) log.trace( "Indexreader not active: {}", subReader );
-				semaphoreIndexReaderLock.lock();
-				try {
-					readerData = searchIndexReaderSemaphores.get( subReader );
-					if ( readerData == null ) {
-						log.error( "Trying to close a Lucene IndexReader not present: {}" + subReader.directory() );
-						//TODO should we try to close?
-						continue;
-					}
+				//final close, the semaphore should be at 0 already
+				if (!finalClose) {
 					readerData.semaphore--;
 					if ( trace ) log.trace( "Semaphore decreased to: {} for {}", readerData.semaphore, subReader );
-					if ( readerData.semaphore < 0 )
-						log.error( "Semaphore negative: {}", subReader.directory() );
-					if ( ( !isActive ) && readerData.semaphore == 0 ) {
-						searchIndexReaderSemaphores.remove( subReader );
-						closeReader = true;
-					}
-					else {
-						closeReader = false;
-					}
 				}
-				finally {
-					semaphoreIndexReaderLock.unlock();
+
+				if ( readerData.semaphore < 0 )
+					log.error( "Semaphore negative: {}", subReader.directory() );
+				if ( ( !isActive ) && readerData.semaphore == 0 ) {
+					searchIndexReaderSemaphores.remove( subReader );
+					closeReader = true;
 				}
+				else {
+					closeReader = false;
+				}
 			}
 			finally {
-				directoryProviderLock.unlock();
+				semaphoreIndexReaderLock.unlock();
 			}
+		}
+		finally {
+			directoryProviderLock.unlock();
+		}
 
-			if ( closeReader ) {
-				if ( trace ) log.trace( "Closing IndexReader: {}", subReader );
-				try {
-					subReader.close();
-				}
-				catch (IOException e) {
-					log.warn( "Unable to close Lucene IndexReader", e );
-				}
+		if ( closeReader ) {
+			if ( trace ) log.trace( "Closing IndexReader: {}", subReader );
+			try {
+				subReader.close();
 			}
+			catch ( IOException e) {
+				log.warn( "Unable to close Lucene IndexReader", e );
+			}
 		}
 	}
 
@@ -290,6 +299,29 @@
 		perDirectoryProviderManipulationLocks = Collections.unmodifiableMap( perDirectoryProviderManipulationLocks );
 	}
 
+	public void destroy() {
+		boolean trace = log.isTraceEnabled();
+		IndexReader[] readers;
+		semaphoreIndexReaderLock.lock();
+		try {
+			//release active readers
+			activeSearchIndexReaders.clear();
+			readers = searchIndexReaderSemaphores.keySet().toArray( new IndexReader[searchIndexReaderSemaphores.size()] );
+		}
+		finally {
+			semaphoreIndexReaderLock.unlock();
+		}
+
+		for (IndexReader reader : readers) {
+			closeInternalReader( trace, reader, true );
+		}
+
+		if ( searchIndexReaderSemaphores.size() != 0 ) {
+			log.warn( "ReaderProvider contains readers not properly closed at destroy time" );
+		}
+
+	}
+
 	private static class ReaderData {
 
 		public ReaderData(int semaphore, DirectoryProvider provider) {

Modified: search/trunk/src/java/org/hibernate/search/reader/SharingBufferReaderProvider.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/reader/SharingBufferReaderProvider.java	2008-09-05 15:26:25 UTC (rev 15155)
+++ search/trunk/src/java/org/hibernate/search/reader/SharingBufferReaderProvider.java	2008-09-08 14:07:27 UTC (rev 15156)
@@ -76,6 +76,16 @@
 		currentReaders = Collections.unmodifiableMap( map );
 	}
 
+	public void destroy() {
+		IndexReader[] readers = allReaders.keySet().toArray( new IndexReader[allReaders.size()] );
+		for (IndexReader reader : readers) {
+			ReaderUsagePair usage =  allReaders.get( reader );
+			usage.close();
+		}
+
+		if ( allReaders.size() != 0 ) log.warn( "ReaderProvider contains readers not properly closed at destroy time" );
+	}
+
 	public IndexReader openReader(DirectoryProvider... directoryProviders) {
 		int length = directoryProviders.length;
 		IndexReader[] readers = new IndexReader[length];

Modified: search/trunk/src/test/org/hibernate/search/test/reader/ReaderPerfTestCase.java
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/reader/ReaderPerfTestCase.java	2008-09-05 15:26:25 UTC (rev 15155)
+++ search/trunk/src/test/org/hibernate/search/test/reader/ReaderPerfTestCase.java	2008-09-08 14:07:27 UTC (rev 15156)
@@ -50,6 +50,7 @@
 
 	protected void tearDown() throws Exception {
 		super.tearDown();
+		if ( getSessions() != null ) getSessions().close();
 		File sub = getBaseIndexDir();
 		FileHelper.delete( sub );
 	}

Copied: search/trunk/src/test/org/hibernate/search/test/reader/SharedBufferedReaderPerfTest.java (from rev 15153, search/trunk/src/test/org/hibernate/search/test/reader/SharedReaderPerfTest.java)
===================================================================
--- search/trunk/src/test/org/hibernate/search/test/reader/SharedBufferedReaderPerfTest.java	                        (rev 0)
+++ search/trunk/src/test/org/hibernate/search/test/reader/SharedBufferedReaderPerfTest.java	2008-09-08 14:07:27 UTC (rev 15156)
@@ -0,0 +1,15 @@
+//$Id$
+package org.hibernate.search.test.reader;
+
+import org.hibernate.cfg.Configuration;
+import org.hibernate.search.Environment;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class SharedBufferedReaderPerfTest extends ReaderPerfTestCase {
+	protected void configure(Configuration cfg) {
+		super.configure( cfg );
+		cfg.setProperty( Environment.READER_STRATEGY, "shared-segments" );
+	}
+}
\ No newline at end of file


Property changes on: search/trunk/src/test/org/hibernate/search/test/reader/SharedBufferedReaderPerfTest.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:mergeinfo
   + 




More information about the hibernate-commits mailing list