Hibernate SVN: r16581 - search/trunk/src/main/java/org/hibernate/search/store.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2009-05-17 22:06:36 -0400 (Sun, 17 May 2009)
New Revision: 16581
Modified:
search/trunk/src/main/java/org/hibernate/search/store/DirectoryProviderHelper.java
Log:
a fix for HSEARCH-284
Modified: search/trunk/src/main/java/org/hibernate/search/store/DirectoryProviderHelper.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/store/DirectoryProviderHelper.java 2009-05-18 01:59:10 UTC (rev 16580)
+++ search/trunk/src/main/java/org/hibernate/search/store/DirectoryProviderHelper.java 2009-05-18 02:06:36 UTC (rev 16581)
@@ -82,7 +82,10 @@
*/
public static FSDirectory createFSIndex(File indexDir, Properties dirConfiguration) throws IOException {
LockFactory lockFactory = createLockFactory(indexDir, dirConfiguration);
- FSDirectory fsDirectory = FSDirectory.getDirectory( indexDir, lockFactory );
+ FSDirectory fsDirectory = FSDirectory.getDirectory( indexDir, null );
+ // must use the setter (instead of using the constructor) to set the lockFactory, or Lucene will
+ // throw an exception if it's different than a previous setting.
+ fsDirectory.setLockFactory( lockFactory );
if ( ! IndexReader.indexExists( fsDirectory ) ) {
log.debug( "Initialize index: '{}'", indexDir.getAbsolutePath() );
IndexWriter.MaxFieldLength fieldLength = new IndexWriter.MaxFieldLength( IndexWriter.DEFAULT_MAX_FIELD_LENGTH );
15 years, 6 months
Hibernate SVN: r16580 - in search/trunk/src: main/java/org/hibernate/search/batchindexing and 6 other directories.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2009-05-17 21:59:10 -0400 (Sun, 17 May 2009)
New Revision: 16580
Added:
search/trunk/src/main/java/org/hibernate/search/Indexer.java
search/trunk/src/main/java/org/hibernate/search/batchindexing/
search/trunk/src/main/java/org/hibernate/search/batchindexing/BatchIndexingWorkspace.java
search/trunk/src/main/java/org/hibernate/search/batchindexing/EntityConsumerLuceneworkProducer.java
search/trunk/src/main/java/org/hibernate/search/batchindexing/Executors.java
search/trunk/src/main/java/org/hibernate/search/batchindexing/IdentifierConsumerEntityProducer.java
search/trunk/src/main/java/org/hibernate/search/batchindexing/IdentifierProducer.java
search/trunk/src/main/java/org/hibernate/search/batchindexing/IndexWritingJob.java
search/trunk/src/main/java/org/hibernate/search/batchindexing/IndexerProgressMonitor.java
search/trunk/src/main/java/org/hibernate/search/batchindexing/ProducerConsumerQueue.java
search/trunk/src/main/java/org/hibernate/search/impl/IndexerImpl.java
search/trunk/src/main/java/org/hibernate/search/impl/SimpleIndexingProgressMonitor.java
search/trunk/src/test/java/org/hibernate/search/test/batchindexing/
search/trunk/src/test/java/org/hibernate/search/test/batchindexing/AncientBook.java
search/trunk/src/test/java/org/hibernate/search/test/batchindexing/Book.java
search/trunk/src/test/java/org/hibernate/search/test/batchindexing/Dvd.java
search/trunk/src/test/java/org/hibernate/search/test/batchindexing/ModernBook.java
search/trunk/src/test/java/org/hibernate/search/test/batchindexing/SearchIndexerTest.java
Modified:
search/trunk/src/main/java/org/hibernate/search/FullTextSession.java
search/trunk/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java
search/trunk/src/main/java/org/hibernate/search/impl/FullTextSessionImpl.java
search/trunk/src/main/java/org/hibernate/search/jpa/FullTextEntityManager.java
search/trunk/src/main/java/org/hibernate/search/jpa/impl/FullTextEntityManagerImpl.java
Log:
HSEARCH-218 loading of entities in parallel sessions (multithreaded) to improve index rebuilding performance. Useless until integrated with a new ad-hoc backend.
Modified: search/trunk/src/main/java/org/hibernate/search/FullTextSession.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/FullTextSession.java 2009-05-18 01:44:29 UTC (rev 16579)
+++ search/trunk/src/main/java/org/hibernate/search/FullTextSession.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -67,4 +67,14 @@
* Flush all index changes forcing Hibernate Search to apply all changes to the index not waiting for the batch limit.
*/
public void flushToIndexes();
+
+ /**
+ * Creates an Indexer to rebuild the indexes of some
+ * or all indexed entity types.
+ * Instances cannot be reused.
+ * @param types optionally restrict the operation to selected types
+ * @return
+ */
+ public Indexer createIndexer(Class<?>... types);
+
}
Added: search/trunk/src/main/java/org/hibernate/search/Indexer.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/Indexer.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/Indexer.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -0,0 +1,88 @@
+package org.hibernate.search;
+
+import java.util.concurrent.TimeUnit;
+
+import org.hibernate.CacheMode;
+
+public interface Indexer {
+
+ /**
+ * Set the number of threads to be used to load
+ * the root entities.
+ * @param numberOfThreads
+ * @return <tt>this</tt> for method chaining
+ */
+ Indexer objectLoadingThreads(int numberOfThreads);
+
+ /**
+ * Sets the batch size used to load the root entities.
+ * @param batchSize
+ * @return <tt>this</tt> for method chaining
+ */
+ Indexer objectLoadingBatchSize(int batchSize);
+
+ /**
+ * Sets the number of threads used to load the lazy collections
+ * related to the indexed entities.
+ * @param numberOfThreads
+ * @return <tt>this</tt> for method chaining
+ */
+ Indexer documentBuilderThreads(int numberOfThreads);
+
+ //not supported yet
+ //Indexer indexWriterThreads(int numberOfThreads);
+
+ /**
+ * Sets the cache interaction mode for the data loading tasks.
+ * Defaults to <tt>CacheMode.IGNORE</tt>.
+ * @return <tt>this</tt> for method chaining
+ */
+ Indexer cacheMode(CacheMode cacheMode);
+
+ /**
+ * If index optimization has to be started at the end
+ * of the indexing process.
+ * Defaults to <tt>true</tt>.
+ * @param optimize
+ * @return <tt>this</tt> for method chaining
+ */
+ Indexer optimizeAtEnd(boolean optimize);
+
+ /**
+ * If index optimization should be run before starting,
+ * after the purgeAll. Has no effect if <tt>purgeAll</tt> is set to false.
+ * Defaults to <tt>true</tt>.
+ * @param optimize
+ * @return <tt>this</tt> for method chaining
+ */
+ Indexer optimizeAfterPurge(boolean optimize);
+
+ /**
+ * If all entities should be removed from the index before starting
+ * using purgeAll. Set it only to false if you know there are no
+ * entities in the index: otherwise search results may be duplicated.
+ * Defaults to true.
+ * @param purgeAll
+ * @return <tt>this</tt> for method chaining
+ */
+ Indexer purgeAllAtStart(boolean purgeAll);
+
+ /**
+ * Starts the indexing process in background (asynchronous).
+ * Can be called only once.
+ */
+ void start();
+
+ /**
+ * Starts the indexing process, and then block until it's finished.
+ * Can be called only once.
+ * @param timeout the maximum time to wait
+ * @param unit the time unit of the <tt>timeout</tt> argument.
+ * @return <tt>true</tt> if the process finished and <tt>false</tt>
+ * if the waiting time elapsed before the process was finished.
+ * @throws InterruptedException if the current thread is interrupted
+ * while waiting.
+ */
+ boolean startAndWait( long timeout, TimeUnit unit ) throws InterruptedException;
+
+}
Added: search/trunk/src/main/java/org/hibernate/search/batchindexing/BatchIndexingWorkspace.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/batchindexing/BatchIndexingWorkspace.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/batchindexing/BatchIndexingWorkspace.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -0,0 +1,190 @@
+package org.hibernate.search.batchindexing;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.hibernate.CacheMode;
+import org.hibernate.SessionFactory;
+import org.hibernate.search.SearchException;
+import org.hibernate.search.backend.BackendQueueProcessorFactory;
+import org.hibernate.search.backend.LuceneWork;
+import org.hibernate.search.backend.OptimizeLuceneWork;
+import org.hibernate.search.backend.PurgeAllLuceneWork;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.hibernate.search.util.LoggerFactory;
+import org.slf4j.Logger;
+
+/**
+ * This runnable will prepare a pipeline for batch indexing
+ * of entities, managing the lifecycle of several ThreadPools.
+ *
+ * @author Sanne Grinovero
+ */
+public class BatchIndexingWorkspace implements Runnable {
+
+ private static final Logger log = LoggerFactory.make();
+
+ private final SearchFactoryImplementor searchFactory;
+ private final SessionFactory sessionFactory;
+
+ //following order shows the 4 stages of an entity flowing to the index:
+ private final ThreadPoolExecutor execIdentifiersLoader;
+ private final ProducerConsumerQueue fromIdentifierListToEntities;
+ private final ThreadPoolExecutor execFirstLoader;
+ private final ProducerConsumerQueue fromEntityToAddwork;
+ private final ThreadPoolExecutor execDocBuilding;
+ private final ProducerConsumerQueue fromAddworkToIndex;
+ private final ThreadPoolExecutor execWriteIndex;
+
+ private final int objectLoadingThreadNum;
+ private final int luceneworkerBuildingThreadNum;
+ private final int indexWritingThreadNum;
+ private final Class<?> indexedType;
+
+ // status control
+ private final AtomicBoolean started = new AtomicBoolean( false );
+ private final CountDownLatch endWritersSignal; //released when we stop adding Documents to Index
+ private final CountDownLatch endAllSignal; //released when we release all locks and IndexWriter
+
+ // progress monitor
+ private final IndexerProgressMonitor monitor;
+
+ // loading options
+ private final CacheMode cacheMode;
+ private final int objectLoadingBatchSize;
+
+ private final boolean purgeAtStart;
+ private final boolean optimizeAfterPurge;
+ private final boolean optimizeAtEnd;
+
+ public BatchIndexingWorkspace(SearchFactoryImplementor searchFactoryImplementor, SessionFactory sessionFactory,
+ Class<?> entityType,
+ int objectLoadingThreads, int collectionLoadingThreads, int writerThreads,
+ CacheMode cacheMode, int objectLoadingBatchSize,
+ boolean optimizeAtEnd, boolean purgeAtStart, boolean optimizeAfterPurge, CountDownLatch endAllSignal,
+ IndexerProgressMonitor monitor) {
+
+ this.indexedType = entityType;
+ this.searchFactory = searchFactoryImplementor;
+ this.sessionFactory = sessionFactory;
+
+ //thread pool sizing:
+ this.objectLoadingThreadNum = objectLoadingThreads;
+ this.luceneworkerBuildingThreadNum = collectionLoadingThreads;//collections are loaded as needed by building the document
+// this.indexWritingThreadNum = writerThreads; //FIXME enable this line and remove the next line after solving HSEARCH-367
+ this.indexWritingThreadNum = 1;
+
+ //loading options:
+ this.cacheMode = cacheMode;
+ this.objectLoadingBatchSize = objectLoadingBatchSize;
+
+ //executors: (quite expensive constructor)
+ //execIdentifiersLoader has size 1 and is not configurable: ensures the list is consistent as produced by one transaction
+ this.execIdentifiersLoader = Executors.newFixedThreadPool( 1, "identifierloader" );
+ this.execFirstLoader = Executors.newFixedThreadPool( objectLoadingThreadNum, "entityloader" );
+ this.execDocBuilding = Executors.newFixedThreadPool( luceneworkerBuildingThreadNum, "collectionsloader" );
+ this.execWriteIndex = Executors.newFixedThreadPool( indexWritingThreadNum, "analyzers" );
+
+ //pipelining queues:
+ this.fromIdentifierListToEntities = new ProducerConsumerQueue( 1 );
+ this.fromEntityToAddwork = new ProducerConsumerQueue( objectLoadingThreadNum );
+ this.fromAddworkToIndex = new ProducerConsumerQueue( luceneworkerBuildingThreadNum );
+
+ //end signal shared with other instances:
+ this.endAllSignal = endAllSignal;
+ this.endWritersSignal = new CountDownLatch( indexWritingThreadNum );
+
+ //behaviour options:
+ this.optimizeAtEnd = optimizeAtEnd;
+ this.optimizeAfterPurge = optimizeAfterPurge;
+ this.purgeAtStart = purgeAtStart;
+
+ this.monitor = monitor;
+ }
+
+ public void run() {
+ if ( ! started.compareAndSet( false, true ) )
+ throw new IllegalStateException( "BatchIndexingWorkspace can be started only once." );
+ boolean interrupted = false;
+ try {
+ //TODO switch to batch mode in backend
+ if ( purgeAtStart ) {
+ purgeAll();
+ if ( optimizeAfterPurge ) {
+ optimize();
+ }
+ }
+
+ BackendQueueProcessorFactory backendQueueProcessorFactory = searchFactory.getBackendQueueProcessorFactory();
+ //first start the consumers, then the producers (reverse order):
+ for ( int i=0; i < indexWritingThreadNum; i++ ) {
+ //from LuceneWork to IndexWriters:
+ execWriteIndex.execute( new IndexWritingJob(
+ fromAddworkToIndex, endWritersSignal, monitor, backendQueueProcessorFactory ) );
+ }
+ for ( int i=0; i < luceneworkerBuildingThreadNum; i++ ) {
+ //from entity to LuceneWork:
+ execDocBuilding.execute( new EntityConsumerLuceneworkProducer(
+ fromEntityToAddwork, fromAddworkToIndex, monitor,
+ sessionFactory, searchFactory, cacheMode) );
+ }
+ for ( int i=0; i < objectLoadingThreadNum; i++ ) {
+ //from primary key to loaded entity:
+ execFirstLoader.execute( new IdentifierConsumerEntityProducer(
+ fromIdentifierListToEntities, fromEntityToAddwork, monitor,
+ sessionFactory, cacheMode, indexedType) );
+ }
+
+ execIdentifiersLoader.execute( new IdentifierProducer(fromIdentifierListToEntities, sessionFactory, objectLoadingBatchSize, indexedType, monitor) );
+ //shutdown all executors:
+ execIdentifiersLoader.shutdown();
+ execFirstLoader.shutdown();
+ execDocBuilding.shutdown();
+ execWriteIndex.shutdown();
+ log.debug( "helper executors are shutting down" );
+ try {
+ endWritersSignal.await(); //await all indexing is done.
+ } catch (InterruptedException e) {
+ interrupted = true;
+ throw new SearchException( "Interrupted on batch Indexing; index will be left in unknown state!", e);
+ }
+ log.debug( "index writing finished" );
+ if ( optimizeAtEnd ) {
+ log.debug( "starting optimization" );
+ optimize();
+ }
+ }
+ finally {
+ endAllSignal.countDown();
+ if ( interrupted ) {
+ //restore interruption signal:
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
+ private void optimize() {
+ Set<Class<?>> targetedClasses = searchFactory.getIndexedTypesPolymorphic( new Class[] {indexedType} );
+ List<LuceneWork> queue = new ArrayList<LuceneWork>( targetedClasses.size() );
+ for ( Class<?> clazz : targetedClasses ) {
+ queue.add( new OptimizeLuceneWork( clazz ) );
+ }
+ //TODO use the batch backend
+ searchFactory.getBackendQueueProcessorFactory().getProcessor( queue ).run();
+ }
+
+ private void purgeAll() {
+ Set<Class<?>> targetedClasses = searchFactory.getIndexedTypesPolymorphic( new Class[] {indexedType} );
+ List<LuceneWork> queue = new ArrayList<LuceneWork>( targetedClasses.size() );
+ for ( Class<?> clazz : targetedClasses ) {
+ queue.add( new PurgeAllLuceneWork( clazz ) );
+ }
+ //TODO use the batch backend
+ searchFactory.getBackendQueueProcessorFactory().getProcessor( queue ).run();
+ }
+
+}
Added: search/trunk/src/main/java/org/hibernate/search/batchindexing/EntityConsumerLuceneworkProducer.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/batchindexing/EntityConsumerLuceneworkProducer.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/batchindexing/EntityConsumerLuceneworkProducer.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -0,0 +1,111 @@
+package org.hibernate.search.batchindexing;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.hibernate.CacheMode;
+import org.hibernate.FlushMode;
+import org.hibernate.Hibernate;
+import org.hibernate.LockMode;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.search.backend.AddLuceneWork;
+import org.hibernate.search.bridge.TwoWayFieldBridge;
+import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.hibernate.search.util.LoggerFactory;
+import org.slf4j.Logger;
+
+/**
+ * Component of batch-indexing pipeline, using chained producer-consumers.
+ * This Runnable will consume entities taken one-by-one from the queue
+ * and produce for each entity an AddLuceneWork to the output queue.
+ *
+ * @author Sanne Grinovero
+ */
+public class EntityConsumerLuceneworkProducer implements Runnable {
+
+ private static final Logger log = LoggerFactory.make();
+
+ private final ProducerConsumerQueue source;
+ private final ProducerConsumerQueue destination;
+ private final SessionFactory sessionFactory;
+ private final Map<Class<?>, DocumentBuilderIndexedEntity<?>> documentBuilders;
+ private final IndexerProgressMonitor monitor;
+
+ private static final int CLEAR_PERIOD = 50;
+ private final CacheMode cacheMode;
+
+ public EntityConsumerLuceneworkProducer(
+ ProducerConsumerQueue entitySource,
+ ProducerConsumerQueue fromAddworkToIndex,
+ IndexerProgressMonitor monitor,
+ SessionFactory sessionFactory,
+ SearchFactoryImplementor searchFactory, CacheMode cacheMode) {
+ this.source = entitySource;
+ this.destination = fromAddworkToIndex;
+ this.monitor = monitor;
+ this.sessionFactory = sessionFactory;
+ this.cacheMode = cacheMode;
+ this.documentBuilders = searchFactory.getDocumentBuildersIndexedEntities();
+ }
+
+ public void run() {
+ Session session = sessionFactory.openSession();
+ session.setFlushMode( FlushMode.MANUAL );
+ session.setCacheMode( cacheMode );
+ try {
+ Transaction transaction = session.beginTransaction();
+ indexAllQueue( session );
+ transaction.commit();
+ }
+ finally {
+ session.close();
+ }
+ log.debug( "finished" );
+ }
+
+ private void indexAllQueue(Session session) {
+ try {
+ for ( int cycle=0; true; cycle++ ) {
+ Object take = source.take();
+ if ( take == null ) {
+ break;
+ }
+ else {
+ log.trace( "received an object {}", take );
+ //trick to attach the objects to session:
+ session.lock( take, LockMode.NONE );
+ index( take, session );
+ monitor.documentsBuilt( 1 );
+ session.evict( take );
+ if ( cycle == CLEAR_PERIOD ) {
+ cycle = 0;
+ session.clear();
+ }
+ }
+ }
+ }
+ catch (InterruptedException e) {
+ // just quit
+ }
+ finally {
+ destination.producerStopping();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void index( Object entity, Session session ) throws InterruptedException {
+ Serializable id = session.getIdentifier( entity );
+ Class clazz = Hibernate.getClass( entity );
+ DocumentBuilderIndexedEntity docBuilder = documentBuilders.get( clazz );
+ TwoWayFieldBridge idBridge = docBuilder.getIdBridge();
+ String idInString = idBridge.objectToString( id );
+ //depending on the complexity of the object graph going to be indexed it's possible
+ //that we hit the database several times during work construction.
+ AddLuceneWork addWork = docBuilder.createAddWork( clazz, entity, id, idInString, true );
+ destination.put( addWork );
+ }
+
+}
Added: search/trunk/src/main/java/org/hibernate/search/batchindexing/Executors.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/batchindexing/Executors.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/batchindexing/Executors.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -0,0 +1,59 @@
+package org.hibernate.search.batchindexing;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Helper class to create threads;
+ * these threads are grouped and named to be readily identified in a profiler.
+ *
+ * @author Sanne Grinovero
+ */
+public class Executors {
+
+ private static final String THREAD_GROUP_PREFIX = "Hibernate Search indexer: ";
+
+ /**
+ * Creates a new fixed size ThreadPoolExecutor
+ * @param threads
+ * @param groupname
+ * @return
+ */
+ public static ThreadPoolExecutor newFixedThreadPool(int threads, String groupname) {
+ return new ThreadPoolExecutor(
+ threads,
+ threads,
+ 0L, TimeUnit.MILLISECONDS,
+ new LinkedBlockingQueue<Runnable>(),
+ new SearchThreadFactory( groupname ) );
+ }
+
+ /**
+ * The thread factory, used to customize thread names
+ */
+ private static class SearchThreadFactory implements ThreadFactory {
+
+ final ThreadGroup group;
+ final AtomicInteger threadNumber = new AtomicInteger( 1 );
+ final String namePrefix;
+
+ SearchThreadFactory(String groupname) {
+ SecurityManager s = System.getSecurityManager();
+ group = (s != null)? s.getThreadGroup() :
+ Thread.currentThread().getThreadGroup();
+ namePrefix = THREAD_GROUP_PREFIX + groupname + "-";
+ }
+
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(group, r,
+ namePrefix + threadNumber.getAndIncrement(),
+ 0);
+ return t;
+ }
+
+ }
+
+}
Added: search/trunk/src/main/java/org/hibernate/search/batchindexing/IdentifierConsumerEntityProducer.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/batchindexing/IdentifierConsumerEntityProducer.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/batchindexing/IdentifierConsumerEntityProducer.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -0,0 +1,112 @@
+package org.hibernate.search.batchindexing;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.hibernate.CacheMode;
+import org.hibernate.Criteria;
+import org.hibernate.FlushMode;
+import org.hibernate.LockMode;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Restrictions;
+import org.hibernate.search.util.LoggerFactory;
+import org.slf4j.Logger;
+
+/**
+ * This Runnable is consuming entity identifiers and
+ * producing loaded detached entities for the next queue.
+ * It will finish when the queue it's consuming from will
+ * signal there are no more identifiers.
+ *
+ * @author Sanne Grinovero
+ */
+public class IdentifierConsumerEntityProducer implements Runnable {
+
+ private static final Logger log = LoggerFactory.make();
+
+ private final ProducerConsumerQueue source;
+ private final ProducerConsumerQueue destination;
+ private final SessionFactory sessionFactory;
+ private final CacheMode cacheMode;
+ private final Class<?> type;
+ private final IndexerProgressMonitor monitor;
+
+ public IdentifierConsumerEntityProducer(
+ ProducerConsumerQueue fromIdentifierListToEntities,
+ ProducerConsumerQueue fromEntityToAddwork,
+ IndexerProgressMonitor monitor,
+ SessionFactory sessionFactory,
+ CacheMode cacheMode, Class<?> type) {
+ this.source = fromIdentifierListToEntities;
+ this.destination = fromEntityToAddwork;
+ this.monitor = monitor;
+ this.sessionFactory = sessionFactory;
+ this.cacheMode = cacheMode;
+ this.type = type;
+ log.trace( "created" );
+ }
+
+ public void run() {
+ log.trace( "started" );
+ Session session = sessionFactory.openSession();
+ session.setFlushMode( FlushMode.MANUAL );
+ session.setCacheMode( cacheMode );
+ try {
+ Transaction transaction = session.beginTransaction();
+ loadAllFromQueue( session );
+ transaction.commit();
+ }
+ finally {
+ session.close();
+ }
+ log.trace( "finished" );
+ }
+
+ private void loadAllFromQueue(Session session) {
+ try {
+ Object take;
+ do {
+ take = source.take();
+ if ( take != null ) {
+ List<Serializable> listIds = (List<Serializable>) take;
+ log.trace( "received list of ids {}", listIds );
+ loadList( listIds, session );
+ }
+ }
+ while ( take != null );
+ }
+ catch (InterruptedException e) {
+ // just quit
+ }
+ finally {
+ destination.producerStopping();
+ }
+ }
+
+ /**
+ * Loads a list of entities of defined type using their identifiers.
+ * The loaded objects are then pushed to the next queue one by one.
+ * @param listIds the list of entity identifiers (of type
+ * @param session the session to be used
+ * @throws InterruptedException
+ */
+ private void loadList(List<Serializable> listIds, Session session) throws InterruptedException {
+ //TODO investigate if I should use ObjectLoaderHelper.initializeObjects instead
+ Criteria criteria = session
+ .createCriteria( type )
+ .setCacheMode( cacheMode )
+ .setLockMode( LockMode.NONE )
+ .setCacheable( false )
+ .setFlushMode( FlushMode.MANUAL )
+ .add( Restrictions.in( "id", listIds ) );
+ List<?> list = criteria.list();
+ monitor.entitiesLoaded( list.size() );
+ session.clear();
+ for ( Object obj : list ) {
+ destination.put( obj );
+ }
+ }
+
+}
Added: search/trunk/src/main/java/org/hibernate/search/batchindexing/IdentifierProducer.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/batchindexing/IdentifierProducer.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/batchindexing/IdentifierProducer.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -0,0 +1,125 @@
+package org.hibernate.search.batchindexing;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hibernate.Criteria;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
+import org.hibernate.SessionFactory;
+import org.hibernate.StatelessSession;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Projections;
+import org.hibernate.search.util.LoggerFactory;
+import org.slf4j.Logger;
+
+/**
+ * This Runnable is going to feed the indexing queue
+ * with the identifiers of all the entities going to be indexed.
+ * This step in the indexing process is not parallel (should be
+ * done by one thread per type) so that a single transaction is used
+ * to define the group of entities to be indexed.
+ * Produced identifiers are put in the destination queue grouped in List
+ * instances: the reason for this is to load them in batches
+ * in the next step and reduce contention on the queue.
+ *
+ * @author Sanne Grinovero
+ */
+public class IdentifierProducer implements Runnable {
+
+ private static final Logger log = LoggerFactory.make();
+
+ private final ProducerConsumerQueue destination;
+ private final SessionFactory sessionFactory;
+ private final int batchSize;
+ private final Class<?> indexedType;
+ private final IndexerProgressMonitor monitor;
+
+ /**
+ * @param fromIdentifierListToEntities the target queue where the produced identifiers are sent to
+ * @param sessionFactory the Hibernate SessionFactory to use to load entities
+ * @param objectLoadingBatchSize affects mostly the next consumer: IdentifierConsumerEntityProducer
+ * @param indexedType the entity type to be loaded
+ * @param monitor to monitor indexing progress
+ */
+ public IdentifierProducer(
+ ProducerConsumerQueue fromIdentifierListToEntities,
+ SessionFactory sessionFactory,
+ int objectLoadingBatchSize,
+ Class<?> indexedType, IndexerProgressMonitor monitor) {
+ this.destination = fromIdentifierListToEntities;
+ this.sessionFactory = sessionFactory;
+ this.batchSize = objectLoadingBatchSize;
+ this.indexedType = indexedType;
+ this.monitor = monitor;
+ log.trace( "created" );
+ }
+
+ public void run() {
+ log.trace( "started" );
+ try {
+ inTransactionWrapper();
+ }
+ finally{
+ destination.producerStopping();
+ }
+ log.trace( "finished" );
+ }
+
+ private void inTransactionWrapper() {
+ StatelessSession session = sessionFactory.openStatelessSession();
+ try {
+ Transaction transaction = session.beginTransaction();
+ loadAllIdentifiers( session );
+ transaction.commit();
+ } catch (InterruptedException e) {
+ // just quit
+ }
+ finally {
+ session.close();
+ }
+ }
+
+ private void loadAllIdentifiers(final StatelessSession session) throws InterruptedException {
+ Integer count = (Integer) session
+ .createCriteria( indexedType )
+ .setProjection( Projections.count( "id" ) )
+ .setCacheable( false )
+ .uniqueResult();
+
+ log.debug( "going to fetch {} primary keys", count);
+ monitor.addToTotalCount( count );
+
+ Criteria criteria = session
+ .createCriteria( indexedType )
+ .setProjection( Projections.id() )
+ .setCacheable( false )
+ .setFetchSize( 100 );
+
+ ScrollableResults results = criteria.scroll( ScrollMode.FORWARD_ONLY );
+ ArrayList<Serializable> destinationList = new ArrayList<Serializable>( batchSize );
+ try {
+ while ( results.next() ) {
+ Serializable id = (Serializable) results.get( 0 );
+ destinationList.add( id );
+ if ( destinationList.size() == batchSize ) {
+ enqueueList( destinationList );
+ destinationList = new ArrayList<Serializable>( batchSize );
+ }
+ }
+ }
+ finally {
+ results.close();
+ }
+ enqueueList( destinationList );
+ }
+
+ private void enqueueList(final List<Serializable> idsList) throws InterruptedException {
+ if ( ! idsList.isEmpty() ) {
+ destination.put( idsList );
+ log.trace( "produced a list of ids {}", idsList );
+ }
+ }
+
+}
Added: search/trunk/src/main/java/org/hibernate/search/batchindexing/IndexWritingJob.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/batchindexing/IndexWritingJob.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/batchindexing/IndexWritingJob.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -0,0 +1,76 @@
+package org.hibernate.search.batchindexing;
+
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+
+import org.hibernate.search.backend.BackendQueueProcessorFactory;
+import org.hibernate.search.backend.LuceneWork;
+import org.hibernate.search.util.LoggerFactory;
+import org.slf4j.Logger;
+
+/**
+ * This Runnable is meant to push to the backend
+ * all LuceneWork it can take from the ProducerConsumerQueue.
+ *
+ * FIXME:
+ * Is currently more an adaptor to bridge the queue approach
+ * to the current backend implementations. This is not by any means
+ * the most efficient way to index documents, it has been built only
+ * to test the approach.
+ *
+ */
+class IndexWritingJob implements Runnable {
+
+ private static final Logger log = LoggerFactory.make();
+
+ private final ProducerConsumerQueue pleq;
+ private final BackendQueueProcessorFactory backend;
+ private final CountDownLatch endSignal;
+ private final IndexerProgressMonitor monitor;
+
+ /**
+ * @param pleq This queue contains the LuceneWork to be send to the backend
+ * @param endSignal
+ * @param monitor
+ * @param backendQueueProcessorFactory
+ */
+ IndexWritingJob(ProducerConsumerQueue pleq, CountDownLatch endSignal, IndexerProgressMonitor monitor, BackendQueueProcessorFactory backendQueueProcessorFactory) {
+ this.pleq = pleq;
+ this.monitor = monitor;
+ this.backend = backendQueueProcessorFactory;
+ this.endSignal = endSignal;
+ log.trace( "created" );
+ }
+
+ public void run() {
+ log.debug( "Start" );
+ try {
+ while ( true ) {
+ Object take = pleq.take();
+ if ( take == null ) {
+ break;
+ }
+ else {
+ LuceneWork work = (LuceneWork) take;
+ log.trace( "received lucenework {}", work );
+ //TODO group work in bigger lists of size #batch and introduce the CommitLuceneWork to avoid waiting more work
+ ArrayList<LuceneWork> list = new ArrayList<LuceneWork>( 1 );
+ list.add( work );
+ Runnable processor = backend.getProcessor( list );
+ processor.run();
+ monitor.documentsAdded( 1L );
+ }
+ }
+ log.debug( "Finished" );
+ }
+ catch (InterruptedException e) {
+ // normal quit: no need to propagate interruption.
+ log.debug( "Interrupted" );
+ }
+ finally {
+ //notify everybody we have finished.
+ endSignal.countDown();
+ }
+ }
+
+}
\ No newline at end of file
Added: search/trunk/src/main/java/org/hibernate/search/batchindexing/IndexerProgressMonitor.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/batchindexing/IndexerProgressMonitor.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/batchindexing/IndexerProgressMonitor.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -0,0 +1,51 @@
+package org.hibernate.search.batchindexing;
+
+/**
+ * As an indexer can take some time to finish,
+ * an IndexerProgressMonitor can be defined in
+ * the configuration property
+ * hibernate.search.worker.indexing.monitor
+ * implementing this interface to track indexing
+ * performance.
+ * Implementors must be threadsafe and have a
+ * no-arg constructor.
+ *
+ * @author Sanne Grinovero
+ */
+public interface IndexerProgressMonitor {
+
+ /**
+ * The number of documents sent to the backend;
+ * This is called several times during
+ * the indexing process.
+ * @param increment
+ */
+ void documentsAdded(long increment);
+
+ /**
+ * The number of Documents built;
+ * This is called several times and concurrently during
+ * the indexing process.
+ * @param number
+ */
+ void documentsBuilt(int number);
+
+ /**
+ * The number of entities loaded from database;
+ * This is called several times and concurrently during
+ * the indexing process.
+ * @param size
+ */
+ void entitiesLoaded(int size);
+
+ /**
+ * The total count of entities to be indexed is
+ * added here; It could be called more than once,
+ * the implementation should add them up.
+ * This is called several times and concurrently during
+ * the indexing process.
+ * @param count
+ */
+ void addToTotalCount(long count);
+
+}
Added: search/trunk/src/main/java/org/hibernate/search/batchindexing/ProducerConsumerQueue.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/batchindexing/ProducerConsumerQueue.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/batchindexing/ProducerConsumerQueue.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -0,0 +1,82 @@
+package org.hibernate.search.batchindexing;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Implements a blocking queue capable of storing
+ * a "poison" token to signal consumer threads
+ * that the task is finished.
+ *
+ * @author Sanne Grinovero
+ */
+public class ProducerConsumerQueue {
+
+ private static final int DEFAULT_BUFF_LENGHT = 1000;
+ private static final Object exitToken = new Object();
+
+ private final BlockingQueue queue;
+ private final AtomicInteger producersToWaitFor;
+
+ /**
+ * @param producersToWaitFor The number of producer threads.
+ */
+ public ProducerConsumerQueue( int producersToWaitFor ) {
+ this( DEFAULT_BUFF_LENGHT, producersToWaitFor );
+ }
+
+ public ProducerConsumerQueue( int queueLenght, int producersToWaitFor ) {
+ queue = new ArrayBlockingQueue( queueLenght );
+ this.producersToWaitFor = new AtomicInteger( producersToWaitFor );
+ }
+
+ /**
+ * Blocks until an object is available; when null
+ * is returned the client thread should quit.
+ * @return the next object in the queue, or null to exit
+ * @throws InterruptedException
+ */
+ public Object take() throws InterruptedException {
+ Object obj = queue.take();
+ if ( obj == exitToken ) {
+ //restore exit signal for other threads
+ queue.put( exitToken );
+ return null;
+ }
+ else {
+ return obj;
+ }
+ }
+
+ /**
+ * Adds a new object to the queue, blocking if no space is
+ * available.
+ * @param obj
+ * @throws InterruptedException
+ */
+ public void put(Object obj) throws InterruptedException {
+ queue.put( obj );
+ }
+
+ /**
+ * Each producer thread should call producerStopping() when it has
+ * finished. After doing it can safely terminate.
+ * After all producer threads have called producerStopping()
+ * a token will be inserted in the blocking queue to eventually
+ * awake sleaping consumers and have them quit, after the
+ * queue has been processed.
+ */
+ public void producerStopping() {
+ int activeProducers = producersToWaitFor.decrementAndGet();
+ //last producer must close consumers
+ if ( activeProducers == 0 ) {
+ try {
+ queue.put( exitToken );//awake all waiting threads to let them quit.
+ } catch (InterruptedException e) {
+ //just quit, consumers will be interrupted anyway if it's a shutdown.
+ }
+ }
+ }
+
+}
Modified: search/trunk/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java 2009-05-18 01:44:29 UTC (rev 16579)
+++ search/trunk/src/main/java/org/hibernate/search/engine/DocumentBuilderIndexedEntity.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -105,7 +105,7 @@
/**
* Flag indicating whether there is an explicit id (@DocumentId or @Id) or not. When Search is used as make
- * for example JBoss Cache searchable the <code>idKeywordName</code> wil be provided.
+ * for example using JBoss Cache Searchable the <code>idKeywordName</code> will be provided.
*/
private boolean idProvided = false;
@@ -337,7 +337,7 @@
super.addWorkToQueue( entityClass, entity, id, workType, queue, searchFactoryImplementor );
}
- private AddLuceneWork createAddWork(Class<T> entityClass, T entity, Serializable id, String idInString, boolean isBatch) {
+ public AddLuceneWork createAddWork(Class<T> entityClass, T entity, Serializable id, String idInString, boolean isBatch) {
Map<String, String> fieldToAnalyzerMap = new HashMap<String, String>();
Document doc = getDocument( entity, id, fieldToAnalyzerMap );
AddLuceneWork addWork;
Modified: search/trunk/src/main/java/org/hibernate/search/impl/FullTextSessionImpl.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/impl/FullTextSessionImpl.java 2009-05-18 01:44:29 UTC (rev 16579)
+++ search/trunk/src/main/java/org/hibernate/search/impl/FullTextSessionImpl.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -46,6 +46,7 @@
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.SearchFactory;
+import org.hibernate.search.Indexer;
import org.hibernate.search.backend.TransactionContext;
import org.hibernate.search.backend.Work;
import org.hibernate.search.backend.WorkType;
@@ -162,6 +163,15 @@
//another solution would be to subclass SessionImpl instead of having this LuceneSession delegation model
//this is an open discussion
}
+
+ public Indexer createIndexer(Class<?>... types) {
+ if ( types.length == 0 ) {
+ return new IndexerImpl( getSearchFactoryImplementor(), getSessionFactory(), Object.class );
+ }
+ else {
+ return new IndexerImpl( getSearchFactoryImplementor(), getSessionFactory(), types );
+ }
+ }
public SearchFactory getSearchFactory() {
if ( searchFactory == null ) {
Added: search/trunk/src/main/java/org/hibernate/search/impl/IndexerImpl.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/impl/IndexerImpl.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/impl/IndexerImpl.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -0,0 +1,172 @@
+package org.hibernate.search.impl;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.hibernate.CacheMode;
+import org.hibernate.SessionFactory;
+import org.hibernate.search.Indexer;
+import org.hibernate.search.batchindexing.BatchIndexingWorkspace;
+import org.hibernate.search.batchindexing.IndexerProgressMonitor;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.hibernate.search.util.LoggerFactory;
+import org.slf4j.Logger;
+
+/**
+ * Prepares and configures a BatchIndexingWorkspace to start rebuilding
+ * the indexes for all entities in the database.
+ *
+ * @author Sanne Grinovero
+ */
+public class IndexerImpl implements Indexer {
+
+ private static final Logger log = LoggerFactory.make();
+
+ private final SearchFactoryImplementor searchFactoryImplementor;
+ private final SessionFactory sessionFactory;
+
+ protected Set<Class<?>> rootEntities = new HashSet<Class<?>>();
+ protected List<BatchIndexingWorkspace> indexers = new LinkedList<BatchIndexingWorkspace>();
+ boolean started = false;
+ private CountDownLatch endAllSignal;
+
+ // default settings defined here:
+ private int objectLoadingThreads = 2; //loading the main entity
+ private int collectionLoadingThreads = 4; //also responsible for loading of lazy @IndexedEmbedded collections
+ private int writerThreads = 1; //also running the Analyzers
+ private int objectLoadingBatchSize = 10;
+ private CacheMode cacheMode = CacheMode.IGNORE;
+ private boolean optimizeAtEnd = true;
+ private boolean purgeAtStart = true;
+ private boolean optimizeAfterPurge = true;
+ private IndexerProgressMonitor monitor = new SimpleIndexingProgressMonitor();
+
+ protected IndexerImpl(SearchFactoryImplementor searchFactory, SessionFactory sessionFactory, Class<?>...entities) {
+ this.searchFactoryImplementor = searchFactory;
+ this.sessionFactory = sessionFactory;
+ rootEntities = toRootEntities( searchFactoryImplementor, entities );
+ }
+
+ /**
+ * From the set of classes a new set is built containing all indexed
+ * subclasses, but removing then all subtypes of indexed entities.
+ * @param selection
+ * @return a new set of entities
+ */
+ private static Set<Class<?>> toRootEntities(SearchFactoryImplementor searchFactoryImplementor, Class<?>... selection) {
+ Set<Class<?>> entities = new HashSet<Class<?>>();
+ //first build the "entities" set containing all indexed subtypes of "selection".
+ for (Class<?> entityType : selection) {
+ Set<Class<?>> targetedClasses = searchFactoryImplementor.getIndexedTypesPolymorphic( new Class[] {entityType} );
+ if ( targetedClasses.isEmpty() ) {
+ String msg = entityType.getName() + " is not an indexed entity or a subclass of an indexed entity";
+ throw new IllegalArgumentException( msg );
+ }
+ entities.addAll( targetedClasses );
+ }
+ Set<Class<?>> cleaned = new HashSet<Class<?>>();
+ Set<Class<?>> toRemove = new HashSet<Class<?>>();
+ //now remove all repeated types to avoid duplicate loading by polymorphic query loading
+ for (Class<?> type : entities) {
+ boolean typeIsOk = true;
+ for (Class<?> existing : cleaned) {
+ if ( existing.isAssignableFrom( type ) ) {
+ typeIsOk = false;
+ break;
+ }
+ if ( type.isAssignableFrom( existing ) ) {
+ toRemove.add( existing );
+ }
+ }
+ if ( typeIsOk ) {
+ cleaned.add( type );
+ }
+ }
+ cleaned.removeAll( toRemove );
+ if ( log.isDebugEnabled() ) {
+ log.debug( "Targets for indexing job: {}", cleaned );
+ }
+ return cleaned;
+ }
+
+ public Indexer cacheMode(CacheMode cacheMode) {
+ if ( cacheMode == null )
+ throw new IllegalArgumentException( "cacheMode must not be null" );
+ this.cacheMode = cacheMode;
+ return this;
+ }
+
+ public Indexer objectLoadingThreads(int numberOfThreads) {
+ if ( numberOfThreads < 1 )
+ throw new IllegalArgumentException( "numberOfThreads must be at least 1" );
+ this.objectLoadingThreads = numberOfThreads;
+ return this;
+ }
+
+ public Indexer objectLoadingBatchSize(int batchSize) {
+ if ( batchSize < 1 )
+ throw new IllegalArgumentException( "batchSize must be at least 1" );
+ this.objectLoadingBatchSize = batchSize;
+ return this;
+ }
+
+ public Indexer documentBuilderThreads(int numberOfThreads) {
+ if ( numberOfThreads < 1 )
+ throw new IllegalArgumentException( "numberOfThreads must be at least 1" );
+ this.collectionLoadingThreads = numberOfThreads;
+ return this;
+ }
+
+ public Indexer indexWriterThreads(int numberOfThreads) {
+ if ( numberOfThreads < 1 )
+ throw new IllegalArgumentException( "numberOfThreads must be at least 1" );
+ this.writerThreads = numberOfThreads;
+ return this;
+ }
+
+ public Indexer optimizeAtEnd(boolean optimize) {
+ this.optimizeAtEnd = optimize;
+ return this;
+ }
+
+ public Indexer optimizeAfterPurge(boolean optimize) {
+ this.optimizeAfterPurge = optimize;
+ return this;
+ }
+
+ public Indexer purgeAllAtStart(boolean purgeAll) {
+ this.purgeAtStart = purgeAll;
+ return this;
+ }
+
+ public void start() {
+ if ( started ) {
+ throw new IllegalStateException( "Can be started only once" );
+ }
+ else {
+ started = true;
+ endAllSignal = new CountDownLatch( rootEntities.size() );
+ for ( Class<?> type : rootEntities ) {
+ indexers.add( new BatchIndexingWorkspace(
+ searchFactoryImplementor, sessionFactory, type,
+ objectLoadingThreads, collectionLoadingThreads, writerThreads,
+ cacheMode, objectLoadingBatchSize,
+ optimizeAtEnd, purgeAtStart, optimizeAfterPurge,
+ endAllSignal, monitor) );
+ }
+ for ( BatchIndexingWorkspace batcher : indexers ) {
+ new Thread( batcher ).start();
+ }
+ }
+ }
+
+ public boolean startAndWait(long timeout, TimeUnit unit) throws InterruptedException {
+ start();
+ return endAllSignal.await( timeout, unit );
+ }
+
+}
Added: search/trunk/src/main/java/org/hibernate/search/impl/SimpleIndexingProgressMonitor.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/impl/SimpleIndexingProgressMonitor.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/impl/SimpleIndexingProgressMonitor.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -0,0 +1,56 @@
+package org.hibernate.search.impl;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.hibernate.search.batchindexing.IndexerProgressMonitor;
+import org.hibernate.search.util.LoggerFactory;
+import org.slf4j.Logger;
+
+/**
+ * A very simple implementation of IndexerProgressMonitor
+ *
+ * @author Sanne Grinovero
+ */
+public class SimpleIndexingProgressMonitor implements IndexerProgressMonitor {
+
+ private static final Logger log = LoggerFactory.make();
+ private final AtomicLong documentsDoneCounter = new AtomicLong();
+ private final AtomicLong totalCounter = new AtomicLong();
+ private volatile long startTimeMs;
+
+ public void entitiesLoaded(int size) {
+ //not used
+ }
+
+ public void documentsAdded(long increment) {
+ long current = documentsDoneCounter.addAndGet( increment );
+ if ( current == increment ) {
+ startTimeMs = System.currentTimeMillis();
+ }
+ if ( current % getStatusMessagePeriod() == 0 ) {
+ printStatusMessage( startTimeMs, totalCounter.get(), current );
+ }
+ }
+
+ public void documentsBuilt(int number) {
+ //not used
+ }
+
+ public void addToTotalCount(long count) {
+ totalCounter.addAndGet( count );
+ log.info( "Going to reindex {} entities", count );
+ }
+
+ protected int getStatusMessagePeriod() {
+ return 1000;
+ }
+
+ protected void printStatusMessage(long starttimems, long totalTodoCount, long doneCount) {
+ long elapsedMs = System.currentTimeMillis() - starttimems;
+ log.info( "{} documents indexed in {} ms", doneCount, elapsedMs );
+ double estimateSpeed = ( (double) doneCount * 1000f ) / elapsedMs ;
+ double estimatePercentileComplete = ( (double) doneCount*100 ) / (double)totalTodoCount ;
+ log.info( "Indexing speed: {} documents/second; progress: {}%", estimateSpeed, estimatePercentileComplete );
+ }
+
+}
Modified: search/trunk/src/main/java/org/hibernate/search/jpa/FullTextEntityManager.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/jpa/FullTextEntityManager.java 2009-05-18 01:44:29 UTC (rev 16579)
+++ search/trunk/src/main/java/org/hibernate/search/jpa/FullTextEntityManager.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -4,6 +4,7 @@
import java.io.Serializable;
import javax.persistence.EntityManager;
+import org.hibernate.search.Indexer;
import org.hibernate.search.SearchFactory;
/**
@@ -68,5 +69,14 @@
* Flush all index changes forcing Hibernate Search to apply all changes to the index not waiting for the batch limit.
*/
public void flushToIndexes();
+
+ /**
+ * Creates an Indexer to rebuild the indexes of some
+ * or all indexed entity types.
+ * Instances cannot be reused.
+ * @param types optionally restrict the operation to selected types
+ * @return
+ */
+ public Indexer createIndexer(Class<?>... types);
}
Modified: search/trunk/src/main/java/org/hibernate/search/jpa/impl/FullTextEntityManagerImpl.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/jpa/impl/FullTextEntityManagerImpl.java 2009-05-18 01:44:29 UTC (rev 16579)
+++ search/trunk/src/main/java/org/hibernate/search/jpa/impl/FullTextEntityManagerImpl.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -10,6 +10,7 @@
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.FullTextQuery;
+import org.hibernate.search.Indexer;
import org.hibernate.search.SearchFactory;
import org.hibernate.search.SearchException;
import org.hibernate.search.FullTextSession;
@@ -176,4 +177,9 @@
public EntityTransaction getTransaction() {
return em.getTransaction();
}
+
+ public Indexer createIndexer(Class<?>... types) {
+ return getFullTextSession().createIndexer( types );
+ }
+
}
Added: search/trunk/src/test/java/org/hibernate/search/test/batchindexing/AncientBook.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/batchindexing/AncientBook.java (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/batchindexing/AncientBook.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -0,0 +1,13 @@
+package org.hibernate.search.test.batchindexing;
+
+import javax.persistence.Entity;
+
+import org.hibernate.search.annotations.Indexed;
+
+@Entity
+@Indexed
+public class AncientBook extends Book {
+
+ public String catalogueGroupName = "";
+
+}
Added: search/trunk/src/test/java/org/hibernate/search/test/batchindexing/Book.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/batchindexing/Book.java (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/batchindexing/Book.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -0,0 +1,15 @@
+package org.hibernate.search.test.batchindexing;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+import org.hibernate.search.annotations.Indexed;
+
+@Indexed
+@Entity
+public class Book {
+
+ @Id
+ public long id;
+
+}
Added: search/trunk/src/test/java/org/hibernate/search/test/batchindexing/Dvd.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/batchindexing/Dvd.java (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/batchindexing/Dvd.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -0,0 +1,36 @@
+package org.hibernate.search.test.batchindexing;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Indexed;
+
+@Indexed
+@Entity
+public class Dvd {
+
+ public long unusuallyNamedIdentifier;
+ public String title;
+
+ @Id
+ @GeneratedValue
+ public long getUnusuallyNamedIdentifier() {
+ return unusuallyNamedIdentifier;
+ }
+
+ public void setUnusuallyNamedIdentifier(long unusuallyNamedIdentifier) {
+ this.unusuallyNamedIdentifier = unusuallyNamedIdentifier;
+ }
+
+ @Field
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+}
Added: search/trunk/src/test/java/org/hibernate/search/test/batchindexing/ModernBook.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/batchindexing/ModernBook.java (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/batchindexing/ModernBook.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -0,0 +1,13 @@
+package org.hibernate.search.test.batchindexing;
+
+import javax.persistence.Entity;
+
+import org.hibernate.search.annotations.Indexed;
+
+@Entity
+@Indexed
+public class ModernBook extends Book {
+
+ public String isbn = null;
+
+}
Added: search/trunk/src/test/java/org/hibernate/search/test/batchindexing/SearchIndexerTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/batchindexing/SearchIndexerTest.java (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/batchindexing/SearchIndexerTest.java 2009-05-18 01:59:10 UTC (rev 16580)
@@ -0,0 +1,118 @@
+package org.hibernate.search.test.batchindexing;
+
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.TestCase;
+
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.TermQuery;
+import org.hibernate.Transaction;
+import org.hibernate.search.Environment;
+import org.hibernate.search.FullTextQuery;
+import org.hibernate.search.FullTextSession;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.hibernate.search.impl.IndexerImpl;
+import org.hibernate.search.test.util.FullTextSessionBuilder;
+
+public class SearchIndexerTest extends TestCase {
+
+ public void testEntityHierarchy() {
+ FullTextSessionBuilder ftsb = new FullTextSessionBuilder()
+ .addAnnotatedClass( ModernBook.class )
+ .addAnnotatedClass( AncientBook.class )
+ .addAnnotatedClass( Dvd.class )
+ .addAnnotatedClass( Book.class )
+ .build();
+ FullTextSession fullTextSession = ftsb.openFullTextSession();
+ SearchFactoryImplementor searchFactory = (SearchFactoryImplementor) fullTextSession.getSearchFactory();
+ {
+ TestableSearchIndexerImpl tsii = new TestableSearchIndexerImpl( searchFactory, Book.class );
+ assertTrue( tsii.getRootEntities().contains( Book.class ) );
+ assertFalse( tsii.getRootEntities().contains( ModernBook.class ) );
+ assertFalse( tsii.getRootEntities().contains( AncientBook.class ) );
+ }
+ {
+ TestableSearchIndexerImpl tsii = new TestableSearchIndexerImpl( searchFactory, ModernBook.class, AncientBook.class, Book.class );
+ assertTrue( tsii.getRootEntities().contains( Book.class ) );
+ assertFalse( tsii.getRootEntities().contains( ModernBook.class ) );
+ assertFalse( tsii.getRootEntities().contains( AncientBook.class ) );
+ }
+ {
+ TestableSearchIndexerImpl tsii = new TestableSearchIndexerImpl( searchFactory, ModernBook.class, AncientBook.class );
+ assertFalse( tsii.getRootEntities().contains( Book.class ) );
+ assertTrue( tsii.getRootEntities().contains( ModernBook.class ) );
+ assertTrue( tsii.getRootEntities().contains( AncientBook.class ) );
+ }
+ //verify that indexing Object will result in one separate indexer working per root indexed entity
+ {
+ TestableSearchIndexerImpl tsii = new TestableSearchIndexerImpl( searchFactory, Object.class );
+ assertTrue( tsii.getRootEntities().contains( Book.class ) );
+ assertTrue( tsii.getRootEntities().contains( Dvd.class ) );
+ assertFalse( tsii.getRootEntities().contains( AncientBook.class ) );
+ assertFalse( tsii.getRootEntities().contains( Object.class ) );
+ assertEquals( 2, tsii.getRootEntities().size() );
+ }
+ }
+
+ private class TestableSearchIndexerImpl extends IndexerImpl {
+
+ protected TestableSearchIndexerImpl(SearchFactoryImplementor searchFactory, Class<?>... types) {
+ super( searchFactory, null, types );
+ }
+
+ public Set<Class<?>> getRootEntities() {
+ return this.rootEntities;
+ }
+
+ }
+
+ public void testIdentifierNaming() throws InterruptedException {
+ //disable automatic indexing, to test manual index creation.
+ FullTextSessionBuilder ftsb = new FullTextSessionBuilder()
+ .setProperty( org.hibernate.search.Environment.ANALYZER_CLASS, StandardAnalyzer.class.getName() )
+ .addAnnotatedClass( Dvd.class )
+ .setProperty( Environment.INDEXING_STRATEGY, "manual" )
+ .build();
+ {
+ //creating the test data in database only:
+ FullTextSession fullTextSession = ftsb.openFullTextSession();
+ Transaction transaction = fullTextSession.beginTransaction();
+ Dvd dvda = new Dvd();
+ dvda.setTitle( "Star Trek (episode 96367)" );
+ fullTextSession.save(dvda);
+ Dvd dvdb = new Dvd();
+ dvdb.setTitle( "The Trek" );
+ fullTextSession.save(dvdb);
+ transaction.commit();
+ fullTextSession.close();
+ }
+ {
+ //verify index is still empty:
+ assertEquals( 0, countResults( new Term( "title", "trek" ), ftsb, Dvd.class ) );
+ }
+ {
+ FullTextSession fullTextSession = ftsb.openFullTextSession();
+ fullTextSession.createIndexer( Dvd.class )
+ .startAndWait( 10, TimeUnit.SECONDS );
+ fullTextSession.close();
+ }
+ {
+ //verify index is now containing both DVDs:
+ assertEquals( 2, countResults( new Term( "title", "trek" ), ftsb, Dvd.class ) );
+ }
+ }
+
+ public int countResults( Term termForQuery, FullTextSessionBuilder ftSessionBuilder, Class<?> type ) {
+ TermQuery fullTextQuery = new TermQuery( new Term( "title", "trek" ) );
+ FullTextSession fullTextSession = ftSessionBuilder.openFullTextSession();
+ Transaction transaction = fullTextSession.beginTransaction();
+ FullTextQuery query = fullTextSession.createFullTextQuery( fullTextQuery, type );
+ int resultSize = query.getResultSize();
+ transaction.commit();
+ fullTextSession.close();
+ return resultSize;
+ }
+
+}
15 years, 6 months
Hibernate SVN: r16579 - in search/trunk/src/test/java/org/hibernate/search/test: analyzer and 3 other directories.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2009-05-17 21:44:29 -0400 (Sun, 17 May 2009)
New Revision: 16579
Modified:
search/trunk/src/test/java/org/hibernate/search/test/SearchTestCase.java
search/trunk/src/test/java/org/hibernate/search/test/analyzer/AnalyzerTest.java
search/trunk/src/test/java/org/hibernate/search/test/configuration/CustomBackendTest.java
search/trunk/src/test/java/org/hibernate/search/test/query/ScrollableResultsTest.java
search/trunk/src/test/java/org/hibernate/search/test/util/FullTextSessionBuilder.java
Log:
review of some test utilities
Modified: search/trunk/src/test/java/org/hibernate/search/test/SearchTestCase.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/SearchTestCase.java 2009-05-17 14:03:07 UTC (rev 16578)
+++ search/trunk/src/test/java/org/hibernate/search/test/SearchTestCase.java 2009-05-18 01:44:29 UTC (rev 16579)
@@ -9,6 +9,7 @@
import org.slf4j.Logger;
import org.hibernate.HibernateException;
+import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
@@ -18,6 +19,7 @@
import org.hibernate.search.Environment;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
+import org.hibernate.search.SearchFactory;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.event.FullTextIndexEventListener;
import org.hibernate.search.store.RAMDirectoryProvider;
@@ -33,6 +35,8 @@
private static final Logger log = org.hibernate.search.util.LoggerFactory.make();
private static File indexDir;
+
+ private SearchFactory searchFactory;
static {
String buildDir = System.getProperty( "build.dir" );
@@ -52,10 +56,10 @@
protected void tearDown() throws Exception {
SchemaExport export = new SchemaExport( cfg );
export.drop( false, true );
+ searchFactory = null;
}
- @SuppressWarnings("unchecked")
- protected Directory getDirectory(Class clazz) {
+ protected Directory getDirectory(Class<?> clazz) {
return getLuceneEventListener().getSearchFactoryImplementor().getDirectoryProviders( clazz )[0].getDirectory();
}
@@ -84,7 +88,7 @@
FullTextSession s = Search.getFullTextSession( openSession() );
Transaction tx;
tx = s.beginTransaction();
- for ( Class clazz : getMappings() ) {
+ for ( Class<?> clazz : getMappings() ) {
if ( clazz.getAnnotation( Indexed.class ) != null ) {
s.purgeAll( clazz );
}
@@ -92,6 +96,16 @@
tx.commit();
s.close();
}
+
+ protected SearchFactory getSearchFactory() {
+ if ( searchFactory == null ) {
+ Session session = openSession();
+ FullTextSession fullTextSession = Search.getFullTextSession( session );
+ searchFactory = fullTextSession.getSearchFactory();
+ fullTextSession.close();
+ }
+ return searchFactory;
+ }
protected void configure(Configuration cfg) {
cfg.setProperty( "hibernate.search.default.directory_provider", RAMDirectoryProvider.class.getName() );
@@ -105,7 +119,7 @@
return indexDir;
}
- protected void buildSessionFactory(Class[] classes, String[] packages, String[] xmlFiles) throws Exception {
+ protected void buildSessionFactory(Class<?>[] classes, String[] packages, String[] xmlFiles) throws Exception {
if ( getSessions() != null ) {
getSessions().close();
}
@@ -118,7 +132,7 @@
for ( String aPackage : packages ) {
( ( AnnotationConfiguration ) getCfg() ).addPackage( aPackage );
}
- for ( Class aClass : classes ) {
+ for ( Class<?> aClass : classes ) {
( ( AnnotationConfiguration ) getCfg() ).addAnnotatedClass( aClass );
}
for ( String xmlFile : xmlFiles ) {
@@ -134,7 +148,7 @@
}
}
- protected abstract Class[] getMappings();
+ protected abstract Class<?>[] getMappings();
protected String[] getAnnotatedPackages() {
return new String[] { };
Modified: search/trunk/src/test/java/org/hibernate/search/test/analyzer/AnalyzerTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/analyzer/AnalyzerTest.java 2009-05-17 14:03:07 UTC (rev 16578)
+++ search/trunk/src/test/java/org/hibernate/search/test/analyzer/AnalyzerTest.java 2009-05-18 01:44:29 UTC (rev 16579)
@@ -157,7 +157,7 @@
session.close();
}
- protected Class[] getMappings() {
+ protected Class<?>[] getMappings() {
return new Class[] { MyEntity.class, Article.class };
}
}
Modified: search/trunk/src/test/java/org/hibernate/search/test/configuration/CustomBackendTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/configuration/CustomBackendTest.java 2009-05-17 14:03:07 UTC (rev 16578)
+++ search/trunk/src/test/java/org/hibernate/search/test/configuration/CustomBackendTest.java 2009-05-18 01:44:29 UTC (rev 16579)
@@ -26,8 +26,9 @@
FullTextSessionBuilder builder = new FullTextSessionBuilder();
FullTextSession ftSession = builder
.setProperty( "hibernate.search.worker.backend", name )
- .build();
+ .openFullTextSession();
SearchFactoryImpl searchFactory = (SearchFactoryImpl) ftSession.getSearchFactory();
+ ftSession.close();
assertEquals( backendType, searchFactory.getBackendQueueProcessorFactory().getClass() );
builder.close();
}
Modified: search/trunk/src/test/java/org/hibernate/search/test/query/ScrollableResultsTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/query/ScrollableResultsTest.java 2009-05-17 14:03:07 UTC (rev 16578)
+++ search/trunk/src/test/java/org/hibernate/search/test/query/ScrollableResultsTest.java 2009-05-18 01:44:29 UTC (rev 16579)
@@ -28,11 +28,12 @@
public void setUp() throws Exception {
super.setUp();
builder = new FullTextSessionBuilder();
- sess = builder
+ builder
.addAnnotatedClass( AlternateBook.class )
.addAnnotatedClass( Employee.class )
.setProperty( "hibernate.default_batch_fetch_size", "10" )
.build();
+ sess = builder.openFullTextSession();
Transaction tx = sess.beginTransaction();
//create some entities to query:
for ( int i = 0; i < 324; i++ ) {
Modified: search/trunk/src/test/java/org/hibernate/search/test/util/FullTextSessionBuilder.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/util/FullTextSessionBuilder.java 2009-05-17 14:03:07 UTC (rev 16578)
+++ search/trunk/src/test/java/org/hibernate/search/test/util/FullTextSessionBuilder.java 2009-05-18 01:44:29 UTC (rev 16579)
@@ -1,6 +1,8 @@
// $Id$
package org.hibernate.search.test.util;
+import java.io.File;
+
import org.apache.lucene.analysis.StopAnalyzer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
@@ -8,7 +10,10 @@
import org.hibernate.cfg.Environment;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
+import org.hibernate.search.store.FSDirectoryProvider;
import org.hibernate.search.store.RAMDirectoryProvider;
+import org.hibernate.search.util.FileHelper;
+import org.slf4j.Logger;
/**
* Use the builder pattern to provide a SessionFactory.
@@ -20,10 +25,23 @@
*/
public class FullTextSessionBuilder {
+ private static final Logger log = org.hibernate.search.util.LoggerFactory.make();
+
+ private static File indexDir;
+
private AnnotationConfiguration cfg;
private SessionFactory sessionFactory;
- private Session session;
+ static {
+ String buildDir = System.getProperty( "build.dir" );
+ if ( buildDir == null ) {
+ buildDir = ".";
+ }
+ File current = new File( buildDir );
+ indexDir = new File( current, "indextemp" );
+ log.debug( "Using {} as index directory.", indexDir.getAbsolutePath() );
+ }
+
public FullTextSessionBuilder() {
cfg = new AnnotationConfiguration();
cfg.setProperty( Environment.HBM2DDL_AUTO, "create-drop" );
@@ -37,11 +55,26 @@
//search specific:
cfg.setProperty( org.hibernate.search.Environment.ANALYZER_CLASS,
StopAnalyzer.class.getName() );
- cfg.setProperty( "hibernate.search.default.directory_provider",
- RAMDirectoryProvider.class.getName() );
+ useRAMDirectoryProvider( true );
}
/**
+ * @param use if true, use indexes in RAM otherwise use FSDirectoryProvider
+ * @return the same builder (this).
+ */
+ public FullTextSessionBuilder useRAMDirectoryProvider(boolean use) {
+ if ( use ) {
+ cfg.setProperty( "hibernate.search.default.directory_provider",
+ RAMDirectoryProvider.class.getName() );
+ }
+ else {
+ cfg.setProperty( "hibernate.search.default.directory_provider",
+ FSDirectoryProvider.class.getName() );
+ }
+ return this;
+ }
+
+ /**
* Override before building any parameter, or add new ones.
* @param key Property name.
* @param value Property value.
@@ -63,28 +96,35 @@
}
/**
- * Creates a new FullTextSession based upon the configuration built so far.
- * @return new FullTextSession based upon the configuration built so far.
+ * @return a new FullTextSession based upon the built configuration.
*/
- public FullTextSession build() {
- if ( session != null || sessionFactory != null ) {
- throw new java.lang.IllegalStateException( "session is open already" );
+ public FullTextSession openFullTextSession() {
+ if ( sessionFactory == null ) {
+ build();
}
- sessionFactory = cfg.buildSessionFactory();
- session = sessionFactory.openSession();
+ Session session = sessionFactory.openSession();
return Search.getFullTextSession( session );
}
/**
- * Closes the provided FullTextSession and the SessionFactory
+ * Closes the SessionFactory.
+ * Make sure you close all sessions first
*/
public void close() {
- if ( session == null || sessionFactory == null ) {
- throw new java.lang.IllegalStateException( "session not yet built" );
+ if ( sessionFactory == null ) {
+ throw new java.lang.IllegalStateException( "sessionFactory not yet built" );
}
- session.close();
- session = null;
sessionFactory.close();
+ FileHelper.delete( indexDir );
sessionFactory = null;
}
+
+ /**
+ * Builds the sessionFactory as configured so far.
+ */
+ public FullTextSessionBuilder build() {
+ sessionFactory = cfg.buildSessionFactory();
+ return this;
+ }
+
}
15 years, 6 months
Hibernate SVN: r16577 - in search/trunk/src: main/java/org/hibernate/search/cfg and 11 other directories.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2009-05-16 06:34:36 -0400 (Sat, 16 May 2009)
New Revision: 16577
Modified:
search/trunk/src/main/java/org/hibernate/search/Version.java
search/trunk/src/main/java/org/hibernate/search/cfg/DocumentIdMapping.java
search/trunk/src/main/java/org/hibernate/search/cfg/EntityMapping.java
search/trunk/src/main/java/org/hibernate/search/cfg/PropertyDescriptor.java
search/trunk/src/main/java/org/hibernate/search/query/FullTextQueryImpl.java
search/trunk/src/test/java/org/hibernate/search/test/TransactionTest.java
search/trunk/src/test/java/org/hibernate/search/test/analyzer/AnalyzerTest.java
search/trunk/src/test/java/org/hibernate/search/test/analyzer/solr/InsertWhitespaceFilter.java
search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java
search/trunk/src/test/java/org/hibernate/search/test/embedded/State.java
search/trunk/src/test/java/org/hibernate/search/test/filter/FiltersOptimizationTest.java
search/trunk/src/test/java/org/hibernate/search/test/inheritance/Animal.java
search/trunk/src/test/java/org/hibernate/search/test/inheritance/Being.java
search/trunk/src/test/java/org/hibernate/search/test/jms/master/MDBSearchController.java
search/trunk/src/test/java/org/hibernate/search/test/query/ProjectionQueryTest.java
search/trunk/src/test/java/org/hibernate/search/test/query/criteria/Bike.java
Log:
removing dead code, unused imports, set Version to 3.2.0-SNAPSHOT
Modified: search/trunk/src/main/java/org/hibernate/search/Version.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/Version.java 2009-05-16 09:57:32 UTC (rev 16576)
+++ search/trunk/src/main/java/org/hibernate/search/Version.java 2009-05-16 10:34:36 UTC (rev 16577)
@@ -1,25 +1,20 @@
//$Id$
package org.hibernate.search;
-import java.util.Date;
-
-import org.slf4j.Logger;
-
import org.hibernate.search.util.LoggerFactory;
-
/**
* @author Emmanuel Bernard
*/
public class Version {
- public static final String VERSION = "3.1.0.GA";
+
+ public static final String VERSION = "3.2.0-SNAPSHOT";
- private static final Logger log = LoggerFactory.make();
-
static {
- log.info( "Hibernate Search {}", VERSION );
+ LoggerFactory.make().info( "Hibernate Search {}", VERSION );
}
public static void touch() {
}
+
}
Modified: search/trunk/src/main/java/org/hibernate/search/cfg/DocumentIdMapping.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/cfg/DocumentIdMapping.java 2009-05-16 09:57:32 UTC (rev 16576)
+++ search/trunk/src/main/java/org/hibernate/search/cfg/DocumentIdMapping.java 2009-05-16 10:34:36 UTC (rev 16577)
@@ -6,10 +6,6 @@
import org.apache.solr.analysis.TokenizerFactory;
-import org.hibernate.search.annotations.Index;
-import org.hibernate.search.annotations.Store;
-import org.hibernate.search.annotations.TermVector;
-
/**
* @author Emmanuel Bernard
*/
Modified: search/trunk/src/main/java/org/hibernate/search/cfg/EntityMapping.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/cfg/EntityMapping.java 2009-05-16 09:57:32 UTC (rev 16576)
+++ search/trunk/src/main/java/org/hibernate/search/cfg/EntityMapping.java 2009-05-16 10:34:36 UTC (rev 16577)
@@ -6,8 +6,6 @@
import org.apache.solr.analysis.TokenizerFactory;
-import org.hibernate.search.annotations.Indexed;
-
/**
* @author Emmanuel Bernard
*/
Modified: search/trunk/src/main/java/org/hibernate/search/cfg/PropertyDescriptor.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/cfg/PropertyDescriptor.java 2009-05-16 09:57:32 UTC (rev 16576)
+++ search/trunk/src/main/java/org/hibernate/search/cfg/PropertyDescriptor.java 2009-05-16 10:34:36 UTC (rev 16577)
@@ -1,9 +1,7 @@
package org.hibernate.search.cfg;
import java.lang.annotation.ElementType;
-import java.util.HashSet;
import java.util.Map;
-import java.util.Set;
import java.util.Collection;
import java.util.ArrayList;
Modified: search/trunk/src/main/java/org/hibernate/search/query/FullTextQueryImpl.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/query/FullTextQueryImpl.java 2009-05-16 09:57:32 UTC (rev 16576)
+++ search/trunk/src/main/java/org/hibernate/search/query/FullTextQueryImpl.java 2009-05-16 10:34:36 UTC (rev 16577)
@@ -150,7 +150,6 @@
QueryHits queryHits = getQueryHits( searcher, calculateTopDocsRetrievalSize() );
int first = first();
int max = max( first, queryHits.totalHits );
- Session sess = ( Session ) this.session;
int size = max - first + 1 < 0 ? 0 : max - first + 1;
List<EntityInfo> infos = new ArrayList<EntityInfo>( size );
@@ -293,7 +292,6 @@
QueryHits queryHits = getQueryHits( searcher, calculateTopDocsRetrievalSize() );
int first = first();
int max = max( first, queryHits.totalHits );
- Session sess = ( Session ) this.session;
int size = max - first + 1 < 0 ? 0 : max - first + 1;
List<EntityInfo> infos = new ArrayList<EntityInfo>( size );
Modified: search/trunk/src/test/java/org/hibernate/search/test/TransactionTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/TransactionTest.java 2009-05-16 09:57:32 UTC (rev 16576)
+++ search/trunk/src/test/java/org/hibernate/search/test/TransactionTest.java 2009-05-16 10:34:36 UTC (rev 16577)
@@ -6,7 +6,6 @@
import org.apache.lucene.index.IndexReader;
import org.hibernate.Session;
-import org.hibernate.cfg.Configuration;
/**
* @author Emmanuel Bernard
Modified: search/trunk/src/test/java/org/hibernate/search/test/analyzer/AnalyzerTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/analyzer/AnalyzerTest.java 2009-05-16 09:57:32 UTC (rev 16576)
+++ search/trunk/src/test/java/org/hibernate/search/test/analyzer/AnalyzerTest.java 2009-05-16 10:34:36 UTC (rev 16577)
@@ -3,7 +3,6 @@
import java.util.HashSet;
import java.util.Set;
-import javax.print.attribute.HashAttributeSet;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.Token;
@@ -20,7 +19,6 @@
import org.hibernate.search.SearchFactory;
import org.hibernate.search.SearchException;
import org.hibernate.search.impl.InitContext;
-import org.hibernate.search.cfg.SearchConfiguration;
import org.hibernate.search.cfg.SearchConfigurationFromHibernateCore;
import org.hibernate.search.engine.DocumentBuilderContainedEntity;
import org.hibernate.search.test.SearchTestCase;
Modified: search/trunk/src/test/java/org/hibernate/search/test/analyzer/solr/InsertWhitespaceFilter.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/analyzer/solr/InsertWhitespaceFilter.java 2009-05-16 09:57:32 UTC (rev 16576)
+++ search/trunk/src/test/java/org/hibernate/search/test/analyzer/solr/InsertWhitespaceFilter.java 2009-05-16 10:34:36 UTC (rev 16577)
@@ -1,17 +1,12 @@
// $Id: AbstractTestAnalyzer.java 15547 2008-11-11 12:57:47Z hardy.ferentschik $
package org.hibernate.search.test.analyzer.solr;
-import java.io.Reader;
import java.io.IOException;
-import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.Token;
-import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.TokenFilter;
-import org.apache.lucene.search.Filter;
+import org.apache.lucene.analysis.TokenStream;
-
/**
* A filter which will actually insert spaces. Most filters/tokenizers remove them, but for testing it is
* sometimes better to insert them again ;-)
Modified: search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java 2009-05-16 09:57:32 UTC (rev 16576)
+++ search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java 2009-05-16 10:34:36 UTC (rev 16577)
@@ -8,7 +8,6 @@
import org.apache.solr.analysis.LowerCaseFilterFactory;
import org.apache.solr.analysis.NGramFilterFactory;
import org.apache.lucene.queryParser.QueryParser;
-import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.search.DefaultSimilarity;
@@ -21,9 +20,6 @@
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.hibernate.search.FullTextQuery;
-import org.hibernate.search.bridge.builtin.StringBridge;
-import org.hibernate.search.store.RAMDirectoryProvider;
-import org.hibernate.search.store.FSDirectoryProvider;
import org.hibernate.cfg.Configuration;
import org.hibernate.Transaction;
Modified: search/trunk/src/test/java/org/hibernate/search/test/embedded/State.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/embedded/State.java 2009-05-16 09:57:32 UTC (rev 16576)
+++ search/trunk/src/test/java/org/hibernate/search/test/embedded/State.java 2009-05-16 10:34:36 UTC (rev 16577)
@@ -9,7 +9,6 @@
import org.hibernate.search.annotations.ContainedIn;
import org.hibernate.search.annotations.DocumentId;
import org.hibernate.search.annotations.Field;
-import org.hibernate.search.annotations.Indexed;
/**
* @author Hardy Ferentschik
Modified: search/trunk/src/test/java/org/hibernate/search/test/filter/FiltersOptimizationTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/filter/FiltersOptimizationTest.java 2009-05-16 09:57:32 UTC (rev 16576)
+++ search/trunk/src/test/java/org/hibernate/search/test/filter/FiltersOptimizationTest.java 2009-05-16 10:34:36 UTC (rev 16577)
@@ -3,7 +3,6 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.BitSet;
-import java.util.Collections;
import java.util.List;
import org.apache.lucene.search.DocIdSet;
Modified: search/trunk/src/test/java/org/hibernate/search/test/inheritance/Animal.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/inheritance/Animal.java 2009-05-16 09:57:32 UTC (rev 16576)
+++ search/trunk/src/test/java/org/hibernate/search/test/inheritance/Animal.java 2009-05-16 10:34:36 UTC (rev 16577)
@@ -1,7 +1,6 @@
//$Id$
package org.hibernate.search.test.inheritance;
-import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@@ -9,7 +8,6 @@
import org.hibernate.search.annotations.DocumentId;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
-import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.Store;
/**
Modified: search/trunk/src/test/java/org/hibernate/search/test/inheritance/Being.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/inheritance/Being.java 2009-05-16 09:57:32 UTC (rev 16576)
+++ search/trunk/src/test/java/org/hibernate/search/test/inheritance/Being.java 2009-05-16 10:34:36 UTC (rev 16577)
@@ -6,7 +6,6 @@
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.FieldBridge;
-import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.test.bridge.PaddedIntegerBridge;
/**
Modified: search/trunk/src/test/java/org/hibernate/search/test/jms/master/MDBSearchController.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/jms/master/MDBSearchController.java 2009-05-16 09:57:32 UTC (rev 16576)
+++ search/trunk/src/test/java/org/hibernate/search/test/jms/master/MDBSearchController.java 2009-05-16 10:34:36 UTC (rev 16577)
@@ -1,8 +1,6 @@
//$Id$
package org.hibernate.search.test.jms.master;
-import javax.jms.MessageListener;
-
import org.hibernate.search.backend.impl.jms.AbstractJMSHibernateSearchController;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
Modified: search/trunk/src/test/java/org/hibernate/search/test/query/ProjectionQueryTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/query/ProjectionQueryTest.java 2009-05-16 09:57:32 UTC (rev 16576)
+++ search/trunk/src/test/java/org/hibernate/search/test/query/ProjectionQueryTest.java 2009-05-16 10:34:36 UTC (rev 16577)
@@ -441,7 +441,7 @@
assertTrue( "Should not trigger projection", result.get( 0 ) instanceof Book );
hibQuery = s.createFullTextQuery( query, Book.class );
- hibQuery.setProjection( null );
+ hibQuery.setProjection( (String[]) null );
result = hibQuery.list();
assertNotNull( result );
assertEquals( 1, result.size() );
Modified: search/trunk/src/test/java/org/hibernate/search/test/query/criteria/Bike.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/query/criteria/Bike.java 2009-05-16 09:57:32 UTC (rev 16576)
+++ search/trunk/src/test/java/org/hibernate/search/test/query/criteria/Bike.java 2009-05-16 10:34:36 UTC (rev 16577)
@@ -1,14 +1,9 @@
//$Id$
package org.hibernate.search.test.query.criteria;
-import javax.persistence.DiscriminatorColumn;
-import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.Table;
import org.hibernate.search.annotations.Field;
15 years, 6 months
Hibernate SVN: r16576 - in search/trunk/src: main/java/org/hibernate/search/store and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2009-05-16 05:57:32 -0400 (Sat, 16 May 2009)
New Revision: 16576
Removed:
search/trunk/src/main/java/org/hibernate/search/backend/impl/lucene/IndexInteractionType.java
Modified:
search/trunk/src/main/java/org/hibernate/search/store/DirectoryProviderFactory.java
search/trunk/src/test/java/org/hibernate/search/test/query/boost/FieldBoostTest.java
Log:
removing dead code, better error message for DirectoryProviderFactory
Deleted: search/trunk/src/main/java/org/hibernate/search/backend/impl/lucene/IndexInteractionType.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/backend/impl/lucene/IndexInteractionType.java 2009-05-16 09:54:26 UTC (rev 16575)
+++ search/trunk/src/main/java/org/hibernate/search/backend/impl/lucene/IndexInteractionType.java 2009-05-16 09:57:32 UTC (rev 16576)
@@ -1,31 +0,0 @@
-package org.hibernate.search.backend.impl.lucene;
-
-/**
- * Constants to make the LuceneWorkDelegates advertise the type
- * of resource they are going to need to perform the work.
- *
- * NEEDS_INDEXREADER is missing to make sure there always is an optimal
- * solution, as some operations can be done both through an IndexReader
- * and an IndexWriter, but as of Lucene 2.4 there are no operations which
- * can't be done using an IndexWriter.
- *
- * @author Sanne Grinovero
- */
-public enum IndexInteractionType {
-
- /**
- * The workType needs an IndexWriter.
- */
- NEEDS_INDEXWRITER,
- /**
- * An IndexWriter should work best but it's possible
- * to use an IndexReader instead.
- */
- PREFER_INDEXWRITER,
- /**
- * An IndexReader should work best but it's possible
- * to use an IndexWriter instead.
- */
- PREFER_INDEXREADER
-
-}
Modified: search/trunk/src/main/java/org/hibernate/search/store/DirectoryProviderFactory.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/store/DirectoryProviderFactory.java 2009-05-16 09:54:26 UTC (rev 16575)
+++ search/trunk/src/main/java/org/hibernate/search/store/DirectoryProviderFactory.java 2009-05-16 09:57:32 UTC (rev 16576)
@@ -129,7 +129,7 @@
provider.initialize( directoryProviderName, indexProps, searchFactoryImplementor );
}
catch (Exception e) {
- throw new SearchException( "Unable to initialize: " + directoryProviderName, e );
+ throw new SearchException( "Unable to initialize directory provider: " + directoryProviderName, e );
}
int index = providers.indexOf( provider );
if ( index != -1 ) {
Modified: search/trunk/src/test/java/org/hibernate/search/test/query/boost/FieldBoostTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/query/boost/FieldBoostTest.java 2009-05-16 09:54:26 UTC (rev 16575)
+++ search/trunk/src/test/java/org/hibernate/search/test/query/boost/FieldBoostTest.java 2009-05-16 09:57:32 UTC (rev 16576)
@@ -140,7 +140,6 @@
l.setDescription( "Scientist discovers invisibility and becomes insane." );
session.save( l );
- session.save( l );
l = new BoostedDescriptionLibrary();
l.setAuthor( "H.G. Wells" );
l.setTitle( "War of the Worlds" );
@@ -158,7 +157,6 @@
l.setDescription( "Scientist discovers invisibility and becomes insane." );
session.save( l );
- session.save( l );
l = new BoostedFieldDescriptionLibrary();
l.setAuthor( "H.G. Wells" );
l.setTitle( "War of the Worlds" );
@@ -176,7 +174,6 @@
l.setDescription( "Scientist discovers invisibility and becomes insane." );
session.save( l );
- session.save( l );
l = new BoostedGetDescriptionLibrary();
l.setAuthor( "H.G. Wells" );
l.setTitle( "War of the Worlds" );
15 years, 6 months
Hibernate SVN: r16575 - search/branches/Branch_3_1/src/main/docbook/en-US/modules.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2009-05-16 05:54:26 -0400 (Sat, 16 May 2009)
New Revision: 16575
Modified:
search/branches/Branch_3_1/src/main/docbook/en-US/modules/architecture.xml
search/branches/Branch_3_1/src/main/docbook/en-US/modules/configuration.xml
search/branches/Branch_3_1/src/main/docbook/en-US/modules/getting-started.xml
search/branches/Branch_3_1/src/main/docbook/en-US/modules/lucene-native.xml
search/branches/Branch_3_1/src/main/docbook/en-US/modules/mapping.xml
search/branches/Branch_3_1/src/main/docbook/en-US/modules/optimize.xml
search/branches/Branch_3_1/src/main/docbook/en-US/modules/query.xml
Log:
HSEARCH-369 Running a spellchecker on documentation
Modified: search/branches/Branch_3_1/src/main/docbook/en-US/modules/architecture.xml
===================================================================
--- search/branches/Branch_3_1/src/main/docbook/en-US/modules/architecture.xml 2009-05-16 09:47:42 UTC (rev 16574)
+++ search/branches/Branch_3_1/src/main/docbook/en-US/modules/architecture.xml 2009-05-16 09:54:26 UTC (rev 16575)
@@ -219,7 +219,7 @@
<title>Reader strategy</title>
<para>When executing a query, Hibernate Search interacts with the Apache
- Lucene indexes through a reader strategy. chosing a reader strategy will
+ Lucene indexes through a reader strategy. Choosing a reader strategy will
depend on the profile of the application (frequent updates, read mostly,
asynchronous index update etc). See also <xref
linkend="configuration-reader-strategy" /></para>
Modified: search/branches/Branch_3_1/src/main/docbook/en-US/modules/configuration.xml
===================================================================
--- search/branches/Branch_3_1/src/main/docbook/en-US/modules/configuration.xml 2009-05-16 09:47:42 UTC (rev 16574)
+++ search/branches/Branch_3_1/src/main/docbook/en-US/modules/configuration.xml 2009-05-16 09:54:26 UTC (rev 16575)
@@ -312,8 +312,8 @@
“Animal”. Both entities will then be stored in the Animal
directory</para>
- <para><programlisting><code>hibernate.search.org.hibernate.search.test.shards.Furniture.indexName = Aninal
-hibernate.search.org.hibernate.search.test.shards.Animal.indexName = Aninal</code></programlisting></para>
+ <para><programlisting><code>hibernate.search.org.hibernate.search.test.shards.Furniture.indexName = Animal
+hibernate.search.org.hibernate.search.test.shards.Animal.indexName = Animal</code></programlisting></para>
</listitem>
<listitem>
@@ -366,7 +366,7 @@
<row>
<entry><literal>hibernate.search.worker.execution</literal></entry>
- <entry>Supports synchronous and asynchrounous execution. Default
+ <entry>Supports synchronous and asynchronous execution. Default
to <literal><literal>sync</literal></literal>. Supports also
<literal>async</literal>.</entry>
</row>
@@ -375,14 +375,14 @@
<entry><literal>hibernate.search.worker.thread_pool.size</literal></entry>
<entry>Defines the number of threads in the pool. useful only for
- asynchrounous execution. Default to 1.</entry>
+ asynchronous execution. Default to 1.</entry>
</row>
<row>
<entry><literal>hibernate.search.worker.buffer_queue.max</literal></entry>
<entry>Defines the maximal number of work queue if the thread poll
- is starved. Useful only for asynchrounous execution. Default to
+ is starved. Useful only for asynchronous execution. Default to
infinite. If the limit is reached, the work is done by the main
thread.</entry>
</row>
@@ -439,7 +439,7 @@
<section>
<title>Slave nodes</title>
- <para>Every index update operation is sent to a JMS queue. Index quering
+ <para>Every index update operation is sent to a JMS queue. Index querying
operations are executed on a local index copy.</para>
<example>
@@ -763,7 +763,7 @@
terms.</para> <para>This silently truncates large documents,
excluding from the index all terms that occur further in the
document. If you know your source documents are large, be sure to
- set this value high enough to accomodate the expected size. If you
+ set this value high enough to accommodate the expected size. If you
set it to Integer.MAX_VALUE, then the only limit is your memory,
but you should anticipate an OutOfMemoryError. </para> <para>If
setting this value in <literal>batch</literal> differently than in
@@ -789,13 +789,13 @@
<entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].merge_factor</literal></entry>
<entry><para>Controls segment merge frequency and size. </para>
- <para>Determines how often segment indices are merged when
+ <para>Determines how often segment indexes are merged when
insertion occurs. With smaller values, less RAM is used while
- indexing, and searches on unoptimized indices are faster, but
+ indexing, and searches on unoptimized indexes are faster, but
indexing speed is slower. With larger values, more RAM is used
- during indexing, and while searches on unoptimized indices are
+ during indexing, and while searches on unoptimized indexes are
slower, indexing is faster. Thus larger values (> 10) are best
- for batch index creation, and smaller values (< 10) for indices
+ for batch index creation, and smaller values (< 10) for indexes
that are interactively maintained. The value must no be lower than
2.</para></entry>
Modified: search/branches/Branch_3_1/src/main/docbook/en-US/modules/getting-started.xml
===================================================================
--- search/branches/Branch_3_1/src/main/docbook/en-US/modules/getting-started.xml 2009-05-16 09:47:42 UTC (rev 16574)
+++ search/branches/Branch_3_1/src/main/docbook/en-US/modules/getting-started.xml 2009-05-16 09:54:26 UTC (rev 16575)
@@ -160,7 +160,7 @@
</example>
<para>Not all dependencies are required. Only the
- <emphasis>hibernate-search</emphasis> dependeny is mandatory. This
+ <emphasis>hibernate-search</emphasis> dependency is mandatory. This
dependency, together with its required transitive dependencies, contain
all required classes needed to use Hibernate Search.
<emphasis>hibernate-annotations</emphasis> is only needed if you want to
@@ -173,7 +173,7 @@
use Hibernate Search in conjunction with JPA. The Solr dependencies are
needed if you want to utilize Solr's analyzer framework. More about this
later. And finally, the <literal>lucene-snowball</literal> dependency is
- needed if you want to utililze Lucene's snowball stemmer.</para>
+ needed if you want to use Lucene's snowball stemmer.</para>
</section>
<section>
@@ -230,7 +230,7 @@
<example>
<title>Example entities Book and Author before adding Hibernate Search
- specific annotatons</title>
+ specific annotations</title>
<programlisting>
package example;
@@ -336,7 +336,7 @@
searchable you have to make sure that the names are indexed as part of the
book itself. On top of <literal>@IndexedEmbedded</literal> you will also
have to mark all fields of the associated entity you want to have included
- in the index with <literal>@Indexed</literal>. For more dedails see <xref
+ in the index with <literal>@Indexed</literal>. For more details see <xref
linkend="search-mapping-associated" />.</para>
<para>These settings should be sufficient for now. For more details on
@@ -408,10 +408,10 @@
<para>Hibernate Search will transparently index every entity persisted,
updated or removed through Hibernate Core. However, you have to trigger an
- inital indexing to populate the Lucene index with the data already present
+ initial indexing to populate the Lucene index with the data already present
in your database. Once you have added the above properties and annotations
it is time to trigger an initial batch index of your books. You can
- achieve this by using one of the following code snipplets (see also <xref
+ achieve this by using one of the following code snippets (see also <xref
linkend="search-batchindex" />):</para>
<example>
@@ -634,7 +634,7 @@
populated with the example code of this tutorial.</para>
<example>
- <title>Using the maven achetype to create tutorial sources</title>
+ <title>Using the Maven archetype to create tutorial sources</title>
<programlisting>mvn archetype:create \
-DarchetypeGroupId=org.hibernate \
Modified: search/branches/Branch_3_1/src/main/docbook/en-US/modules/lucene-native.xml
===================================================================
--- search/branches/Branch_3_1/src/main/docbook/en-US/modules/lucene-native.xml 2009-05-16 09:47:42 UTC (rev 16574)
+++ search/branches/Branch_3_1/src/main/docbook/en-US/modules/lucene-native.xml 2009-05-16 09:54:26 UTC (rev 16575)
@@ -81,7 +81,7 @@
citizen" rules.</para>
<example>
- <title>Accesing an <classname>IndexReader</classname></title>
+ <title>Accessing an <classname>IndexReader</classname></title>
<programlisting>DirectoryProvider orderProvider = searchFactory.getDirectoryProviders(Order.class)[0];
DirectoryProvider clientProvider = searchFactory.getDirectoryProviders(Client.class)[0];
@@ -129,7 +129,7 @@
<para>Lucene allows the user to customize its scoring formula by extending
<classname>org.apache.lucene.search.Similarity</classname>. The abstract
- methods defined in this class match the factors of the follownig formula
+ methods defined in this class match the factors of the following formula
calculating the score of query q for document d:</para>
<para><emphasis role="bold">score(q,d) = coord(q,d) · queryNorm(q) ·
@@ -205,7 +205,7 @@
<emphasis role="bold">@Similarity(impl = DummySimilarity.class)</emphasis>
public class Book {
...
-}</programlisting>As an exmaple, let's assume it is not important how often a
+}</programlisting>As an example, let's assume it is not important how often a
term appears in a document. Documents with a single occurrence of the term
should be scored the same as documents with multiple occurrences. In this
case your custom implementation of the method <methodname>tf(float
Modified: search/branches/Branch_3_1/src/main/docbook/en-US/modules/mapping.xml
===================================================================
--- search/branches/Branch_3_1/src/main/docbook/en-US/modules/mapping.xml 2009-05-16 09:47:42 UTC (rev 16574)
+++ search/branches/Branch_3_1/src/main/docbook/en-US/modules/mapping.xml 2009-05-16 09:54:26 UTC (rev 16575)
@@ -73,7 +73,7 @@
<para>For each property (or attribute) of your entity, you have the
ability to describe how it will be indexed. The default (no annotation
- present) means that the property is completly ignored by the indexing
+ present) means that the property is completely ignored by the indexing
process. <literal>@Field</literal> does declare a property as indexed.
When indexing an element to a Lucene document you can specify how it is
indexed:</para>
@@ -88,7 +88,7 @@
<listitem>
<para><literal>store</literal> : describe whether or not the
property is stored in the Lucene index. You can store the value
- <literal>Store.YES</literal> (comsuming more space in the index but
+ <literal>Store.YES</literal> (consuming more space in the index but
allowing projection, see <xref linkend="projections" /> for more
information), store it in a compressed way
<literal>Store.COMPRESS</literal> (this does consume more CPU), or
@@ -103,8 +103,8 @@
information store. The different values are
<literal>Index.NO</literal> (no indexing, ie cannot be found by a
query), <literal>Index.TOKENIZED</literal> (use an analyzer to
- process the property), <literal>Index.UN_TOKENISED</literal> (no
- analyzer pre processing), <literal>Index.NO_NORM</literal> (do not
+ process the property), <literal>Index.UN_TOKENIZED</literal> (no
+ analyzer pre-processing), <literal>Index.NO_NORMS</literal> (do not
store the normalization data). The default value is
<literal>TOKENIZED</literal>.</para>
</listitem>
@@ -162,7 +162,7 @@
<row>
<entry
- align="left">TermVector.WITH_POSITIONS_OFFSETS</entry>
+ align="left">TermVector.WITH_POSITION_OFFSETS</entry>
<entry>Store the term vector, token position and offset
information. This is a combination of the YES, WITH_OFFSETS
@@ -275,7 +275,7 @@
<title>Embedded and associated objects</title>
<para>Associated objects as well as embedded objects can be indexed as
- part of the root entity index. This is ueful if you expect to search a
+ part of the root entity index. This is useful if you expect to search a
given entity based on properties of associated objects. In the following
example the aim is to return places where the associated city is Atlanta
(In the Lucene query parser language, it would translate into
@@ -334,7 +334,7 @@
<classname>Address</classname> object to keep the index up to date. To
make sure the <literal><classname>Place</classname></literal> Lucene
document is updated when it's <classname>Address</classname> changes,
- you need to mark the other side of the birirectional relationship with
+ you need to mark the other side of the bidirectional relationship with
<classname>@ContainedIn</classname>.</para>
<para><literal>@ContainedIn</literal> is only useful on associations
@@ -417,7 +417,7 @@
</listitem>
<listitem>
- <para>addess.ownedBy_name</para>
+ <para>address.ownedBy_name</para>
</listitem>
</itemizedlist>
@@ -434,7 +434,7 @@
graph contains a cyclic dependency of classes (not instances). For
example, if <classname>Owner</classname> points to
<classname>Place</classname>. Hibernate Search will stop including
- Indexed embedded atttributes after reaching the expected depth (or the
+ Indexed embedded attributes after reaching the expected depth (or the
object graph boundaries are reached). A class having a self reference is
an example of cyclic dependency. In our example, because
<literal>depth</literal> is set to 1, any
@@ -519,7 +519,7 @@
<title>Boost factor</title>
<para>Lucene has the notion of <emphasis>boost factor</emphasis>. It's a
- way to give more weigth to a field or to an indexed element over others
+ way to give more weight to a field or to an indexed element over others
during the indexation process. You can use <literal>@Boost</literal> at
the @Field, method or class level.</para>
@@ -649,7 +649,7 @@
<para>This separation of tasks - a tokenizer followed by a list of
filters - allows for easy reuse of each individual component and let
you build your customized analyzer in a very flexible way (just like
- lego). Generally speaking the <classname>Tokenizer</classname> starts
+ Lego). Generally speaking the <classname>Tokenizer</classname> starts
the analysis process by turning the character input into tokens which
are then further processed by the <classname>TokenFilter</classname>s.
Hibernate Search supports this infrastructure by utilizing the Solr
@@ -661,7 +661,7 @@
depend on more libraries. For example, the
<classname>PhoneticFilterFactory</classname> depends on <ulink
url="http://commons.apache.org/codec">commons-codec</ulink>. Your
- distribution of Hibernate Search provides these dependecies in its
+ distribution of Hibernate Search provides these dependencies in its
<filename>lib</filename> directory.</para>
<example>
@@ -749,7 +749,7 @@
Let check a few of them.</para>
<table>
- <title>Some of the tokenizers avalable</title>
+ <title>Some of the available tokenizers</title>
<tgroup cols="3">
<thead>
@@ -784,7 +784,7 @@
</table>
<table>
- <title>Some of the filters avalable</title>
+ <title>Some of the available filters</title>
<tgroup cols="3">
<thead>
@@ -860,7 +860,7 @@
<title>Analyzer discriminator (experimental)</title>
<para>So far all the introduced ways to specify an analyzer were
- static. However, there are usecases where it is useful to select an
+ static. However, there are use cases where it is useful to select an
analyzer depending on the current state of the entity to be indexed,
for example in multilingual application. For an
<classname>BlogEntry</classname> class for example the analyzer could
@@ -947,7 +947,7 @@
interface has to return the name of an existing analyzer definition if
the analyzer should be set dynamically or <classname>null</classname>
if the default analyzer should not be overridden. The given example
- assumes that the language paramter is either 'de' or 'en' which
+ assumes that the language parameter is either 'de' or 'en' which
matches the specified names in the
<classname>@AnalyzerDef</classname>s.</para>
@@ -1076,7 +1076,7 @@
important is that when using a DateRange Query, you should know
that the dates have to be expressed in GMT time.</para>
- <para>Usually, storing the date up to the milisecond is not
+ <para>Usually, storing the date up to the millisecond is not
necessary. <literal>@DateBridge</literal> defines the appropriate
resolution you are willing to store in the index ( <literal>
<literal>@DateBridge(resolution=Resolution.DAY)</literal>
@@ -1213,8 +1213,8 @@
</example>
<para>The <classname>ParameterizedBridge</classname> interface can be
- implemented by <classname>StringBridge</classname> ,
- <classname>TwoWayStringBridge</classname> ,
+ implemented by <classname>StringBridge</classname>,
+ <classname>TwoWayStringBridge</classname>,
<classname>FieldBridge</classname> implementations.</para>
<para>All implementations have to be thread-safe, but the parameters
@@ -1276,13 +1276,13 @@
<section>
<title>FieldBridge</title>
- <para>Some usecases require more than a simple object to string
+ <para>Some use cases require more than a simple object to string
translation when mapping a property to a Lucene index. To give you the
greatest possible flexibility you can also implement a bridge as a
<classname>FieldBridge</classname>. This interface gives you a
property value and let you map it the way you want in your Lucene
<classname>Document</classname>.The interface is very similar in its
- concept to the Hibernate<classname> UserType</classname>'s.</para>
+ concept to the Hibernate<classname> UserType</classname>s.</para>
<para>You can for example store a given property in two different
document fields:</para>
Modified: search/branches/Branch_3_1/src/main/docbook/en-US/modules/optimize.xml
===================================================================
--- search/branches/Branch_3_1/src/main/docbook/en-US/modules/optimize.xml 2009-05-16 09:47:42 UTC (rev 16574)
+++ search/branches/Branch_3_1/src/main/docbook/en-US/modules/optimize.xml 2009-05-16 09:54:26 UTC (rev 16575)
@@ -35,7 +35,7 @@
During the optimization process the deletions will be applied which also
effects the number of files in the Lucene Directory.</para>
- <para>Optimising the Lucene index speeds up searches but has no effect on
+ <para>Optimizing the Lucene index speeds up searches but has no effect on
the indexation (update) performance. During an optimization, searches can be
performed, but will most likely be slowed down. All index updates will be
stopped. It is recommended to schedule optimization:</para>
@@ -61,7 +61,7 @@
</listitem>
<listitem>
- <para>or a certain amout of transactions </para>
+ <para>or a certain amount of transactions </para>
</listitem>
</itemizedlist>
@@ -129,7 +129,7 @@
<para>Apache Lucene has a few parameters to influence how optimization is
performed. Hibernate Search exposes those parameters.</para>
- <para>Further index optimisation parameters include: <itemizedlist>
+ <para>Further index optimization parameters include: <itemizedlist>
<listitem>
<literal>hibernate.search.[default|<indexname>].indexwriter.[batch|transaction].max_buffered_docs</literal>
</listitem>
Modified: search/branches/Branch_3_1/src/main/docbook/en-US/modules/query.xml
===================================================================
--- search/branches/Branch_3_1/src/main/docbook/en-US/modules/query.xml 2009-05-16 09:47:42 UTC (rev 16574)
+++ search/branches/Branch_3_1/src/main/docbook/en-US/modules/query.xml 2009-05-16 09:54:26 UTC (rev 16575)
@@ -58,7 +58,7 @@
</itemizedlist>
<para>To access the querying facilities, you have to use an
- <classname>FullTextSession</classname> . This Search specfic session wraps a
+ <classname>FullTextSession</classname>. This Search specific session wraps a
regular <classname>org.hibernate.Session</classname> to provide query and
indexing capabilities.</para>
@@ -179,7 +179,7 @@
<section>
<title>Pagination</title>
- <para>Out of performace reasons it is recommended to restrict the
+ <para>Out of performance reasons it is recommended to restrict the
number of returned objects per query. In fact is a very common use
case anyway that the user navigates from one page to an other. The way
to define pagination is exactly the way you would define pagination in
@@ -313,8 +313,8 @@
</listitem>
</itemizedlist>
- <para>Projection is useful for another kind of usecases. Lucene
- provides some metadata informations to the user about the results. By
+ <para>Projection is useful for another kind of use cases. Lucene
+ provides some metadata information to the user about the results. By
using some special placeholders, the projection mechanism can retrieve
them:</para>
@@ -335,7 +335,7 @@
<itemizedlist>
<listitem>
- <para>FullTextQuery.THIS: returns the intialized and managed
+ <para>FullTextQuery.THIS: returns the initialized and managed
entity (as a non projected query would have done).</para>
</listitem>
@@ -346,7 +346,7 @@
<listitem>
<para>FullTextQuery.OBJECT_CLASS: returns the class of the
- indexded entity.</para>
+ indexed entity.</para>
</listitem>
<listitem>
@@ -471,7 +471,7 @@
the targeted data structure:</para>
<example>
- <title>Using ResultTransformer in conjuncton with projections</title>
+ <title>Using ResultTransformer in conjunction with projections</title>
<programlisting>org.hibernate.search.FullTextQuery query = s.createFullTextQuery( luceneQuery, Book.class );
query.setProjection( "title", "mainAuthor.name" );
@@ -551,7 +551,7 @@
<para>Apache Lucene has a powerful feature that allows to filter query
results according to a custom filtering process. This is a very powerful
way to apply additional data restrictions, especially since filters can be
- cached and reused. Some interesting usecases are:</para>
+ cached and reused. Some interesting use cases are:</para>
<itemizedlist>
<listitem>
@@ -674,7 +674,7 @@
filter or filter factory of the targeted named filter definition.</para>
<example>
- <title>Using paramters in the actual filter implementation</title>
+ <title>Using parameters in the actual filter implementation</title>
<programlisting>public class SecurityFilterFactory {
private Integer level;
@@ -704,7 +704,7 @@
<para>Note the method annotated <classname>@Key</classname> returning a
<classname>FilterKey</classname> object. The returned object has a special
contract: the key object must implement <methodname>equals()</methodname>
- / <methodname>hashcode()</methodname> so that 2 keys are equal if and only
+ / <methodname>hashCode()</methodname> so that 2 keys are equal if and only
if the given <classname>Filter</classname> types are the same and the set
of parameters are the same. In other words, 2 filter keys are equal if and
only if the filters from which the keys are generated can be interchanged.
@@ -725,7 +725,7 @@
<para>In most cases, using the <literal>StandardFilterKey</literal>
implementation will be good enough. It delegates the
- <methodname>equals()</methodname> / <methodname>hashcode()</methodname>
+ <methodname>equals()</methodname> / <methodname>hashCode()</methodname>
implementation to each of the parameters equals and hashcode
methods.</para>
@@ -734,11 +734,11 @@
of memory when needed. The hard reference cache keeps track of the most
recently used filters and transforms the ones least used to
<classname>SoftReferences</classname> when needed. Once the limit of the
- hard reference cache is reached addtional filters are cached as
+ hard reference cache is reached additional filters are cached as
<classname>SoftReferences</classname>. To adjust the size of the hard
reference cache, use
<literal>hibernate.search.filter.cache_strategy.size</literal> (defaults
- to 128). For advance use of filter caching, you can implement your own
+ to 128). For advanced use of filter caching, you can implement your own
<classname>FilterCachingStrategy</classname>. The classname is defined by
<literal>hibernate.search.filter.cache_strategy</literal>.</para>
@@ -769,12 +769,12 @@
(<classname>org.hibernate.search.filter.CachingWrapperFilter</classname>).
In contrast to Lucene's version of this class
<classname>SoftReference</classname>s are used together with a hard
- reference count (see dicussion about filter cache). The hard reference
+ reference count (see discussion about filter cache). The hard reference
count can be adjusted using
<literal>hibernate.search.filter.cache_docidresults.size</literal>
(defaults to 5). The wrapping behaviour can be controlled using the
<literal>@FullTextFilterDef.cache</literal> parameter. There are three
- differerent values for this parameter:</para>
+ different values for this parameter:</para>
<para><informaltable align="left" width="">
<tgroup cols="2">
@@ -866,6 +866,6 @@
<para>If you wish to use some specific features of Lucene, you can always
run Lucene specific queries. Check <xref linkend="search-lucene-native" />
- for more informations.</para>
+ for more information.</para>
</section>
</chapter>
15 years, 6 months
Hibernate SVN: r16574 - in search/branches/Branch_3_1: src/main/java/org/hibernate/search and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2009-05-16 05:47:42 -0400 (Sat, 16 May 2009)
New Revision: 16574
Modified:
search/branches/Branch_3_1/pom.xml
search/branches/Branch_3_1/src/main/java/org/hibernate/search/Version.java
Log:
Fixing version number of branch 3.1 to 3.1.1-SNAPSHOT (Was 3.2)
Modified: search/branches/Branch_3_1/pom.xml
===================================================================
--- search/branches/Branch_3_1/pom.xml 2009-05-16 09:36:56 UTC (rev 16573)
+++ search/branches/Branch_3_1/pom.xml 2009-05-16 09:47:42 UTC (rev 16574)
@@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search</artifactId>
- <version>3.2.0-SNAPSHOT</version>
+ <version>3.1.1-SNAPSHOT</version>
<name>Hibernate Search</name>
<description>Hibernate Search</description>
<url>http://search.hibernate.org</url>
Modified: search/branches/Branch_3_1/src/main/java/org/hibernate/search/Version.java
===================================================================
--- search/branches/Branch_3_1/src/main/java/org/hibernate/search/Version.java 2009-05-16 09:36:56 UTC (rev 16573)
+++ search/branches/Branch_3_1/src/main/java/org/hibernate/search/Version.java 2009-05-16 09:47:42 UTC (rev 16574)
@@ -1,25 +1,20 @@
//$Id$
package org.hibernate.search;
-import java.util.Date;
-
-import org.slf4j.Logger;
-
import org.hibernate.search.util.LoggerFactory;
-
/**
* @author Emmanuel Bernard
*/
public class Version {
- public static final String VERSION = "3.1.0.GA";
+
+ public static final String VERSION = "3.1.1-SNAPSHOT";
- private static final Logger log = LoggerFactory.make();
-
static {
- log.info( "Hibernate Search {}", VERSION );
+ LoggerFactory.make().info( "Hibernate Search {}", VERSION );
}
public static void touch() {
}
+
}
15 years, 6 months
Hibernate SVN: r16573 - search/trunk/src/main/docbook/en-US/modules.
by hibernate-commits@lists.jboss.org
Author: sannegrinovero
Date: 2009-05-16 05:36:56 -0400 (Sat, 16 May 2009)
New Revision: 16573
Modified:
search/trunk/src/main/docbook/en-US/modules/architecture.xml
search/trunk/src/main/docbook/en-US/modules/configuration.xml
search/trunk/src/main/docbook/en-US/modules/getting-started.xml
search/trunk/src/main/docbook/en-US/modules/lucene-native.xml
search/trunk/src/main/docbook/en-US/modules/mapping.xml
search/trunk/src/main/docbook/en-US/modules/optimize.xml
search/trunk/src/main/docbook/en-US/modules/query.xml
Log:
HSEARCH-369 Running a spellchecker on documentation
Modified: search/trunk/src/main/docbook/en-US/modules/architecture.xml
===================================================================
--- search/trunk/src/main/docbook/en-US/modules/architecture.xml 2009-05-15 15:21:57 UTC (rev 16572)
+++ search/trunk/src/main/docbook/en-US/modules/architecture.xml 2009-05-16 09:36:56 UTC (rev 16573)
@@ -219,7 +219,7 @@
<title>Reader strategy</title>
<para>When executing a query, Hibernate Search interacts with the Apache
- Lucene indexes through a reader strategy. chosing a reader strategy will
+ Lucene indexes through a reader strategy. Choosing a reader strategy will
depend on the profile of the application (frequent updates, read mostly,
asynchronous index update etc). See also <xref
linkend="configuration-reader-strategy" /></para>
Modified: search/trunk/src/main/docbook/en-US/modules/configuration.xml
===================================================================
--- search/trunk/src/main/docbook/en-US/modules/configuration.xml 2009-05-15 15:21:57 UTC (rev 16572)
+++ search/trunk/src/main/docbook/en-US/modules/configuration.xml 2009-05-16 09:36:56 UTC (rev 16573)
@@ -321,8 +321,8 @@
“Animal”. Both entities will then be stored in the Animal
directory</para>
- <para><programlisting><code>hibernate.search.org.hibernate.search.test.shards.Furniture.indexName = Aninal
-hibernate.search.org.hibernate.search.test.shards.Animal.indexName = Aninal</code></programlisting></para>
+ <para><programlisting><code>hibernate.search.org.hibernate.search.test.shards.Furniture.indexName = Animal
+hibernate.search.org.hibernate.search.test.shards.Animal.indexName = Animal</code></programlisting></para>
</listitem>
<listitem>
@@ -373,7 +373,7 @@
<row>
<entry><literal>hibernate.search.worker.execution</literal></entry>
- <entry>Supports synchronous and asynchrounous execution. Default
+ <entry>Supports synchronous and asynchronous execution. Default
to <literal><literal>sync</literal></literal>. Supports also
<literal>async</literal>.</entry>
</row>
@@ -382,14 +382,14 @@
<entry><literal>hibernate.search.worker.thread_pool.size</literal></entry>
<entry>Defines the number of threads in the pool. useful only for
- asynchrounous execution. Default to 1.</entry>
+ asynchronous execution. Default to 1.</entry>
</row>
<row>
<entry><literal>hibernate.search.worker.buffer_queue.max</literal></entry>
<entry>Defines the maximal number of work queue if the thread poll
- is starved. Useful only for asynchrounous execution. Default to
+ is starved. Useful only for asynchronous execution. Default to
infinite. If the limit is reached, the work is done by the main
thread.</entry>
</row>
@@ -445,7 +445,7 @@
<section>
<title>Slave nodes</title>
- <para>Every index update operation is sent to a JMS queue. Index quering
+ <para>Every index update operation is sent to a JMS queue. Index querying
operations are executed on a local index copy.</para>
<example>
@@ -768,7 +768,7 @@
terms.</para> <para>This silently truncates large documents,
excluding from the index all terms that occur further in the
document. If you know your source documents are large, be sure to
- set this value high enough to accomodate the expected size. If you
+ set this value high enough to accommodate the expected size. If you
set it to Integer.MAX_VALUE, then the only limit is your memory,
but you should anticipate an OutOfMemoryError. </para> <para>If
setting this value in <literal>batch</literal> differently than in
@@ -794,13 +794,13 @@
<entry><literal>hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].merge_factor</literal></entry>
<entry><para>Controls segment merge frequency and size. </para>
- <para>Determines how often segment indices are merged when
+ <para>Determines how often segment indexes are merged when
insertion occurs. With smaller values, less RAM is used while
- indexing, and searches on unoptimized indices are faster, but
+ indexing, and searches on unoptimized indexes are faster, but
indexing speed is slower. With larger values, more RAM is used
- during indexing, and while searches on unoptimized indices are
+ during indexing, and while searches on unoptimized indexes are
slower, indexing is faster. Thus larger values (> 10) are best
- for batch index creation, and smaller values (< 10) for indices
+ for batch index creation, and smaller values (< 10) for indexes
that are interactively maintained. The value must no be lower than
2.</para></entry>
Modified: search/trunk/src/main/docbook/en-US/modules/getting-started.xml
===================================================================
--- search/trunk/src/main/docbook/en-US/modules/getting-started.xml 2009-05-15 15:21:57 UTC (rev 16572)
+++ search/trunk/src/main/docbook/en-US/modules/getting-started.xml 2009-05-16 09:36:56 UTC (rev 16573)
@@ -160,7 +160,7 @@
</example>
<para>Not all dependencies are required. Only the
- <emphasis>hibernate-search</emphasis> dependeny is mandatory. This
+ <emphasis>hibernate-search</emphasis> dependency is mandatory. This
dependency, together with its required transitive dependencies, contain
all required classes needed to use Hibernate Search.
<emphasis>hibernate-annotations</emphasis> is only needed if you want to
@@ -173,7 +173,7 @@
use Hibernate Search in conjunction with JPA. The Solr dependencies are
needed if you want to utilize Solr's analyzer framework. More about this
later. And finally, the <literal>lucene-snowball</literal> dependency is
- needed if you want to utililze Lucene's snowball stemmer.</para>
+ needed if you want to use Lucene's snowball stemmer.</para>
</section>
<section>
@@ -230,7 +230,7 @@
<example>
<title>Example entities Book and Author before adding Hibernate Search
- specific annotatons</title>
+ specific annotations</title>
<programlisting>
package example;
@@ -336,7 +336,7 @@
searchable you have to make sure that the names are indexed as part of the
book itself. On top of <literal>@IndexedEmbedded</literal> you will also
have to mark all fields of the associated entity you want to have included
- in the index with <literal>@Indexed</literal>. For more dedails see <xref
+ in the index with <literal>@Indexed</literal>. For more details see <xref
linkend="search-mapping-associated" />.</para>
<para>These settings should be sufficient for now. For more details on
@@ -408,10 +408,10 @@
<para>Hibernate Search will transparently index every entity persisted,
updated or removed through Hibernate Core. However, you have to trigger an
- inital indexing to populate the Lucene index with the data already present
+ initial indexing to populate the Lucene index with the data already present
in your database. Once you have added the above properties and annotations
it is time to trigger an initial batch index of your books. You can
- achieve this by using one of the following code snipplets (see also <xref
+ achieve this by using one of the following code snippets (see also <xref
linkend="search-batchindex" />):</para>
<example>
@@ -634,7 +634,7 @@
populated with the example code of this tutorial.</para>
<example>
- <title>Using the maven achetype to create tutorial sources</title>
+ <title>Using the Maven archetype to create tutorial sources</title>
<programlisting>mvn archetype:create \
-DarchetypeGroupId=org.hibernate \
Modified: search/trunk/src/main/docbook/en-US/modules/lucene-native.xml
===================================================================
--- search/trunk/src/main/docbook/en-US/modules/lucene-native.xml 2009-05-15 15:21:57 UTC (rev 16572)
+++ search/trunk/src/main/docbook/en-US/modules/lucene-native.xml 2009-05-16 09:36:56 UTC (rev 16573)
@@ -81,7 +81,7 @@
citizen" rules.</para>
<example>
- <title>Accesing an <classname>IndexReader</classname></title>
+ <title>Accessing an <classname>IndexReader</classname></title>
<programlisting>DirectoryProvider orderProvider = searchFactory.getDirectoryProviders(Order.class)[0];
DirectoryProvider clientProvider = searchFactory.getDirectoryProviders(Client.class)[0];
@@ -129,7 +129,7 @@
<para>Lucene allows the user to customize its scoring formula by extending
<classname>org.apache.lucene.search.Similarity</classname>. The abstract
- methods defined in this class match the factors of the follownig formula
+ methods defined in this class match the factors of the following formula
calculating the score of query q for document d:</para>
<para><emphasis role="bold">score(q,d) = coord(q,d) · queryNorm(q) ·
@@ -205,7 +205,7 @@
<emphasis role="bold">@Similarity(impl = DummySimilarity.class)</emphasis>
public class Book {
...
-}</programlisting>As an exmaple, let's assume it is not important how often a
+}</programlisting>As an example, let's assume it is not important how often a
term appears in a document. Documents with a single occurrence of the term
should be scored the same as documents with multiple occurrences. In this
case your custom implementation of the method <methodname>tf(float
Modified: search/trunk/src/main/docbook/en-US/modules/mapping.xml
===================================================================
--- search/trunk/src/main/docbook/en-US/modules/mapping.xml 2009-05-15 15:21:57 UTC (rev 16572)
+++ search/trunk/src/main/docbook/en-US/modules/mapping.xml 2009-05-16 09:36:56 UTC (rev 16573)
@@ -73,7 +73,7 @@
<para>For each property (or attribute) of your entity, you have the
ability to describe how it will be indexed. The default (no annotation
- present) means that the property is completly ignored by the indexing
+ present) means that the property is completely ignored by the indexing
process. <literal>@Field</literal> does declare a property as indexed.
When indexing an element to a Lucene document you can specify how it is
indexed:</para>
@@ -88,7 +88,7 @@
<listitem>
<para><literal>store</literal> : describe whether or not the
property is stored in the Lucene index. You can store the value
- <literal>Store.YES</literal> (comsuming more space in the index but
+ <literal>Store.YES</literal> (consuming more space in the index but
allowing projection, see <xref linkend="projections" /> for more
information), store it in a compressed way
<literal>Store.COMPRESS</literal> (this does consume more CPU), or
@@ -103,8 +103,8 @@
information store. The different values are
<literal>Index.NO</literal> (no indexing, ie cannot be found by a
query), <literal>Index.TOKENIZED</literal> (use an analyzer to
- process the property), <literal>Index.UN_TOKENISED</literal> (no
- analyzer pre processing), <literal>Index.NO_NORM</literal> (do not
+ process the property), <literal>Index.UN_TOKENIZED</literal> (no
+ analyzer pre-processing), <literal>Index.NO_NORMS</literal> (do not
store the normalization data). The default value is
<literal>TOKENIZED</literal>.</para>
</listitem>
@@ -162,7 +162,7 @@
<row>
<entry
- align="left">TermVector.WITH_POSITIONS_OFFSETS</entry>
+ align="left">TermVector.WITH_POSITION_OFFSETS</entry>
<entry>Store the term vector, token position and offset
information. This is a combination of the YES, WITH_OFFSETS
@@ -275,7 +275,7 @@
<title>Embedded and associated objects</title>
<para>Associated objects as well as embedded objects can be indexed as
- part of the root entity index. This is ueful if you expect to search a
+ part of the root entity index. This is useful if you expect to search a
given entity based on properties of associated objects. In the following
example the aim is to return places where the associated city is Atlanta
(In the Lucene query parser language, it would translate into
@@ -334,7 +334,7 @@
<classname>Address</classname> object to keep the index up to date. To
make sure the <literal><classname>Place</classname></literal> Lucene
document is updated when it's <classname>Address</classname> changes,
- you need to mark the other side of the birirectional relationship with
+ you need to mark the other side of the bidirectional relationship with
<classname>@ContainedIn</classname>.</para>
<para><literal>@ContainedIn</literal> is only useful on associations
@@ -417,7 +417,7 @@
</listitem>
<listitem>
- <para>addess.ownedBy_name</para>
+ <para>address.ownedBy_name</para>
</listitem>
</itemizedlist>
@@ -434,7 +434,7 @@
graph contains a cyclic dependency of classes (not instances). For
example, if <classname>Owner</classname> points to
<classname>Place</classname>. Hibernate Search will stop including
- Indexed embedded atttributes after reaching the expected depth (or the
+ Indexed embedded attributes after reaching the expected depth (or the
object graph boundaries are reached). A class having a self reference is
an example of cyclic dependency. In our example, because
<literal>depth</literal> is set to 1, any
@@ -519,7 +519,7 @@
<title>Boost factor</title>
<para>Lucene has the notion of <emphasis>boost factor</emphasis>. It's a
- way to give more weigth to a field or to an indexed element over others
+ way to give more weight to a field or to an indexed element over others
during the indexation process. You can use <literal>@Boost</literal> at
the @Field, method or class level.</para>
@@ -649,7 +649,7 @@
<para>This separation of tasks - a tokenizer followed by a list of
filters - allows for easy reuse of each individual component and let
you build your customized analyzer in a very flexible way (just like
- lego). Generally speaking the <classname>Tokenizer</classname> starts
+ Lego). Generally speaking the <classname>Tokenizer</classname> starts
the analysis process by turning the character input into tokens which
are then further processed by the <classname>TokenFilter</classname>s.
Hibernate Search supports this infrastructure by utilizing the Solr
@@ -661,7 +661,7 @@
depend on more libraries. For example, the
<classname>PhoneticFilterFactory</classname> depends on <ulink
url="http://commons.apache.org/codec">commons-codec</ulink>. Your
- distribution of Hibernate Search provides these dependecies in its
+ distribution of Hibernate Search provides these dependencies in its
<filename>lib</filename> directory.</para>
<example>
@@ -749,7 +749,7 @@
Let check a few of them.</para>
<table>
- <title>Some of the tokenizers avalable</title>
+ <title>Some of the available tokenizers</title>
<tgroup cols="3">
<thead>
@@ -784,7 +784,7 @@
</table>
<table>
- <title>Some of the filters avalable</title>
+ <title>Some of the available filters</title>
<tgroup cols="3">
<thead>
@@ -860,7 +860,7 @@
<title>Analyzer discriminator (experimental)</title>
<para>So far all the introduced ways to specify an analyzer were
- static. However, there are usecases where it is useful to select an
+ static. However, there are use cases where it is useful to select an
analyzer depending on the current state of the entity to be indexed,
for example in multilingual application. For an
<classname>BlogEntry</classname> class for example the analyzer could
@@ -947,7 +947,7 @@
interface has to return the name of an existing analyzer definition if
the analyzer should be set dynamically or <classname>null</classname>
if the default analyzer should not be overridden. The given example
- assumes that the language paramter is either 'de' or 'en' which
+ assumes that the language parameter is either 'de' or 'en' which
matches the specified names in the
<classname>@AnalyzerDef</classname>s.</para>
@@ -1076,7 +1076,7 @@
important is that when using a DateRange Query, you should know
that the dates have to be expressed in GMT time.</para>
- <para>Usually, storing the date up to the milisecond is not
+ <para>Usually, storing the date up to the millisecond is not
necessary. <literal>@DateBridge</literal> defines the appropriate
resolution you are willing to store in the index ( <literal>
<literal>@DateBridge(resolution=Resolution.DAY)</literal>
@@ -1213,8 +1213,8 @@
</example>
<para>The <classname>ParameterizedBridge</classname> interface can be
- implemented by <classname>StringBridge</classname> ,
- <classname>TwoWayStringBridge</classname> ,
+ implemented by <classname>StringBridge</classname>,
+ <classname>TwoWayStringBridge</classname>,
<classname>FieldBridge</classname> implementations.</para>
<para>All implementations have to be thread-safe, but the parameters
@@ -1276,13 +1276,13 @@
<section>
<title>FieldBridge</title>
- <para>Some usecases require more than a simple object to string
+ <para>Some use cases require more than a simple object to string
translation when mapping a property to a Lucene index. To give you the
greatest possible flexibility you can also implement a bridge as a
<classname>FieldBridge</classname>. This interface gives you a
property value and let you map it the way you want in your Lucene
<classname>Document</classname>.The interface is very similar in its
- concept to the Hibernate<classname> UserType</classname>'s.</para>
+ concept to the Hibernate<classname> UserType</classname>s.</para>
<para>You can for example store a given property in two different
document fields:</para>
Modified: search/trunk/src/main/docbook/en-US/modules/optimize.xml
===================================================================
--- search/trunk/src/main/docbook/en-US/modules/optimize.xml 2009-05-15 15:21:57 UTC (rev 16572)
+++ search/trunk/src/main/docbook/en-US/modules/optimize.xml 2009-05-16 09:36:56 UTC (rev 16573)
@@ -35,7 +35,7 @@
During the optimization process the deletions will be applied which also
effects the number of files in the Lucene Directory.</para>
- <para>Optimising the Lucene index speeds up searches but has no effect on
+ <para>Optimizing the Lucene index speeds up searches but has no effect on
the indexation (update) performance. During an optimization, searches can be
performed, but will most likely be slowed down. All index updates will be
stopped. It is recommended to schedule optimization:</para>
@@ -61,7 +61,7 @@
</listitem>
<listitem>
- <para>or a certain amout of transactions </para>
+ <para>or a certain amount of transactions </para>
</listitem>
</itemizedlist>
@@ -129,7 +129,7 @@
<para>Apache Lucene has a few parameters to influence how optimization is
performed. Hibernate Search exposes those parameters.</para>
- <para>Further index optimisation parameters include: <itemizedlist>
+ <para>Further index optimization parameters include: <itemizedlist>
<listitem>
<literal>hibernate.search.[default|<indexname>].indexwriter.[batch|transaction].max_buffered_docs</literal>
</listitem>
Modified: search/trunk/src/main/docbook/en-US/modules/query.xml
===================================================================
--- search/trunk/src/main/docbook/en-US/modules/query.xml 2009-05-15 15:21:57 UTC (rev 16572)
+++ search/trunk/src/main/docbook/en-US/modules/query.xml 2009-05-16 09:36:56 UTC (rev 16573)
@@ -58,7 +58,7 @@
</itemizedlist>
<para>To access the querying facilities, you have to use an
- <classname>FullTextSession</classname> . This Search specfic session wraps a
+ <classname>FullTextSession</classname>. This Search specific session wraps a
regular <classname>org.hibernate.Session</classname> to provide query and
indexing capabilities.</para>
@@ -179,7 +179,7 @@
<section>
<title>Pagination</title>
- <para>Out of performace reasons it is recommended to restrict the
+ <para>Out of performance reasons it is recommended to restrict the
number of returned objects per query. In fact is a very common use
case anyway that the user navigates from one page to an other. The way
to define pagination is exactly the way you would define pagination in
@@ -313,8 +313,8 @@
</listitem>
</itemizedlist>
- <para>Projection is useful for another kind of usecases. Lucene
- provides some metadata informations to the user about the results. By
+ <para>Projection is useful for another kind of use cases. Lucene
+ provides some metadata information to the user about the results. By
using some special placeholders, the projection mechanism can retrieve
them:</para>
@@ -335,7 +335,7 @@
<itemizedlist>
<listitem>
- <para>FullTextQuery.THIS: returns the intialized and managed
+ <para>FullTextQuery.THIS: returns the initialized and managed
entity (as a non projected query would have done).</para>
</listitem>
@@ -346,7 +346,7 @@
<listitem>
<para>FullTextQuery.OBJECT_CLASS: returns the class of the
- indexded entity.</para>
+ indexed entity.</para>
</listitem>
<listitem>
@@ -471,7 +471,7 @@
the targeted data structure:</para>
<example>
- <title>Using ResultTransformer in conjuncton with projections</title>
+ <title>Using ResultTransformer in conjunction with projections</title>
<programlisting>org.hibernate.search.FullTextQuery query = s.createFullTextQuery( luceneQuery, Book.class );
query.setProjection( "title", "mainAuthor.name" );
@@ -551,7 +551,7 @@
<para>Apache Lucene has a powerful feature that allows to filter query
results according to a custom filtering process. This is a very powerful
way to apply additional data restrictions, especially since filters can be
- cached and reused. Some interesting usecases are:</para>
+ cached and reused. Some interesting use cases are:</para>
<itemizedlist>
<listitem>
@@ -674,7 +674,7 @@
filter or filter factory of the targeted named filter definition.</para>
<example>
- <title>Using paramters in the actual filter implementation</title>
+ <title>Using parameters in the actual filter implementation</title>
<programlisting>public class SecurityFilterFactory {
private Integer level;
@@ -704,7 +704,7 @@
<para>Note the method annotated <classname>@Key</classname> returning a
<classname>FilterKey</classname> object. The returned object has a special
contract: the key object must implement <methodname>equals()</methodname>
- / <methodname>hashcode()</methodname> so that 2 keys are equal if and only
+ / <methodname>hashCode()</methodname> so that 2 keys are equal if and only
if the given <classname>Filter</classname> types are the same and the set
of parameters are the same. In other words, 2 filter keys are equal if and
only if the filters from which the keys are generated can be interchanged.
@@ -725,7 +725,7 @@
<para>In most cases, using the <literal>StandardFilterKey</literal>
implementation will be good enough. It delegates the
- <methodname>equals()</methodname> / <methodname>hashcode()</methodname>
+ <methodname>equals()</methodname> / <methodname>hashCode()</methodname>
implementation to each of the parameters equals and hashcode
methods.</para>
@@ -734,11 +734,11 @@
of memory when needed. The hard reference cache keeps track of the most
recently used filters and transforms the ones least used to
<classname>SoftReferences</classname> when needed. Once the limit of the
- hard reference cache is reached addtional filters are cached as
+ hard reference cache is reached additional filters are cached as
<classname>SoftReferences</classname>. To adjust the size of the hard
reference cache, use
<literal>hibernate.search.filter.cache_strategy.size</literal> (defaults
- to 128). For advance use of filter caching, you can implement your own
+ to 128). For advanced use of filter caching, you can implement your own
<classname>FilterCachingStrategy</classname>. The classname is defined by
<literal>hibernate.search.filter.cache_strategy</literal>.</para>
@@ -769,12 +769,12 @@
(<classname>org.hibernate.search.filter.CachingWrapperFilter</classname>).
In contrast to Lucene's version of this class
<classname>SoftReference</classname>s are used together with a hard
- reference count (see dicussion about filter cache). The hard reference
+ reference count (see discussion about filter cache). The hard reference
count can be adjusted using
<literal>hibernate.search.filter.cache_docidresults.size</literal>
(defaults to 5). The wrapping behaviour can be controlled using the
<literal>@FullTextFilterDef.cache</literal> parameter. There are three
- differerent values for this parameter:</para>
+ different values for this parameter:</para>
<para><informaltable align="left" width="">
<tgroup cols="2">
@@ -864,6 +864,6 @@
<para>If you wish to use some specific features of Lucene, you can always
run Lucene specific queries. Check <xref linkend="search-lucene-native" />
- for more informations.</para>
+ for more information.</para>
</section>
</chapter>
15 years, 6 months
Hibernate SVN: r16572 - search/branches/Branch_3_1/src/test/java/org/hibernate/search/test/util.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-05-15 11:21:57 -0400 (Fri, 15 May 2009)
New Revision: 16572
Modified:
search/branches/Branch_3_1/src/test/java/org/hibernate/search/test/util/FullTextSessionBuilder.java
Log:
Removed hardy dependency to HSQLDB
Modified: search/branches/Branch_3_1/src/test/java/org/hibernate/search/test/util/FullTextSessionBuilder.java
===================================================================
--- search/branches/Branch_3_1/src/test/java/org/hibernate/search/test/util/FullTextSessionBuilder.java 2009-05-15 15:17:35 UTC (rev 16571)
+++ search/branches/Branch_3_1/src/test/java/org/hibernate/search/test/util/FullTextSessionBuilder.java 2009-05-15 15:21:57 UTC (rev 16572)
@@ -1,4 +1,4 @@
-//$Id
+// $Id$
package org.hibernate.search.test.util;
import org.apache.lucene.analysis.StopAnalyzer;
@@ -16,38 +16,24 @@
* which need to use several differently configured SessionFactories.
*
* @author Sanne Grinovero
+ * @author Hardy Ferentschik
*/
public class FullTextSessionBuilder {
- private AnnotationConfiguration cfg = new AnnotationConfiguration();
+ private AnnotationConfiguration cfg;
private SessionFactory sessionFactory;
private Session session;
public FullTextSessionBuilder() {
+ cfg = new AnnotationConfiguration();
cfg.setProperty( Environment.HBM2DDL_AUTO, "create-drop" );
- //DB type:
- cfg.setProperty( Environment.URL, "jdbc:hsqldb:mem:." );
- cfg.setProperty( Environment.DRIVER,
- org.hsqldb.jdbcDriver.class.getCanonicalName() );
- cfg.setProperty( Environment.DIALECT,
- org.hibernate.dialect.HSQLDialect.class.getCanonicalName() );
- //connection:
- cfg.setProperty( Environment.USER, "sa" );
- cfg.setProperty( Environment.PASS, "" );
- cfg.setProperty( Environment.ISOLATION, "2" );
- cfg.setProperty( Environment.POOL_SIZE, "1" );
- cfg.setProperty( Environment.ORDER_UPDATES, "true" );
+
//cache:
cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "true" );
cfg.setProperty( Environment.CACHE_PROVIDER,
org.hibernate.cache.HashtableCacheProvider.class.getCanonicalName() );
cfg.setProperty( Environment.USE_QUERY_CACHE, "true" );
- //debugging/logging:
- cfg.setProperty( Environment.SHOW_SQL, "false" );
- cfg.setProperty( Environment.USE_SQL_COMMENTS, "true" );
- cfg.setProperty( Environment.FORMAT_SQL, "true" );
- cfg.setProperty( Environment.USE_STRUCTURED_CACHE, "true" );
- cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
+
//search specific:
cfg.setProperty( org.hibernate.search.Environment.ANALYZER_CLASS,
StopAnalyzer.class.getName() );
@@ -57,9 +43,9 @@
/**
* Override before building any parameter, or add new ones.
- * @param key
- * @param value
- * @return the same builder (this)
+ * @param key Property name.
+ * @param value Property value.
+ * @return the same builder (this).
*/
public FullTextSessionBuilder setProperty(String key, String value) {
cfg.setProperty( key, value );
@@ -67,8 +53,8 @@
}
/**
- * Adds classes to the SessionFactory being built
- * @param annotatedClass
+ * Adds classes to the SessionFactory being built.
+ * @param annotatedClass The annotated class to add to the configuration.
* @return the same builder (this)
*/
public FullTextSessionBuilder addAnnotatedClass(Class annotatedClass) {
@@ -78,7 +64,7 @@
/**
* Creates a new FullTextSession based upon the configuration built so far.
- * @return
+ * @return new FullTextSession based upon the configuration built so far.
*/
public FullTextSession build() {
if ( session != null || sessionFactory != null ) {
@@ -101,5 +87,4 @@
sessionFactory.close();
sessionFactory = null;
}
-
}
15 years, 6 months