[hibernate-commits] Hibernate SVN: r20176 - in search/trunk/hibernate-search/src: main/java/org/hibernate/search/impl and 4 other directories.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Thu Aug 19 07:45:48 EDT 2010
Author: hardy.ferentschik
Date: 2010-08-19 07:45:48 -0400 (Thu, 19 Aug 2010)
New Revision: 20176
Modified:
search/trunk/hibernate-search/src/main/java/org/hibernate/search/Environment.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/SearchFactory.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/ImmutableSearchFactory.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MutableSearchFactory.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsImpl.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/FullTextQueryImpl.java
search/trunk/hibernate-search/src/main/java/org/hibernate/search/stat/Statistics.java
search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/batchindexing/IndexingGeneratedCorpusTest.java
Log:
HSEARCH-278 Introduced a Statistics interface and implementation. Also exposed it via JMX
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/Environment.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/Environment.java 2010-08-19 11:44:21 UTC (rev 20175)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/Environment.java 2010-08-19 11:45:48 UTC (rev 20176)
@@ -121,9 +121,13 @@
public static final String ERROR_HANDLER = "hibernate.search.error_handler";
/**
- * If set to {@code true} the JMX Statistics bean gets enabled. For all other values the bean does not
+ * If set to {@code true} JMX beans get enabled. For all other values the beans do not.
* get enabled.
*/
public static final String JMX_ENABLED = "hibernate.search.jmx_enabled";
+ /**
+ * If set to {@code true} the search statistic will be gathered.
+ */
+ public static final String GENERATE_STATS = "hibernate.search.generate_statistics";
}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/SearchFactory.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/SearchFactory.java 2010-08-19 11:44:21 UTC (rev 20175)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/SearchFactory.java 2010-08-19 11:45:48 UTC (rev 20176)
@@ -28,10 +28,12 @@
import org.hibernate.search.query.dsl.v2.QueryContextBuilder;
import org.hibernate.search.reader.ReaderProvider;
+import org.hibernate.search.stat.Statistics;
import org.hibernate.search.store.DirectoryProvider;
/**
* Provide application wide operations as well as access to the underlying Lucene resources.
+ *
* @author Emmanuel Bernard
*/
public interface SearchFactory {
@@ -63,18 +65,20 @@
/**
* Experimental API
* retrieve an analyzer instance by its definition name
- *
+ *
* @throws SearchException if the definition name is unknown
*/
Analyzer getAnalyzer(String name);
-
+
/**
* Retrieves the scoped analyzer for a given class.
- *
+ *
* @param clazz The class for which to retrieve the analyzer.
+ *
* @return The scoped analyzer for the specified class.
+ *
* @throws IllegalArgumentException in case <code>clazz == null</code> or the specified
- * class is not an indexed entity.
+ * class is not an indexed entity.
*/
Analyzer getAnalyzer(Class<?> clazz);
@@ -82,4 +86,11 @@
* Return a query builder providing a fluent API to create Lucene queries
*/
QueryContextBuilder buildQueryBuilder();
+
+ /**
+ * Retrieve the statistics for this factory.
+ *
+ * @return The statistics.
+ */
+ public Statistics getStatistics();
}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/ImmutableSearchFactory.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/ImmutableSearchFactory.java 2010-08-19 11:44:21 UTC (rev 20175)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/ImmutableSearchFactory.java 2010-08-19 11:45:48 UTC (rev 20176)
@@ -56,6 +56,9 @@
import org.hibernate.search.engine.SearchFactoryImplementor;
import org.hibernate.search.exception.ErrorHandler;
import org.hibernate.search.filter.FilterCachingStrategy;
+import org.hibernate.search.jmx.JMXRegistrar;
+import org.hibernate.search.jmx.StatisticsImpl;
+import org.hibernate.search.jmx.StatisticsImplMBean;
import org.hibernate.search.query.dsl.v2.QueryContextBuilder;
import org.hibernate.search.query.dsl.v2.impl.ConnectedQueryContextBuilder;
import org.hibernate.search.reader.ReaderProvider;
@@ -63,6 +66,7 @@
import org.hibernate.search.spi.internals.DirectoryProviderData;
import org.hibernate.search.spi.internals.PolymorphicIndexHierarchy;
import org.hibernate.search.spi.internals.StateSearchFactoryImplementor;
+import org.hibernate.search.stat.Statistics;
import org.hibernate.search.store.DirectoryProvider;
import org.hibernate.search.store.optimization.OptimizerStrategy;
import org.hibernate.search.util.LoggerFactory;
@@ -97,6 +101,7 @@
private final Properties configurationProperties;
private final ErrorHandler errorHandler;
private final PolymorphicIndexHierarchy indexHierarchy;
+ private final Statistics statistics;
/**
* Each directory provider (index) can have its own performance settings.
@@ -120,6 +125,16 @@
this.indexingStrategy = cfg.indexingStrategy;
this.readerProvider = cfg.readerProvider;
this.worker = cfg.worker;
+ this.statistics = new StatisticsImpl();
+ String enableStats = configurationProperties.getProperty( Environment.JMX_ENABLED );
+ if ( "true".equalsIgnoreCase( enableStats ) ) {
+ statistics.setStatisticsEnabled( true );
+ }
+
+ String enableJMX = configurationProperties.getProperty( Environment.JMX_ENABLED );
+ if ( "true".equalsIgnoreCase( enableJMX ) ) {
+ JMXRegistrar.registerMBean( statistics, StatisticsImplMBean.STATISTICS_MBEAN_OBJECT_NAME );
+ }
}
public BackendQueueProcessorFactory getBackendQueueProcessorFactory() {
@@ -264,6 +279,10 @@
return new ConnectedQueryContextBuilder( this );
}
+ public Statistics getStatistics() {
+ return statistics;
+ }
+
public FilterCachingStrategy getFilterCachingStrategy() {
return filterCachingStrategy;
}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MutableSearchFactory.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MutableSearchFactory.java 2010-08-19 11:44:21 UTC (rev 20175)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/impl/MutableSearchFactory.java 2010-08-19 11:45:48 UTC (rev 20176)
@@ -25,6 +25,7 @@
import org.hibernate.search.spi.internals.DirectoryProviderData;
import org.hibernate.search.spi.internals.PolymorphicIndexHierarchy;
import org.hibernate.search.spi.internals.StateSearchFactoryImplementor;
+import org.hibernate.search.stat.Statistics;
import org.hibernate.search.store.DirectoryProvider;
import org.hibernate.search.store.optimization.OptimizerStrategy;
@@ -180,6 +181,10 @@
return delegate.buildQueryBuilder();
}
+ public Statistics getStatistics() {
+ return delegate.getStatistics();
+ }
+
public Map<Class<?>, DocumentBuilderContainedEntity<?>> getDocumentBuildersContainedEntities() {
return delegate.getDocumentBuildersContainedEntities();
}
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsImpl.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsImpl.java 2010-08-19 11:44:21 UTC (rev 20175)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/jmx/StatisticsImpl.java 2010-08-19 11:45:48 UTC (rev 20176)
@@ -24,41 +24,60 @@
package org.hibernate.search.jmx;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
-import org.hibernate.search.jmx.StatisticsImplMBean;
-import org.hibernate.search.stat.Statistics;
-
/**
* @author Hardy Ferentschik
*/
-public class StatisticsImpl implements Statistics, StatisticsImplMBean {
+public class StatisticsImpl implements StatisticsImplMBean {
private AtomicLong searchQueryCount = new AtomicLong();
- private AtomicLong searchExecutionAvgTime = new AtomicLong();
private AtomicLong searchExecutionTotalTime = new AtomicLong();
private AtomicLong searchExecutionMaxTime = new AtomicLong();
- private AtomicLong searchExecutionMinTime = new AtomicLong();
private volatile String queryExecutionMaxTimeQueryString;
private volatile boolean isStatisticsEnabled;
+ private final Lock readLock;
+ private final Lock writeLock;
+ {
+ ReadWriteLock lock = new ReentrantReadWriteLock();
+ readLock = lock.readLock();
+ writeLock = lock.writeLock();
+ }
+
public void clear() {
searchQueryCount.set( 0 );
+ searchExecutionTotalTime.set( 0 );
+ searchExecutionMaxTime.set( 0 );
+ queryExecutionMaxTimeQueryString = "";
}
public long getSearchQueryExecutionCount() {
return searchQueryCount.get();
}
+ public long getSearchQueryTotalTime() {
+ return searchExecutionTotalTime.get();
+ }
+
public long getSearchQueryExecutionMaxTime() {
return searchExecutionMaxTime.get();
}
- public long getSearchQueryExecutionMinTime() {
- return searchExecutionMinTime.get();
- }
-
public long getSearchQueryExecutionAvgTime() {
- return searchExecutionAvgTime.get();
+ writeLock.lock();
+ try {
+ long avgExecutionTime = 0;
+ if ( searchQueryCount.get() > 0 ) {
+ avgExecutionTime = searchExecutionTotalTime.get() / searchQueryCount.get();
+ }
+ return avgExecutionTime;
+ }
+ finally {
+ writeLock.unlock();
+ }
}
public String getSearchQueryExecutionMaxTimeQueryString() {
@@ -66,26 +85,23 @@
}
public void searchExecuted(String searchString, long time) {
- searchQueryCount.getAndIncrement();
- boolean isLongestQuery = false;
- for ( long old = searchExecutionMaxTime.get();
- ( time > old ) && ( isLongestQuery = !searchExecutionMaxTime.compareAndSet( old, time ) );
- old = searchExecutionMaxTime.get() ) {
- ;
+ readLock.lock();
+ try {
+ boolean isLongestQuery = false;
+ for ( long old = searchExecutionMaxTime.get();
+ ( time > old ) && ( isLongestQuery = searchExecutionMaxTime.compareAndSet( old, time ) );
+ old = searchExecutionMaxTime.get() ) {
+ ;
+ }
+ if ( isLongestQuery ) {
+ queryExecutionMaxTimeQueryString = searchString;
+ }
+ searchQueryCount.getAndIncrement();
+ searchExecutionTotalTime.addAndGet( time );
}
- if ( isLongestQuery ) {
- queryExecutionMaxTimeQueryString = searchString;
+ finally {
+ readLock.unlock();
}
-
- boolean isShortestQuery = false;
- for ( long old = searchExecutionMinTime.get();
- ( time < old ) && ( isShortestQuery = !searchExecutionMinTime.compareAndSet( old, time ) );
- old = searchExecutionMinTime.get() ) {
- ;
- }
-
- searchExecutionTotalTime.getAndAdd( time );
- searchExecutionAvgTime.getAndSet( searchExecutionTotalTime.get() / searchQueryCount.get() );
}
public boolean isStatisticsEnabled() {
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/FullTextQueryImpl.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/FullTextQueryImpl.java 2010-08-19 11:44:21 UTC (rev 20175)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/query/FullTextQueryImpl.java 2010-08-19 11:45:48 UTC (rev 20176)
@@ -53,11 +53,11 @@
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
+import org.hibernate.LockOptions;
import org.hibernate.Query;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
-import org.hibernate.LockOptions;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.query.ParameterMetadata;
import org.hibernate.impl.AbstractQueryImpl;
@@ -77,24 +77,21 @@
import org.hibernate.search.engine.SearchFactoryImplementor;
import org.hibernate.search.filter.ChainedFilter;
import org.hibernate.search.filter.FilterKey;
-import org.hibernate.search.filter.StandardFilterKey;
import org.hibernate.search.filter.FullTextFilterImplementor;
import org.hibernate.search.filter.ShardSensitiveOnlyFilter;
+import org.hibernate.search.filter.StandardFilterKey;
import org.hibernate.search.reader.ReaderProvider;
-
-import static org.hibernate.search.reader.ReaderProviderHelper.getIndexReaders;
-
import org.hibernate.search.store.DirectoryProvider;
import org.hibernate.search.store.IndexShardingStrategy;
import org.hibernate.search.util.ContextHelper;
+import org.hibernate.search.util.LoggerFactory;
+import org.hibernate.transform.ResultTransformer;
+import org.hibernate.util.ReflectHelper;
+import static org.hibernate.search.reader.ReaderProviderHelper.getIndexReaders;
import static org.hibernate.search.util.FilterCacheModeTypeHelper.cacheInstance;
import static org.hibernate.search.util.FilterCacheModeTypeHelper.cacheResults;
-import org.hibernate.search.util.LoggerFactory;
-import org.hibernate.transform.ResultTransformer;
-import org.hibernate.util.ReflectHelper;
-
/**
* Implementation of {@link org.hibernate.search.FullTextQuery}.
*
@@ -401,6 +398,13 @@
org.apache.lucene.search.Query query = filterQueryByClasses( luceneQuery );
buildFilters();
QueryHits queryHits;
+
+ boolean stats = searchFactoryImplementor.getStatistics().isStatisticsEnabled();
+ long startTime = 0;
+ if ( stats ) {
+ startTime = System.currentTimeMillis();
+ }
+
if ( n == null ) { // try to make sure that we get the right amount of top docs
queryHits = new QueryHits( searcher, query, filter, sort );
}
@@ -408,6 +412,11 @@
queryHits = new QueryHits( searcher, query, filter, sort, n );
}
resultSize = queryHits.totalHits;
+
+ if ( stats ) {
+ searchFactoryImplementor.getStatistics().searchExecuted( query.toString(), System.currentTimeMillis() - startTime );
+ }
+
return queryHits;
}
@@ -902,10 +911,10 @@
}
public <T> T unwrap(Class<T> type) {
- if ( type == org.apache.lucene.search.Query.class) {
- return (T) luceneQuery;
+ if ( type == org.apache.lucene.search.Query.class ) {
+ return ( T ) luceneQuery;
}
- throw new IllegalArgumentException("Cannot unwrap " + type.getName() );
+ throw new IllegalArgumentException( "Cannot unwrap " + type.getName() );
}
public LockOptions getLockOptions() {
Modified: search/trunk/hibernate-search/src/main/java/org/hibernate/search/stat/Statistics.java
===================================================================
--- search/trunk/hibernate-search/src/main/java/org/hibernate/search/stat/Statistics.java 2010-08-19 11:44:21 UTC (rev 20175)
+++ search/trunk/hibernate-search/src/main/java/org/hibernate/search/stat/Statistics.java 2010-08-19 11:45:48 UTC (rev 20176)
@@ -1,10 +1,75 @@
-// $Id:$
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat, Inc. and/or its affiliates or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat, Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
package org.hibernate.search.stat;
/**
* @author Hardy Ferentschik
*/
-public class Statistics {
+public interface Statistics {
+ /**
+ * Reset all statistics.
+ */
+ void clear();
+
+ /**
+ * Get global number of executed search queries
+ *
+ * @return search query execution count
+ */
+ long getSearchQueryExecutionCount();
+
+ /**
+ * Get the total search time in milliseconds.
+ */
+ long getSearchQueryTotalTime();
+
+ /**
+ * Get the time in milliseconds of the slowest search.
+ */
+ long getSearchQueryExecutionMaxTime();
+
+ /**
+ * Get the average search time in milliseconds.
+ */
+ long getSearchQueryExecutionAvgTime();
+
+ /**
+ * Get the query string for the slowest query.
+ */
+ String getSearchQueryExecutionMaxTimeQueryString();
+
+ void searchExecuted(String searchString, long time);
+
+ /**
+ * Are statistics logged
+ */
+ public boolean isStatisticsEnabled();
+
+ /**
+ * Enable statistics logs (this is a dynamic parameter)
+ */
+ public void setStatisticsEnabled(boolean b);
}
Modified: search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/batchindexing/IndexingGeneratedCorpusTest.java
===================================================================
--- search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/batchindexing/IndexingGeneratedCorpusTest.java 2010-08-19 11:44:21 UTC (rev 20175)
+++ search/trunk/hibernate-search/src/test/java/org/hibernate/search/test/batchindexing/IndexingGeneratedCorpusTest.java 2010-08-19 11:45:48 UTC (rev 20176)
@@ -70,6 +70,7 @@
.setProperty( "hibernate.jndi.org.osjava.sj.root", "/Users/hardy/tmp/jndi-entries" )
.setProperty( "hibernate.jndi.org.osjava.sj.jndi.shared", "true" )
.setProperty( Environment.JMX_ENABLED, "true" )
+ .setProperty( Environment.GENERATE_STATS, "true" )
.build();
createMany( Book.class, BOOK_NUM );
createMany( Dvd.class, DVD_NUM );
More information about the hibernate-commits
mailing list