You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2009/03/30 11:24:16 UTC
svn commit: r759889 - in /jackrabbit/trunk/jackrabbit-core/src:
main/java/org/apache/jackrabbit/core/query/lucene/
test/java/org/apache/jackrabbit/core/integration/daily/
test/java/org/apache/jackrabbit/core/query/
Author: mreutegg
Date: Mon Mar 30 09:24:03 2009
New Revision: 759889
URL: http://svn.apache.org/viewvc?rev=759889&view=rev
Log:
JCR-2044: Pass resultFetchSize/limit hint to SortedLuceneQueryHits
Added:
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/LargeResultSetTest.java (with props)
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ChildAxisQuery.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DescendantSelfAxisQuery.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitQuery.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/daily/DailyIntegrationTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/AbstractIndexingTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/AbstractQueryTest.java
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ChildAxisQuery.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ChildAxisQuery.java?rev=759889&r1=759888&r2=759889&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ChildAxisQuery.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ChildAxisQuery.java Mon Mar 30 09:24:03 2009
@@ -264,7 +264,7 @@
throws IOException {
if (sort.getSort().length == 0 && matchesAnyChildNode()) {
Query context = getContextQuery();
- return new ChildNodesQueryHits(searcher.evaluate(context, sort), session);
+ return new ChildNodesQueryHits(searcher.evaluate(context), session);
} else {
return null;
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DescendantSelfAxisQuery.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DescendantSelfAxisQuery.java?rev=759889&r1=759888&r2=759889&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DescendantSelfAxisQuery.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DescendantSelfAxisQuery.java Mon Mar 30 09:24:03 2009
@@ -229,7 +229,7 @@
if (sort.getSort().length == 0 && subQueryMatchesAll()) {
// maps path String to NodeId
Map startingPoints = new TreeMap();
- QueryHits result = searcher.evaluate(getContextQuery(), sort);
+ QueryHits result = searcher.evaluate(getContextQuery());
try {
// minLevels 0 and 1 are handled with a series of
// NodeTraversingQueryHits directly on result. For minLevels >= 2
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java?rev=759889&r1=759888&r2=759889&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java Mon Mar 30 09:24:03 2009
@@ -55,25 +55,31 @@
/**
* Executes the query and returns the hits that match the query.
*
- * @param query the query to execute.
- * @param sort the sort criteria.
+ * @param query the query to execute.
+ * @param sort the sort criteria.
+ * @param resultFetchHint a hint on how many results should be fetched.
* @return the query hits.
* @throws IOException if an error occurs while executing the query.
*/
- public MultiColumnQueryHits execute(Query query, Sort sort) throws IOException {
- return new QueryHitsAdapter(evaluate(query, sort),
+ public MultiColumnQueryHits execute(Query query,
+ Sort sort,
+ long resultFetchHint)
+ throws IOException {
+ return new QueryHitsAdapter(evaluate(query, sort, resultFetchHint),
QueryImpl.DEFAULT_SELECTOR_NAME);
}
/**
* Evaluates the query and returns the hits that match the query.
*
- * @param query the query to execute.
- * @param sort the sort criteria.
+ * @param query the query to execute.
+ * @param sort the sort criteria.
+ * @param resultFetchHint a hint on how many results should be fetched.
* @return the query hits.
* @throws IOException if an error occurs while executing the query.
*/
- public QueryHits evaluate(Query query, Sort sort) throws IOException {
+ public QueryHits evaluate(Query query, Sort sort, long resultFetchHint)
+ throws IOException {
query = query.rewrite(reader);
QueryHits hits = null;
if (query instanceof JackrabbitQuery) {
@@ -83,9 +89,21 @@
if (sort == null) {
hits = new LuceneQueryHits(reader, this, query);
} else {
- hits = new SortedLuceneQueryHits(reader, this, query, sort);
+ hits = new SortedLuceneQueryHits(
+ reader, this, query, sort, resultFetchHint);
}
}
return hits;
}
+
+ /**
+ * Evaluates the query and returns the hits that match the query.
+ *
+ * @param query the query to execute.
+ * @return the query hits.
+ * @throws IOException if an error occurs while executing the query.
+ */
+ public QueryHits evaluate(Query query) throws IOException {
+ return evaluate(query, new Sort(), Integer.MAX_VALUE);
+ }
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitQuery.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitQuery.java?rev=759889&r1=759888&r2=759889&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitQuery.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitQuery.java Mon Mar 30 09:24:03 2009
@@ -17,6 +17,7 @@
package org.apache.jackrabbit.core.query.lucene;
import org.apache.lucene.search.Sort;
+import org.apache.lucene.search.Query;
import org.apache.jackrabbit.core.SessionImpl;
import java.io.IOException;
@@ -34,7 +35,7 @@
* this query should be executed using the regular Lucene API.
* <p/>
* <b>Important note:</b> an implementation <b>must not</b> call
- * {@link JackrabbitIndexSearcher#execute(org.apache.lucene.search.Query, Sort)}
+ * {@link JackrabbitIndexSearcher#execute(Query, Sort, long)}
* with this query instance as a parameter, otherwise a stack overflow will
* occur.
*
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java?rev=759889&r1=759888&r2=759889&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java Mon Mar 30 09:24:03 2009
@@ -237,12 +237,13 @@
* Executes the query for this result and returns hits. The caller must
* close the query hits when he is done using it.
*
+ * @param resultFetchHint a hint on how many results should be fetched.
* @return hits for this query result.
* @throws IOException if an error occurs while executing the query.
*/
- protected MultiColumnQueryHits executeQuery() throws IOException {
+ protected MultiColumnQueryHits executeQuery(long resultFetchHint) throws IOException {
return index.executeQuery(session, queryImpl,
- query, orderProps, orderSpecs);
+ query, orderProps, orderSpecs, resultFetchHint);
}
//--------------------------------< internal >------------------------------
@@ -291,7 +292,7 @@
MultiColumnQueryHits result = null;
try {
long time = System.currentTimeMillis();
- result = executeQuery();
+ result = executeQuery(maxResultSize);
log.debug("query executed in {} ms",
new Long(System.currentTimeMillis() - time));
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java?rev=759889&r1=759888&r2=759889&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java Mon Mar 30 09:24:03 2009
@@ -730,21 +730,25 @@
/**
* Executes the query on the search index.
- * @param session the session that executes the query.
- * @param queryImpl the query impl.
- * @param query the lucene query.
- * @param orderProps name of the properties for sort order.
- * @param orderSpecs the order specs for the sort order properties.
- * <code>true</code> indicates ascending order, <code>false</code> indicates
- * descending.
+ *
+ * @param session the session that executes the query.
+ * @param queryImpl the query impl.
+ * @param query the lucene query.
+ * @param orderProps name of the properties for sort order.
+ * @param orderSpecs the order specs for the sort order properties.
+ * <code>true</code> indicates ascending order,
+ * <code>false</code> indicates descending.
+ * @param resultFetchHint a hint on how many results should be fetched.
* @return the query hits.
* @throws IOException if an error occurs while searching the index.
*/
public MultiColumnQueryHits executeQuery(SessionImpl session,
- AbstractQueryImpl queryImpl,
- Query query,
- Path[] orderProps,
- boolean[] orderSpecs) throws IOException {
+ AbstractQueryImpl queryImpl,
+ Query query,
+ Path[] orderProps,
+ boolean[] orderSpecs,
+ long resultFetchHint)
+ throws IOException {
checkOpen();
Sort sort = new Sort(createSortFields(orderProps, orderSpecs));
@@ -752,7 +756,8 @@
final IndexReader reader = getIndexReader(queryImpl.needsSystemTree());
JackrabbitIndexSearcher searcher = new JackrabbitIndexSearcher(session, reader);
searcher.setSimilarity(getSimilarity());
- return new FilterMultiColumnQueryHits(searcher.execute(query, sort)) {
+ return new FilterMultiColumnQueryHits(
+ searcher.execute(query, sort, resultFetchHint)) {
public void close() throws IOException {
try {
super.close();
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java?rev=759889&r1=759888&r2=759889&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java Mon Mar 30 09:24:03 2009
@@ -23,6 +23,8 @@
import org.apache.lucene.index.IndexReader;
import org.apache.jackrabbit.core.NodeId;
import org.apache.jackrabbit.uuid.UUID;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Logger;
import java.io.IOException;
import java.util.List;
@@ -36,6 +38,21 @@
public final class SortedLuceneQueryHits extends AbstractQueryHits {
/**
+ * The Logger instance for this class.
+ */
+ private static final Logger log = LoggerFactory.getLogger(SortedLuceneQueryHits.class);
+
+ /**
+ * The upper limit for the initial fetch size.
+ */
+ private static final int MAX_FETCH_SIZE = 32 * 1024;
+
+ /**
+ * The lower limit for the initial fetch size.
+ */
+ private static final int MIN_FETCH_SIZE = 32;
+
+ /**
* The IndexReader in use by the lucene hits.
*/
private final IndexReader reader;
@@ -73,25 +90,30 @@
/**
* Number of hits to retrieve.
*/
- private int numHits = 50;
+ private int numHits;
/**
* Creates a new <code>QueryHits</code> instance wrapping <code>hits</code>.
*
- * @param reader the IndexReader in use.
- * @param searcher the index searcher.
- * @param query the query to execute.
- * @param sort the sort criteria.
+ * @param reader the IndexReader in use.
+ * @param searcher the index searcher.
+ * @param query the query to execute.
+ * @param sort the sort criteria.
+ * @param resultFetchHint a hint on how many results should be fetched.
* @throws IOException if an error occurs while reading from the index.
*/
public SortedLuceneQueryHits(IndexReader reader,
JackrabbitIndexSearcher searcher,
Query query,
- Sort sort) throws IOException {
+ Sort sort,
+ long resultFetchHint) throws IOException {
this.reader = reader;
this.searcher = searcher;
this.query = query;
this.sort = sort;
+ this.numHits = (int) Math.min(
+ Math.max(resultFetchHint, MIN_FETCH_SIZE),
+ MAX_FETCH_SIZE);
getHits();
}
@@ -110,7 +132,8 @@
// no more score nodes
return null;
} else if (hitIndex >= scoreNodes.size()) {
- // refill
+ // refill at least numHits or twice hitIndex
+ this.numHits = Math.max(this.numHits, hitIndex * 2);
getHits();
}
return (ScoreNode) scoreNodes.get(hitIndex);
@@ -128,20 +151,18 @@
//-------------------------------< internal >-------------------------------
- private int getHits() throws IOException {
- // double hits
- numHits *= 2;
+ private void getHits() throws IOException {
TopFieldDocCollector collector = new TopFieldDocCollector(reader, sort, numHits);
searcher.search(query, collector);
this.size = collector.getTotalHits();
ScoreDoc[] docs = collector.topDocs().scoreDocs;
- int num = 0;
for (int i = scoreNodes.size(); i < docs.length; i++) {
String uuid = reader.document(docs[i].doc).get(FieldNames.UUID);
NodeId id = new NodeId(UUID.fromString(uuid));
scoreNodes.add(new ScoreNode(id, docs[i].score));
- num++;
}
- return num;
+ log.debug("getHits() {}/{}", new Integer(scoreNodes.size()), new Integer(numHits));
+ // double hits for next round
+ numHits *= 2;
}
}
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/daily/DailyIntegrationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/daily/DailyIntegrationTest.java?rev=759889&r1=759888&r2=759889&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/daily/DailyIntegrationTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/daily/DailyIntegrationTest.java Mon Mar 30 09:24:03 2009
@@ -29,6 +29,7 @@
import org.apache.jackrabbit.core.ConcurrentVersioningWithTransactionsTest;
import org.apache.jackrabbit.core.LockTest;
import org.apache.jackrabbit.core.ReadVersionsWhileModified;
+import org.apache.jackrabbit.core.query.LargeResultSetTest;
import org.apache.jackrabbit.core.lock.ConcurrentLockingTest;
import org.apache.jackrabbit.core.lock.ConcurrentLockingWithTransactionsTest;
@@ -56,6 +57,7 @@
suite.addTestSuite(ReadVersionsWhileModified.class);
suite.addTestSuite(ConcurrentLockingTest.class);
suite.addTestSuite(ConcurrentLockingWithTransactionsTest.class);
+ suite.addTestSuite(LargeResultSetTest.class);
return suite;
}
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/AbstractIndexingTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/AbstractIndexingTest.java?rev=759889&r1=759888&r2=759889&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/AbstractIndexingTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/AbstractIndexingTest.java Mon Mar 30 09:24:03 2009
@@ -46,11 +46,4 @@
testRootNode = null;
super.tearDown();
}
-
- /**
- * @return the query handler inside the {@link #qm query manager}.
- */
- protected QueryHandler getQueryHandler() {
- return ((QueryManagerImpl) qm).getQueryHandler();
- }
}
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/AbstractQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/AbstractQueryTest.java?rev=759889&r1=759888&r2=759889&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/AbstractQueryTest.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/AbstractQueryTest.java Mon Mar 30 09:24:03 2009
@@ -250,4 +250,11 @@
return qm.createQuery(statement, Query.XPATH).execute();
}
}
+
+ /**
+ * @return the query handler inside the {@link #qm query manager}.
+ */
+ protected QueryHandler getQueryHandler() {
+ return ((QueryManagerImpl) qm).getQueryHandler();
+ }
}
Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/LargeResultSetTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/LargeResultSetTest.java?rev=759889&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/LargeResultSetTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/LargeResultSetTest.java Mon Mar 30 09:24:03 2009
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.query;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.query.Query;
+import javax.jcr.query.RowIterator;
+import javax.jcr.query.QueryResult;
+
+import org.apache.jackrabbit.core.query.lucene.SearchIndex;
+
+/**
+ * <code>LargeResultSetTest</code>...
+ */
+public class LargeResultSetTest extends AbstractQueryTest {
+
+ public void testResultSet() throws RepositoryException {
+ createNodes(testRootNode, 10, 5, 0);
+ superuser.save();
+
+ SearchIndex index = (SearchIndex) getQueryHandler();
+ int resultFetchSize = index.getResultFetchSize();
+ try {
+ String stmt = testPath + "//*[@" + jcrPrimaryType + "] order by @jcr:score descending";
+
+ // with result fetch size Integer.MAX_VALUE
+ readResult(executeQuery(stmt));
+
+ // with result fetch size 100
+ index.setResultFetchSize(100);
+ readResult(executeQuery(stmt));
+
+ // with 100 limit
+ QueryImpl query = (QueryImpl) qm.createQuery(stmt, Query.XPATH);
+ query.setLimit(100);
+ readResult(query.execute());
+ } finally {
+ index.setResultFetchSize(resultFetchSize);
+ }
+
+ for (NodeIterator it = testRootNode.getNodes(); it.hasNext(); ) {
+ it.nextNode().remove();
+ superuser.save();
+ }
+ }
+
+ private void readResult(QueryResult result) throws RepositoryException {
+ for (RowIterator rows = result.getRows(); rows.hasNext(); ) {
+ rows.nextRow();
+ }
+ }
+
+ private int createNodes(Node n, int nodesPerLevel, int levels, int count)
+ throws RepositoryException {
+ levels--;
+ for (int i = 0; i < nodesPerLevel; i++) {
+ Node child = n.addNode("node" + i);
+ count++;
+ if (count % 10000 == 0) {
+ superuser.save();
+ }
+ if (levels > 0) {
+ count = createNodes(child, nodesPerLevel, levels, count);
+ }
+ }
+ return count;
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/LargeResultSetTest.java
------------------------------------------------------------------------------
svn:eol-style = native