You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2011/01/05 12:16:43 UTC

svn commit: r1055416 [1/3] - in /lucene/dev/trunk: lucene/ lucene/contrib/ant/src/java/org/apache/lucene/ant/ lucene/contrib/ant/src/test/org/apache/lucene/ant/ lucene/contrib/demo/src/java/org/apache/lucene/demo/ lucene/contrib/highlighter/src/test/or...

Author: mikemccand
Date: Wed Jan  5 11:16:40 2011
New Revision: 1055416

URL: http://svn.apache.org/viewvc?rev=1055416&view=rev
Log:
LUCENE-2837: collapse Searcher/Searchable into IndexSearcher; remove contrib/remote, MultiSearcher; absorb ParallelMultiSearcher into IndexSearcher as optional ExecutorService to ctor

Removed:
    lucene/dev/trunk/lucene/contrib/remote/
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/MultiSearcher.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/ParallelMultiSearcher.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/Searchable.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/Searcher.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestMultiSearcher.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestMultiSearcherRanking.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestParallelMultiSearcher.java
Modified:
    lucene/dev/trunk/lucene/CHANGES.txt
    lucene/dev/trunk/lucene/contrib/ant/src/java/org/apache/lucene/ant/IndexTask.java
    lucene/dev/trunk/lucene/contrib/ant/src/test/org/apache/lucene/ant/IndexTaskTest.java
    lucene/dev/trunk/lucene/contrib/demo/src/java/org/apache/lucene/demo/SearchFiles.java
    lucene/dev/trunk/lucene/contrib/highlighter/src/test/org/apache/lucene/search/highlight/HighlighterTest.java
    lucene/dev/trunk/lucene/contrib/lucli/src/java/lucli/LuceneMethods.java
    lucene/dev/trunk/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java
    lucene/dev/trunk/lucene/contrib/queries/src/java/org/apache/lucene/search/BoostingQuery.java
    lucene/dev/trunk/lucene/contrib/queries/src/java/org/apache/lucene/search/FuzzyLikeThisQuery.java
    lucene/dev/trunk/lucene/contrib/queries/src/test/org/apache/lucene/search/ChainedFilterTest.java
    lucene/dev/trunk/lucene/contrib/queries/src/test/org/apache/lucene/search/regex/TestSpanRegexQuery.java
    lucene/dev/trunk/lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTst.java
    lucene/dev/trunk/lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestCartesian.java
    lucene/dev/trunk/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynExpand.java
    lucene/dev/trunk/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynLookup.java
    lucene/dev/trunk/lucene/contrib/wordnet/src/test/org/apache/lucene/wordnet/TestWordnet.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/document/Document.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/LogMergePolicy.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/BooleanQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/FilteredQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/IndexSearcher.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/MatchAllDocsQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/PhraseQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/Query.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/Similarity.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/TermQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/FieldMaskingSpanQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanQuery.java
    lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/spans/SpanWeight.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/TestSearch.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/TestSearchForDuplicates.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/document/TestDocument.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/index/TestLazyProxSkipping.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/index/TestNRTThreads.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/index/TestOmitTf.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/CheckHits.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/QueryUtils.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestBooleanMinShouldMatch.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestConstantScoreQuery.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestCustomSearcherSort.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestMultiValuedNumericRangeQuery.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestNot.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestPhraseQuery.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestRegexpRandom.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestSimilarity.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestSimpleExplanations.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestSort.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestTermRangeQuery.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestTimeLimitingCollector.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/TestWildcardRandom.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/function/TestCustomScoreQuery.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/payloads/TestPayloadNearQuery.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/spans/TestSpanMultiTermQueryWrapper.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/spans/TestSpans.java
    lucene/dev/trunk/lucene/src/test/org/apache/lucene/search/spans/TestSpansAdvanced.java
    lucene/dev/trunk/modules/analysis/common/src/test/org/apache/lucene/collation/CollationTestBase.java
    lucene/dev/trunk/modules/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTask.java
    lucene/dev/trunk/modules/benchmark/src/java/org/apache/lucene/benchmark/quality/QualityBenchmark.java
    lucene/dev/trunk/modules/benchmark/src/java/org/apache/lucene/benchmark/quality/trec/QueryDriver.java
    lucene/dev/trunk/modules/benchmark/src/java/org/apache/lucene/benchmark/quality/utils/DocNameExtractor.java
    lucene/dev/trunk/modules/benchmark/src/java/org/apache/lucene/benchmark/quality/utils/SubmissionReport.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/schema/LatLonType.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/LuceneQueryOptimizer.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/SolrConstantScoreQuery.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/SolrFilter.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/ValueSourceParser.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/BoostedQuery.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/DocFreqValueSource.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/DualFloatFunction.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/FunctionQuery.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/IDFValueSource.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/LinearFloatFunction.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/MaxDocValueSource.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/MaxFloatFunction.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/MultiFloatFunction.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/NormValueSource.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/QueryValueSource.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/RangeMapFloatFunction.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/ReciprocalFloatFunction.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/ScaleFloatFunction.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/SingleFunction.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/TFValueSource.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/ValueSource.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/ValueSourceRangeFilter.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/VectorValueSource.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/GeohashHaversineFunction.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/HaversineConstFunction.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/HaversineFunction.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/VectorDistanceFunction.java

Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Wed Jan  5 11:16:40 2011
@@ -123,6 +123,11 @@ Changes in backwards compatibility polic
   you really want a top-level norms, use MultiNorms or SlowMultiReaderWrapper.
   (Uwe Schindler, Robert Muir)
 
+* LUCENE-2837: Collapsed Searcher, Searchable into IndexSearcher;
+  removed contrib/remote and MultiSearcher (Mike McCandless); absorbed
+  ParallelMultiSearcher into IndexSearcher as an optional
+  ExecutorServiced passed to its ctor.  (Mike McCandless)
+
 Changes in Runtime Behavior
 
 * LUCENE-2650, LUCENE-2825: The behavior of FSDirectory.open has changed. On 64-bit

Modified: lucene/dev/trunk/lucene/contrib/ant/src/java/org/apache/lucene/ant/IndexTask.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/contrib/ant/src/java/org/apache/lucene/ant/IndexTask.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/contrib/ant/src/java/org/apache/lucene/ant/IndexTask.java (original)
+++ lucene/dev/trunk/lucene/contrib/ant/src/java/org/apache/lucene/ant/IndexTask.java Wed Jan  5 11:16:40 2011
@@ -44,7 +44,6 @@ import org.apache.lucene.index.Term;
 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.ScoreDoc;
-import org.apache.lucene.search.Searcher;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.store.FSDirectory;
 import org.apache.lucene.util.Version;
@@ -268,7 +267,7 @@ public class IndexTask extends Task {
 
     FSDirectory dir = FSDirectory.open(indexDir);
     try {
-      Searcher searcher = null;
+      IndexSearcher searcher = null;
       boolean checkLastModified = false;
       if (!create) {
         try {

Modified: lucene/dev/trunk/lucene/contrib/ant/src/test/org/apache/lucene/ant/IndexTaskTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/contrib/ant/src/test/org/apache/lucene/ant/IndexTaskTest.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/contrib/ant/src/test/org/apache/lucene/ant/IndexTaskTest.java (original)
+++ lucene/dev/trunk/lucene/contrib/ant/src/test/org/apache/lucene/ant/IndexTaskTest.java Wed Jan  5 11:16:40 2011
@@ -18,14 +18,13 @@ package org.apache.lucene.ant;
  */
 
 import java.io.File;
-import java.io.IOException;
+import java.io.IOException;  // javadoc
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.core.StopAnalyzer;
 import org.apache.lucene.queryParser.QueryParser;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.search.Searcher;
 import org.apache.lucene.store.Directory;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.types.FileSet;
@@ -39,7 +38,7 @@ public class IndexTaskTest extends Lucen
     private final static String docHandler =
             "org.apache.lucene.ant.FileExtensionDocumentHandler";
 
-    private Searcher searcher;
+    private IndexSearcher searcher;
     private Analyzer analyzer;
     private Directory dir;
 

Modified: lucene/dev/trunk/lucene/contrib/demo/src/java/org/apache/lucene/demo/SearchFiles.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/contrib/demo/src/java/org/apache/lucene/demo/SearchFiles.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/contrib/demo/src/java/org/apache/lucene/demo/SearchFiles.java (original)
+++ lucene/dev/trunk/lucene/contrib/demo/src/java/org/apache/lucene/demo/SearchFiles.java Wed Jan  5 11:16:40 2011
@@ -34,7 +34,6 @@ import org.apache.lucene.search.IndexSea
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.ScoreDoc;
 import org.apache.lucene.search.Scorer;
-import org.apache.lucene.search.Searcher;
 import org.apache.lucene.search.TopScoreDocCollector;
 import org.apache.lucene.store.FSDirectory;
 import org.apache.lucene.util.Version;
@@ -92,7 +91,7 @@ public class SearchFiles {
     
     IndexReader reader = IndexReader.open(FSDirectory.open(new File(index)), true); // only searching, so read-only=true
 
-    Searcher searcher = new IndexSearcher(reader);
+    IndexSearcher searcher = new IndexSearcher(reader);
     Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);
 
     BufferedReader in = null;
@@ -144,7 +143,7 @@ public class SearchFiles {
    *  This simulates the streaming search use case, where all hits are supposed to
    *  be processed, regardless of their relevance.
    */
-  public static void doStreamingSearch(final Searcher searcher, Query query) throws IOException {
+  public static void doStreamingSearch(final IndexSearcher searcher, Query query) throws IOException {
     Collector streamingHitCollector = new Collector() {
       private Scorer scorer;
       private int docBase;
@@ -186,7 +185,7 @@ public class SearchFiles {
    * is executed another time and all hits are collected.
    * 
    */
-  public static void doPagingSearch(BufferedReader in, Searcher searcher, Query query, 
+  public static void doPagingSearch(BufferedReader in, IndexSearcher searcher, Query query, 
                                      int hitsPerPage, boolean raw, boolean interactive) throws IOException {
  
     // Collect enough docs to show 5 pages

Modified: lucene/dev/trunk/lucene/contrib/highlighter/src/test/org/apache/lucene/search/highlight/HighlighterTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/contrib/highlighter/src/test/org/apache/lucene/search/highlight/HighlighterTest.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/contrib/highlighter/src/test/org/apache/lucene/search/highlight/HighlighterTest.java (original)
+++ lucene/dev/trunk/lucene/contrib/highlighter/src/test/org/apache/lucene/search/highlight/HighlighterTest.java Wed Jan  5 11:16:40 2011
@@ -58,7 +58,6 @@ import org.apache.lucene.search.BooleanQ
 import org.apache.lucene.search.FilteredQuery;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MultiPhraseQuery;
-import org.apache.lucene.search.MultiSearcher;
 import org.apache.lucene.search.MultiTermQuery;
 import org.apache.lucene.search.NumericRangeQuery;
 import org.apache.lucene.search.PhraseQuery;
@@ -1301,68 +1300,6 @@ public class HighlighterTest extends Bas
     assertEquals("XHTML Encoding should have worked:", rawDocContent, decodedSnippet);
   }
 
-  public void testMultiSearcher() throws Exception {
-    // setup index 1
-    Directory ramDir1 = newDirectory();
-    IndexWriter writer1 = new IndexWriter(ramDir1, newIndexWriterConfig(
-        TEST_VERSION_CURRENT, new MockAnalyzer(MockTokenizer.SIMPLE, true, MockTokenFilter.ENGLISH_STOPSET, true)));
-    Document d = new Document();
-    Field f = new Field(FIELD_NAME, "multiOne", Field.Store.YES, Field.Index.ANALYZED);
-    d.add(f);
-    writer1.addDocument(d);
-    writer1.optimize();
-    writer1.close();
-    IndexReader reader1 = IndexReader.open(ramDir1, true);
-
-    // setup index 2
-    Directory ramDir2 = newDirectory();
-    IndexWriter writer2 = new IndexWriter(ramDir2, newIndexWriterConfig(
-        TEST_VERSION_CURRENT, new MockAnalyzer(MockTokenizer.SIMPLE, true, MockTokenFilter.ENGLISH_STOPSET, true)));
-    d = new Document();
-    f = new Field(FIELD_NAME, "multiTwo", Field.Store.YES, Field.Index.ANALYZED);
-    d.add(f);
-    writer2.addDocument(d);
-    writer2.optimize();
-    writer2.close();
-    IndexReader reader2 = IndexReader.open(ramDir2, true);
-
-    IndexSearcher searchers[] = new IndexSearcher[2];
-    searchers[0] = new IndexSearcher(ramDir1, true);
-    searchers[1] = new IndexSearcher(ramDir2, true);
-    MultiSearcher multiSearcher = new MultiSearcher(searchers);
-    QueryParser parser = new QueryParser(TEST_VERSION_CURRENT, FIELD_NAME, new MockAnalyzer(MockTokenizer.SIMPLE, true, MockTokenFilter.ENGLISH_STOPSET, true));
-    parser.setMultiTermRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);
-    query = parser.parse("multi*");
-    if (VERBOSE) System.out.println("Searching for: " + query.toString(FIELD_NAME));
-    // at this point the multisearcher calls combine(query[])
-    hits = multiSearcher.search(query, null, 1000);
-
-    // query = QueryParser.parse("multi*", FIELD_NAME, new StandardAnalyzer(TEST_VERSION));
-    Query expandedQueries[] = new Query[2];
-    expandedQueries[0] = query.rewrite(reader1);
-    expandedQueries[1] = query.rewrite(reader2);
-    query = query.combine(expandedQueries);
-
-    // create an instance of the highlighter with the tags used to surround
-    // highlighted text
-    Highlighter highlighter = new Highlighter(this, new QueryTermScorer(query));
-
-    for (int i = 0; i < hits.totalHits; i++) {
-      String text = multiSearcher.doc(hits.scoreDocs[i].doc).get(FIELD_NAME);
-      TokenStream tokenStream = analyzer.tokenStream(FIELD_NAME, new StringReader(text));
-      String highlightedText = highlighter.getBestFragment(tokenStream, text);
-      if (VERBOSE) System.out.println(highlightedText);
-    }
-    assertTrue("Failed to find correct number of highlights " + numHighlights + " found",
-        numHighlights == 2);
-    reader1.close();
-    reader2.close();
-    searchers[0].close();
-    searchers[1].close();
-    ramDir1.close();
-    ramDir2.close();
-  }
-
   public void testFieldSpecificHighlighting() throws Exception {
     TestHighlightRunner helper = new TestHighlightRunner() {
 

Modified: lucene/dev/trunk/lucene/contrib/lucli/src/java/lucli/LuceneMethods.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/contrib/lucli/src/java/lucli/LuceneMethods.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/contrib/lucli/src/java/lucli/LuceneMethods.java (original)
+++ lucene/dev/trunk/lucene/contrib/lucli/src/java/lucli/LuceneMethods.java Wed Jan  5 11:16:40 2011
@@ -53,11 +53,10 @@ import org.apache.lucene.queryParser.Mul
 import org.apache.lucene.queryParser.ParseException;
 import org.apache.lucene.search.Collector;
 import org.apache.lucene.search.Explanation;
-import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.ScoreDoc;
 import org.apache.lucene.search.Scorer;
-import org.apache.lucene.search.Searcher;
+import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.store.FSDirectory;
 import org.apache.lucene.util.Version;
 import org.apache.lucene.util.BytesRef;
@@ -73,7 +72,7 @@ class LuceneMethods {
   private List<String> fields; //Fields as a vector
   private List<String> indexedFields; //Fields as a vector
   private String fieldsArray[]; //Fields as an array
-  private Searcher searcher;
+  private IndexSearcher searcher;
   private Query query; //current query string
   private String analyzerClassFQN = null; // Analyzer class, if NULL, use default Analyzer
 

Modified: lucene/dev/trunk/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java (original)
+++ lucene/dev/trunk/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java Wed Jan  5 11:16:40 2011
@@ -51,7 +51,6 @@ import org.apache.lucene.index.FieldInve
 import org.apache.lucene.search.Collector;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.search.Searcher;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Similarity;
 import org.apache.lucene.store.RAMDirectory; // for javadocs
@@ -421,7 +420,7 @@ public class MemoryIndex implements Seri
     if (query == null) 
       throw new IllegalArgumentException("query must not be null");
     
-    Searcher searcher = createSearcher();
+    IndexSearcher searcher = createSearcher();
     try {
       final float[] scores = new float[1]; // inits to 0.0f (no match)
       searcher.search(query, new Collector() {
@@ -738,7 +737,7 @@ public class MemoryIndex implements Seri
    */
   private final class MemoryIndexReader extends IndexReader {
     
-    private Searcher searcher; // needed to find searcher.getSimilarity() 
+    private IndexSearcher searcher; // needed to find searcher.getSimilarity() 
     
     private MemoryIndexReader() {
       super(); // avoid as much superclass baggage as possible
@@ -1135,7 +1134,7 @@ public class MemoryIndex implements Seri
       return Similarity.getDefault();
     }
     
-    private void setSearcher(Searcher searcher) {
+    private void setSearcher(IndexSearcher searcher) {
       this.searcher = searcher;
     }
     

Modified: lucene/dev/trunk/lucene/contrib/queries/src/java/org/apache/lucene/search/BoostingQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/contrib/queries/src/java/org/apache/lucene/search/BoostingQuery.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/contrib/queries/src/java/org/apache/lucene/search/BoostingQuery.java (original)
+++ lucene/dev/trunk/lucene/contrib/queries/src/java/org/apache/lucene/search/BoostingQuery.java Wed Jan  5 11:16:40 2011
@@ -23,7 +23,7 @@ import org.apache.lucene.index.IndexRead
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.DefaultSimilarity;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.search.Searcher;
+import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Similarity;
 /**
  * The BoostingQuery class can be used to effectively demote results that match a given query. 
@@ -58,7 +58,7 @@ public class BoostingQuery extends Query
       BooleanQuery result = new BooleanQuery() {
 
         @Override
-        public Similarity getSimilarity(Searcher searcher) {
+        public Similarity getSimilarity(IndexSearcher searcher) {
           return new DefaultSimilarity() {
 
             @Override

Modified: lucene/dev/trunk/lucene/contrib/queries/src/java/org/apache/lucene/search/FuzzyLikeThisQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/contrib/queries/src/java/org/apache/lucene/search/FuzzyLikeThisQuery.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/contrib/queries/src/java/org/apache/lucene/search/FuzzyLikeThisQuery.java (original)
+++ lucene/dev/trunk/lucene/contrib/queries/src/java/org/apache/lucene/search/FuzzyLikeThisQuery.java Wed Jan  5 11:16:40 2011
@@ -360,7 +360,7 @@ public class FuzzyLikeThisQuery extends 
         	  this.ignoreTF=ignoreTF;
           }
           @Override
-          public Similarity getSimilarity(Searcher searcher)
+          public Similarity getSimilarity(IndexSearcher searcher)
           {            
               Similarity result = super.getSimilarity(searcher);
               result = new SimilarityDelegator(result) {

Modified: lucene/dev/trunk/lucene/contrib/queries/src/test/org/apache/lucene/search/ChainedFilterTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/contrib/queries/src/test/org/apache/lucene/search/ChainedFilterTest.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/contrib/queries/src/test/org/apache/lucene/search/ChainedFilterTest.java (original)
+++ lucene/dev/trunk/lucene/contrib/queries/src/test/org/apache/lucene/search/ChainedFilterTest.java Wed Jan  5 11:16:40 2011
@@ -29,11 +29,10 @@ import org.apache.lucene.search.BooleanC
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.CachingWrapperFilter;
 import org.apache.lucene.search.Filter;
-import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchAllDocsQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.QueryWrapperFilter;
-import org.apache.lucene.search.Searcher;
+import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.search.TermRangeFilter;
 import org.apache.lucene.search.TopDocs;
@@ -195,7 +194,7 @@ public class ChainedFilterTest extends L
     IndexReader reader = writer.getReader();
     writer.close();
   
-    Searcher searcher = new IndexSearcher(reader);
+    IndexSearcher searcher = new IndexSearcher(reader);
   
     Query query = new TermQuery(new Term("none", "none"));
   

Modified: lucene/dev/trunk/lucene/contrib/queries/src/test/org/apache/lucene/search/regex/TestSpanRegexQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/contrib/queries/src/test/org/apache/lucene/search/regex/TestSpanRegexQuery.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/contrib/queries/src/test/org/apache/lucene/search/regex/TestSpanRegexQuery.java (original)
+++ lucene/dev/trunk/lucene/contrib/queries/src/test/org/apache/lucene/search/regex/TestSpanRegexQuery.java Wed Jan  5 11:16:40 2011
@@ -27,10 +27,8 @@ import org.apache.lucene.index.IndexWrit
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
 import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.MultiSearcher;
 import org.apache.lucene.search.spans.SpanFirstQuery;
 import org.apache.lucene.search.spans.SpanMultiTermQueryWrapper;
-import org.apache.lucene.search.spans.SpanNearQuery;
 import org.apache.lucene.search.spans.SpanQuery;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.LockObtainFailedException;
@@ -85,33 +83,6 @@ public class TestSpanRegexQuery extends 
     directory.close();
   }
   
-  public void testSpanRegexBug() throws CorruptIndexException, IOException {
-    createRAMDirectories();
-
-    SpanQuery srq = new SpanMultiTermQueryWrapper<RegexQuery>(new RegexQuery(new Term("field", "a.*")));
-    SpanQuery stq = new SpanMultiTermQueryWrapper<RegexQuery>(new RegexQuery(new Term("field", "b.*")));
-    SpanNearQuery query = new SpanNearQuery(new SpanQuery[] { srq, stq }, 6,
-        true);
-
-    // 1. Search the same store which works
-    IndexSearcher[] arrSearcher = new IndexSearcher[2];
-    arrSearcher[0] = new IndexSearcher(indexStoreA, true);
-    arrSearcher[1] = new IndexSearcher(indexStoreB, true);
-    MultiSearcher searcher = new MultiSearcher(arrSearcher);
-    int numHits = searcher.search(query, null, 1000).totalHits;
-    arrSearcher[0].close();
-    arrSearcher[1].close();
-
-    // Will fail here
-    // We expect 2 but only one matched
-    // The rewriter function only write it once on the first IndexSearcher
-    // So it's using term: a1 b1 to search on the second IndexSearcher
-    // As a result, it won't match the document in the second IndexSearcher
-    assertEquals(2, numHits);
-    indexStoreA.close();
-    indexStoreB.close();
-  }
-  
   private void createRAMDirectories() throws CorruptIndexException,
       LockObtainFailedException, IOException {
     // creating a document to store

Modified: lucene/dev/trunk/lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTst.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTst.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTst.java (original)
+++ lucene/dev/trunk/lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTst.java Wed Jan  5 11:16:40 2011
@@ -21,7 +21,6 @@ import java.io.IOException;
 
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Searcher;
 import org.apache.lucene.search.Collector;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Query;
@@ -122,7 +121,7 @@ public class BooleanQueryTst {
     /* if (verbose) System.out.println("Lucene: " + query.toString()); */
 
     TestCollector tc = new TestCollector();
-    Searcher searcher = new IndexSearcher(dBase.getDb(), true);
+    IndexSearcher searcher = new IndexSearcher(dBase.getDb(), true);
     try {
       searcher.search(query, tc);
     } finally {

Modified: lucene/dev/trunk/lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestCartesian.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestCartesian.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestCartesian.java (original)
+++ lucene/dev/trunk/lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestCartesian.java Wed Jan  5 11:16:40 2011
@@ -252,7 +252,7 @@ public class TestCartesian extends Lucen
 
     // Perform the search, using the term query, the serial chain filter, and the
     // distance sort
-    TopDocs hits = searcher.search(customScore.createWeight(searcher),null, 1000, sort);
+    TopDocs hits = searcher.search(customScore,null, 1000, sort);
     int results = hits.totalHits;
     ScoreDoc[] scoreDocs = hits.scoreDocs; 
     
@@ -348,7 +348,7 @@ public class TestCartesian extends Lucen
 
     // Perform the search, using the term query, the serial chain filter, and the
     // distance sort
-    TopDocs hits = searcher.search(customScore.createWeight(searcher),null, 1000, sort);
+    TopDocs hits = searcher.search(customScore,null, 1000, sort);
     int results = hits.totalHits;
     ScoreDoc[] scoreDocs = hits.scoreDocs; 
 
@@ -444,7 +444,7 @@ public class TestCartesian extends Lucen
     
       // Perform the search, using the term query, the serial chain filter, and the
       // distance sort
-      TopDocs hits = searcher.search(customScore.createWeight(searcher),null, 1000, sort);
+      TopDocs hits = searcher.search(customScore,null, 1000, sort);
       int results = hits.totalHits;
       ScoreDoc[] scoreDocs = hits.scoreDocs; 
     
@@ -539,7 +539,7 @@ public class TestCartesian extends Lucen
 	    
       // Perform the search, using the term query, the serial chain filter, and the
       // distance sort
-      TopDocs hits = searcher.search(customScore.createWeight(searcher),dq.getFilter(), 1000); //,sort);
+      TopDocs hits = searcher.search(customScore,dq.getFilter(), 1000); //,sort);
       int results = hits.totalHits;
       ScoreDoc[] scoreDocs = hits.scoreDocs; 
 	    

Modified: lucene/dev/trunk/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynExpand.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynExpand.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynExpand.java (original)
+++ lucene/dev/trunk/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynExpand.java Wed Jan  5 11:16:40 2011
@@ -39,7 +39,6 @@ import org.apache.lucene.search.Collecto
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Scorer;
-import org.apache.lucene.search.Searcher;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.store.FSDirectory;
 import org.apache.lucene.util.Version;
@@ -104,7 +103,7 @@ public final class SynExpand {
 	 * @return the expanded Query
 	 */ 
 	public static Query expand( String query,
-								Searcher syns,
+								IndexSearcher syns,
 								Analyzer a,
 								String f,
 								final float boost)

Modified: lucene/dev/trunk/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynLookup.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynLookup.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynLookup.java (original)
+++ lucene/dev/trunk/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynLookup.java Wed Jan  5 11:16:40 2011
@@ -39,7 +39,6 @@ import org.apache.lucene.search.IndexSea
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.ScoreDoc;
 import org.apache.lucene.search.Scorer;
-import org.apache.lucene.search.Searcher;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.store.FSDirectory;
 
@@ -114,7 +113,7 @@ public class SynLookup {
 	 * @param boost
 	 */ 
 	public static Query expand( String query,
-								Searcher syns,
+								IndexSearcher syns,
 								Analyzer a,
 								final String field,
 								final float boost)

Modified: lucene/dev/trunk/lucene/contrib/wordnet/src/test/org/apache/lucene/wordnet/TestWordnet.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/contrib/wordnet/src/test/org/apache/lucene/wordnet/TestWordnet.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/contrib/wordnet/src/test/org/apache/lucene/wordnet/TestWordnet.java (original)
+++ lucene/dev/trunk/lucene/contrib/wordnet/src/test/org/apache/lucene/wordnet/TestWordnet.java Wed Jan  5 11:16:40 2011
@@ -26,13 +26,12 @@ import org.apache.lucene.search.BooleanC
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.search.Searcher;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.LuceneTestCase;
 
 public class TestWordnet extends LuceneTestCase {
-  private Searcher searcher;
+  private IndexSearcher searcher;
   private Directory dir;
   
   String storePathName = new File(TEMP_DIR,"testLuceneWordnet").getAbsolutePath();

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/document/Document.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/document/Document.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/document/Document.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/document/Document.java Wed Jan  5 11:16:40 2011
@@ -19,7 +19,6 @@ package org.apache.lucene.document;
 
 import java.util.*;             // for javadoc
 import org.apache.lucene.search.ScoreDoc; // for javadoc
-import org.apache.lucene.search.Searcher;  // for javadoc
 import org.apache.lucene.index.IndexReader;  // for javadoc
 
 /** Documents are the unit of indexing and search.
@@ -32,8 +31,7 @@ import org.apache.lucene.index.IndexRead
  *
  * <p>Note that fields which are <i>not</i> {@link Fieldable#isStored() stored} are
  * <i>not</i> available in documents retrieved from the index, e.g. with {@link
- * ScoreDoc#doc}, {@link Searcher#doc(int)} or {@link
- * IndexReader#document(int)}.
+ * ScoreDoc#doc} or {@link IndexReader#document(int)}.
  */
 
 public final class Document implements java.io.Serializable {

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/LogMergePolicy.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/LogMergePolicy.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/LogMergePolicy.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/index/LogMergePolicy.java Wed Jan  5 11:16:40 2011
@@ -338,10 +338,18 @@ public abstract class LogMergePolicy ext
       int maxNumSegments, Set<SegmentInfo> segmentsToOptimize) throws IOException {
 
     assert maxNumSegments > 0;
+    if (verbose()) {
+      message("findMergesForOptimize: maxNumSegs=" + maxNumSegments + " segsToOptimize= "+ segmentsToOptimize);
+    }
 
     // If the segments are already optimized (e.g. there's only 1 segment), or
     // there are <maxNumSegements, all optimized, nothing to do.
-    if (isOptimized(infos, maxNumSegments, segmentsToOptimize)) return null;
+    if (isOptimized(infos, maxNumSegments, segmentsToOptimize)) {
+      if (verbose()) {
+        message("already optimized; skip");
+      }
+      return null;
+    }
     
     // Find the newest (rightmost) segment that needs to
     // be optimized (other segments may have been flushed
@@ -355,10 +363,20 @@ public abstract class LogMergePolicy ext
       }
     }
 
-    if (last == 0) return null;
+    if (last == 0) {
+      if (verbose()) {
+        message("last == 0; skip");
+      }
+      return null;
+    }
     
     // There is only one segment already, and it is optimized
-    if (maxNumSegments == 1 && last == 1 && isOptimized(infos.info(0))) return null;
+    if (maxNumSegments == 1 && last == 1 && isOptimized(infos.info(0))) {
+      if (verbose()) {
+        message("already 1 seg; skip");
+      }
+      return null;
+    }
 
     // Check if there are any segments above the threshold
     boolean anyTooLarge = false;

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/BooleanQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/BooleanQuery.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/BooleanQuery.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/BooleanQuery.java Wed Jan  5 11:16:40 2011
@@ -89,7 +89,7 @@ public class BooleanQuery extends Query 
   // Implement coord disabling.
   // Inherit javadoc.
   @Override
-  public Similarity getSimilarity(Searcher searcher) {
+  public Similarity getSimilarity(IndexSearcher searcher) {
     Similarity result = super.getSimilarity(searcher);
     if (disableCoord) {                           // disable coord as requested
       result = new SimilarityDelegator(result) {
@@ -179,7 +179,7 @@ public class BooleanQuery extends Query 
     protected ArrayList<Weight> weights;
     protected int maxCoord;  // num optional + num required
 
-    public BooleanWeight(Searcher searcher)
+    public BooleanWeight(IndexSearcher searcher)
       throws IOException {
       this.similarity = getSimilarity(searcher);
       weights = new ArrayList<Weight>(clauses.size());
@@ -362,7 +362,7 @@ public class BooleanQuery extends Query 
   }
 
   @Override
-  public Weight createWeight(Searcher searcher) throws IOException {
+  public Weight createWeight(IndexSearcher searcher) throws IOException {
     return new BooleanWeight(searcher);
   }
 

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java Wed Jan  5 11:16:40 2011
@@ -100,7 +100,7 @@ public class ConstantScoreQuery extends 
     private float queryNorm;
     private float queryWeight;
     
-    public ConstantWeight(Searcher searcher) throws IOException {
+    public ConstantWeight(IndexSearcher searcher) throws IOException {
       this.similarity = getSimilarity(searcher);
       this.innerWeight = (query == null) ? null : query.createWeight(searcher);
     }
@@ -256,7 +256,7 @@ public class ConstantScoreQuery extends 
   }
 
   @Override
-  public Weight createWeight(Searcher searcher) throws IOException {
+  public Weight createWeight(IndexSearcher searcher) throws IOException {
     return new ConstantScoreQuery.ConstantWeight(searcher);
   }
 

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java Wed Jan  5 11:16:40 2011
@@ -101,7 +101,7 @@ public class DisjunctionMaxQuery extends
     protected ArrayList<Weight> weights = new ArrayList<Weight>();  // The Weight's for our subqueries, in 1-1 correspondence with disjuncts
 
     /* Construct the Weight for this Query searched by searcher.  Recursively construct subquery weights. */
-    public DisjunctionMaxWeight(Searcher searcher) throws IOException {
+    public DisjunctionMaxWeight(IndexSearcher searcher) throws IOException {
       this.similarity = searcher.getSimilarity();
       for (Query disjunctQuery : disjuncts) {
         weights.add(disjunctQuery.createWeight(searcher));
@@ -180,7 +180,7 @@ public class DisjunctionMaxQuery extends
 
   /* Create the Weight used to score us */
   @Override
-  public Weight createWeight(Searcher searcher) throws IOException {
+  public Weight createWeight(IndexSearcher searcher) throws IOException {
     return new DisjunctionMaxWeight(searcher);
   }
 

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/FilteredQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/FilteredQuery.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/FilteredQuery.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/FilteredQuery.java Wed Jan  5 11:16:40 2011
@@ -59,7 +59,7 @@ extends Query {
    * This is accomplished by overriding the Scorer returned by the Weight.
    */
   @Override
-  public Weight createWeight(final Searcher searcher) throws IOException {
+  public Weight createWeight(final IndexSearcher searcher) throws IOException {
     final Weight weight = query.createWeight (searcher);
     final Similarity similarity = query.getSimilarity(searcher);
     return new Weight() {

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/IndexSearcher.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/IndexSearcher.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/IndexSearcher.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/IndexSearcher.java Wed Jan  5 11:16:40 2011
@@ -19,7 +19,17 @@ package org.apache.lucene.search;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorCompletionService;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.FieldSelector;
@@ -28,6 +38,7 @@ import org.apache.lucene.index.IndexRead
 import org.apache.lucene.index.Term;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.ReaderUtil;
+import org.apache.lucene.util.ThreadInterruptedException;
 
 /** Implements search over a single IndexReader.
  *
@@ -44,14 +55,19 @@ import org.apache.lucene.util.ReaderUtil
  * synchronize on the <code>IndexSearcher</code> instance;
  * use your own (non-Lucene) objects instead.</p>
  */
-public class IndexSearcher extends Searcher {
+public class IndexSearcher {
   IndexReader reader;
   private boolean closeReader;
   
   // NOTE: these members might change in incompatible ways
   // in the next release
-  protected IndexReader[] subReaders;
-  protected int[] docStarts;
+  protected final IndexReader[] subReaders;
+  protected final IndexSearcher[] subSearchers;
+  protected final int[] docStarts;
+  private final ExecutorService executor;
+
+  /** The Similarity implementation used by this searcher. */
+  private Similarity similarity = Similarity.getDefault();
 
   /** Creates a searcher searching the index in the named
    *  directory, with readOnly=true
@@ -60,7 +76,7 @@ public class IndexSearcher extends Searc
    * @throws IOException if there is a low-level IO error
    */
   public IndexSearcher(Directory path) throws CorruptIndexException, IOException {
-    this(IndexReader.open(path, true), true);
+    this(IndexReader.open(path, true), true, null);
   }
 
   /** Creates a searcher searching the index in the named
@@ -75,12 +91,27 @@ public class IndexSearcher extends Searc
    * @throws IOException if there is a low-level IO error
    */
   public IndexSearcher(Directory path, boolean readOnly) throws CorruptIndexException, IOException {
-    this(IndexReader.open(path, readOnly), true);
+    this(IndexReader.open(path, readOnly), true, null);
   }
 
   /** Creates a searcher searching the provided index. */
   public IndexSearcher(IndexReader r) {
-    this(r, false);
+    this(r, false, null);
+  }
+
+  /** Runs searches for each segment separately, using the
+   *  provided ExecutorService.  IndexSearcher will not
+   *  shutdown/awaitTermination this ExecutorService on
+   *  close; you must do so, eventually, on your own.  NOTE:
+   *  if you are using {@link NIOFSDirectory}, do not use
+   *  the shutdownNow method of ExecutorService as this uses
+   *  Thread.interrupt under-the-hood which can silently
+   *  close file descriptors (see <a
+   *  href="https://issues.apache.org/jira/browse/LUCENE-2239">LUCENE-2239</a>).
+   * 
+   * @lucene.experimental */
+  public IndexSearcher(IndexReader r, ExecutorService executor) {
+    this(r, false, executor);
   }
 
   /** Expert: directly specify the reader, subReaders and
@@ -91,21 +122,58 @@ public class IndexSearcher extends Searc
     this.reader = reader;
     this.subReaders = subReaders;
     this.docStarts = docStarts;
+    subSearchers = new IndexSearcher[subReaders.length];
+    for(int i=0;i<subReaders.length;i++) {
+      subSearchers[i] = new IndexSearcher(subReaders[i]);
+    }
     closeReader = false;
+    executor = null;
   }
   
-  private IndexSearcher(IndexReader r, boolean closeReader) {
+  /** Expert: directly specify the reader, subReaders and
+   *  their docID starts, and an ExecutorService.  In this
+   *  case, each segment will be separately searched using the
+   *  ExecutorService.  IndexSearcher will not
+   *  shutdown/awaitTermination this ExecutorService on
+   *  close; you must do so, eventually, on your own.  NOTE:
+   *  if you are using {@link NIOFSDirectory}, do not use
+   *  the shutdownNow method of ExecutorService as this uses
+   *  Thread.interrupt under-the-hood which can silently
+   *  close file descriptors (see <a
+   *  href="https://issues.apache.org/jira/browse/LUCENE-2239">LUCENE-2239</a>).
+   * 
+   * @lucene.experimental */
+  public IndexSearcher(IndexReader reader, IndexReader[] subReaders, int[] docStarts, ExecutorService executor) {
+    this.reader = reader;
+    this.subReaders = subReaders;
+    this.docStarts = docStarts;
+    subSearchers = new IndexSearcher[subReaders.length];
+    for(int i=0;i<subReaders.length;i++) {
+      subSearchers[i] = new IndexSearcher(subReaders[i]);
+    }
+    closeReader = false;
+    this.executor = executor;
+  }
+
+  private IndexSearcher(IndexReader r, boolean closeReader, ExecutorService executor) {
     reader = r;
+    this.executor = executor;
     this.closeReader = closeReader;
 
     List<IndexReader> subReadersList = new ArrayList<IndexReader>();
     gatherSubReaders(subReadersList, reader);
     subReaders = subReadersList.toArray(new IndexReader[subReadersList.size()]);
     docStarts = new int[subReaders.length];
+    subSearchers = new IndexSearcher[subReaders.length];
     int maxDoc = 0;
     for (int i = 0; i < subReaders.length; i++) {
       docStarts[i] = maxDoc;
       maxDoc += subReaders[i].maxDoc();
+      if (subReaders[i] == r) {
+        subSearchers[i] = this;
+      } else {
+        subSearchers[i] = new IndexSearcher(subReaders[i]);
+      }
     }
   }
 
@@ -118,59 +186,219 @@ public class IndexSearcher extends Searc
     return reader;
   }
 
+  /** Returns the atomic subReaders used by this searcher. */
+  public IndexReader[] getSubReaders() {
+    return subReaders;
+  }
+
+  /** Expert: Returns one greater than the largest possible document number.
+   * 
+   * @see org.apache.lucene.index.IndexReader#maxDoc()
+   */
+  public int maxDoc() {
+    return reader.maxDoc();
+  }
+
+  /** Returns total docFreq for this term. */
+  public int docFreq(final Term term) throws IOException {
+    if (executor == null) {
+      return reader.docFreq(term);
+    } else {
+      final ExecutionHelper<Integer> runner = new ExecutionHelper<Integer>(executor);
+      for(int i = 0; i < subReaders.length; i++) {
+        final IndexSearcher searchable = subSearchers[i];
+        runner.submit(new Callable<Integer>() {
+            public Integer call() throws IOException {
+              return Integer.valueOf(searchable.docFreq(term));
+            }
+          });
+      }
+      int docFreq = 0;
+      for (Integer num : runner) {
+        docFreq += num.intValue();
+      }
+      return docFreq;
+    }
+  }
+
+  /* Sugar for .getIndexReader().document(docID) */
+  public Document doc(int docID) throws CorruptIndexException, IOException {
+    return reader.document(docID);
+  }
+  
+  /* Sugar for .getIndexReader().document(docID, fieldSelector) */
+  public Document doc(int docID, FieldSelector fieldSelector) throws CorruptIndexException, IOException {
+    return reader.document(docID, fieldSelector);
+  }
+  
+  /** Expert: Set the Similarity implementation used by this Searcher.
+   *
+   * @see Similarity#setDefault(Similarity)
+   */
+  public void setSimilarity(Similarity similarity) {
+    this.similarity = similarity;
+  }
+
+  public Similarity getSimilarity() {
+    return similarity;
+  }
+
   /**
    * Note that the underlying IndexReader is not closed, if
    * IndexSearcher was constructed with IndexSearcher(IndexReader r).
    * If the IndexReader was supplied implicitly by specifying a directory, then
-   * the IndexReader gets closed.
+   * the IndexReader is closed.
    */
-  @Override
   public void close() throws IOException {
-    if(closeReader)
+    if (closeReader) {
       reader.close();
+    }
   }
 
-  // inherit javadoc
-  @Override
-  public int docFreq(Term term) throws IOException {
-    return reader.docFreq(term);
+  /** Finds the top <code>n</code>
+   * hits for <code>query</code>.
+   *
+   * @throws BooleanQuery.TooManyClauses
+   */
+  public TopDocs search(Query query, int n)
+    throws IOException {
+    return search(query, null, n);
   }
 
-  // inherit javadoc
-  @Override
-  public Document doc(int i) throws CorruptIndexException, IOException {
-    return reader.document(i);
+
+  /** Finds the top <code>n</code>
+   * hits for <code>query</code>, applying <code>filter</code> if non-null.
+   *
+   * @throws BooleanQuery.TooManyClauses
+   */
+  public TopDocs search(Query query, Filter filter, int n)
+    throws IOException {
+    return search(createWeight(query), filter, n);
   }
-  
-  // inherit javadoc
-  @Override
-  public Document doc(int i, FieldSelector fieldSelector) throws CorruptIndexException, IOException {
-	    return reader.document(i, fieldSelector);
+
+  /** Lower-level search API.
+   *
+   * <p>{@link Collector#collect(int)} is called for every matching
+   * document.
+   * <br>Collector-based access to remote indexes is discouraged.
+   *
+   * <p>Applications should only use this if they need <i>all</i> of the
+   * matching documents.  The high-level search API ({@link
+   * Searcher#search(Query, Filter, int)}) is usually more efficient, as it skips
+   * non-high-scoring hits.
+   *
+   * @param query to match documents
+   * @param filter if non-null, used to permit documents to be collected.
+   * @param results to receive hits
+   * @throws BooleanQuery.TooManyClauses
+   */
+  public void search(Query query, Filter filter, Collector results)
+    throws IOException {
+    search(createWeight(query), filter, results);
+  }
+
+  /** Lower-level search API.
+  *
+  * <p>{@link Collector#collect(int)} is called for every matching document.
+  *
+  * <p>Applications should only use this if they need <i>all</i> of the
+  * matching documents.  The high-level search API ({@link
+  * Searcher#search(Query, int)}) is usually more efficient, as it skips
+  * non-high-scoring hits.
+  * <p>Note: The <code>score</code> passed to this method is a raw score.
+  * In other words, the score will not necessarily be a float whose value is
+  * between 0 and 1.
+  * @throws BooleanQuery.TooManyClauses
+  */
+  public void search(Query query, Collector results)
+    throws IOException {
+    search(createWeight(query), null, results);
   }
   
-  // inherit javadoc
-  @Override
-  public int maxDoc() throws IOException {
-    return reader.maxDoc();
+  /** Search implementation with arbitrary sorting.  Finds
+   * the top <code>n</code> hits for <code>query</code>, applying
+   * <code>filter</code> if non-null, and sorting the hits by the criteria in
+   * <code>sort</code>.
+   * 
+   * <p>NOTE: this does not compute scores by default; use
+   * {@link IndexSearcher#setDefaultFieldSortScoring} to
+   * enable scoring.
+   *
+   * @throws BooleanQuery.TooManyClauses
+   */
+  public TopFieldDocs search(Query query, Filter filter, int n,
+                             Sort sort) throws IOException {
+    return search(createWeight(query), filter, n, sort);
   }
 
-  // inherit javadoc
-  @Override
-  public TopDocs search(Weight weight, Filter filter, int nDocs) throws IOException {
+  /**
+   * Search implementation with arbitrary sorting and no filter.
+   * @param query The query to search for
+   * @param n Return only the top n results
+   * @param sort The {@link org.apache.lucene.search.Sort} object
+   * @return The top docs, sorted according to the supplied {@link org.apache.lucene.search.Sort} instance
+   * @throws IOException
+   */
+  public TopFieldDocs search(Query query, int n,
+                             Sort sort) throws IOException {
+    return search(createWeight(query), null, n, sort);
+  }
 
-    int limit = reader.maxDoc();
-    if (limit == 0) {
-      limit = 1;
-    }
-    nDocs = Math.min(nDocs, limit);
+  /** Expert: Low-level search implementation.  Finds the top <code>n</code>
+   * hits for <code>query</code>, applying <code>filter</code> if non-null.
+   *
+   * <p>Applications should usually call {@link Searcher#search(Query,int)} or
+   * {@link Searcher#search(Query,Filter,int)} instead.
+   * @throws BooleanQuery.TooManyClauses
+   */
+  protected TopDocs search(Weight weight, Filter filter, int nDocs) throws IOException {
+
+    if (executor == null) {
+      // single thread
+      int limit = reader.maxDoc();
+      if (limit == 0) {
+        limit = 1;
+      }
+      nDocs = Math.min(nDocs, limit);
+      TopScoreDocCollector collector = TopScoreDocCollector.create(nDocs, !weight.scoresDocsOutOfOrder());
+      search(weight, filter, collector);
+      return collector.topDocs();
+    } else {
+      final HitQueue hq = new HitQueue(nDocs, false);
+      final Lock lock = new ReentrantLock();
+      final ExecutionHelper<TopDocs> runner = new ExecutionHelper<TopDocs>(executor);
+    
+      for (int i = 0; i < subReaders.length; i++) { // search each sub
+        runner.submit(
+                      new MultiSearcherCallableNoSort(lock, subSearchers[i], weight, filter, nDocs, hq, i, docStarts));
+      }
+
+      int totalHits = 0;
+      float maxScore = Float.NEGATIVE_INFINITY;
+      for (final TopDocs topDocs : runner) {
+        totalHits += topDocs.totalHits;
+        maxScore = Math.max(maxScore, topDocs.getMaxScore());
+      }
 
-    TopScoreDocCollector collector = TopScoreDocCollector.create(nDocs, !weight.scoresDocsOutOfOrder());
-    search(weight, filter, collector);
-    return collector.topDocs();
+      final ScoreDoc[] scoreDocs = new ScoreDoc[hq.size()];
+      for (int i = hq.size() - 1; i >= 0; i--) // put docs in array
+        scoreDocs[i] = hq.pop();
+
+      return new TopDocs(totalHits, scoreDocs, maxScore);
+    }
   }
 
-  @Override
-  public TopFieldDocs search(Weight weight, Filter filter,
+  /** Expert: Low-level search implementation with arbitrary sorting.  Finds
+   * the top <code>n</code> hits for <code>query</code>, applying
+   * <code>filter</code> if non-null, and sorting the hits by the criteria in
+   * <code>sort</code>.
+   *
+   * <p>Applications should usually call {@link
+   * Searcher#search(Query,Filter,int,Sort)} instead.
+   * 
+   * @throws BooleanQuery.TooManyClauses
+   */
+  protected TopFieldDocs search(Weight weight, Filter filter,
       final int nDocs, Sort sort) throws IOException {
     return search(weight, filter, nDocs, sort, true);
   }
@@ -186,26 +414,74 @@ public class IndexSearcher extends Searc
    * then pass that to {@link #search(Weight, Filter,
    * Collector)}.</p>
    */
-  public TopFieldDocs search(Weight weight, Filter filter, int nDocs,
+  protected TopFieldDocs search(Weight weight, Filter filter, int nDocs,
                              Sort sort, boolean fillFields)
       throws IOException {
 
-    int limit = reader.maxDoc();
-    if (limit == 0) {
-      limit = 1;
-    }
-    nDocs = Math.min(nDocs, limit);
+    if (sort == null) throw new NullPointerException();
+
+    if (executor == null) {
+      // single thread
+      int limit = reader.maxDoc();
+      if (limit == 0) {
+        limit = 1;
+      }
+      nDocs = Math.min(nDocs, limit);
+
+      TopFieldCollector collector = TopFieldCollector.create(sort, nDocs,
+                                                             fillFields, fieldSortDoTrackScores, fieldSortDoMaxScore, !weight.scoresDocsOutOfOrder());
+      search(weight, filter, collector);
+      return (TopFieldDocs) collector.topDocs();
+    } else {
+      // TODO: make this respect fillFields
+      final FieldDocSortedHitQueue hq = new FieldDocSortedHitQueue(nDocs);
+      final Lock lock = new ReentrantLock();
+      final ExecutionHelper<TopFieldDocs> runner = new ExecutionHelper<TopFieldDocs>(executor);
+      for (int i = 0; i < subReaders.length; i++) { // search each sub
+        runner.submit(
+                      new MultiSearcherCallableWithSort(lock, subSearchers[i], weight, filter, nDocs, hq, sort, i, docStarts));
+      }
+      int totalHits = 0;
+      float maxScore = Float.NEGATIVE_INFINITY;
+      for (final TopFieldDocs topFieldDocs : runner) {
+        totalHits += topFieldDocs.totalHits;
+        maxScore = Math.max(maxScore, topFieldDocs.getMaxScore());
+      }
+      final ScoreDoc[] scoreDocs = new ScoreDoc[hq.size()];
+      for (int i = hq.size() - 1; i >= 0; i--) // put docs in array
+        scoreDocs[i] = hq.pop();
 
-    TopFieldCollector collector = TopFieldCollector.create(sort, nDocs,
-        fillFields, fieldSortDoTrackScores, fieldSortDoMaxScore, !weight.scoresDocsOutOfOrder());
-    search(weight, filter, collector);
-    return (TopFieldDocs) collector.topDocs();
+      return new TopFieldDocs(totalHits, scoreDocs, hq.getFields(), maxScore);
+    }
   }
 
-  @Override
-  public void search(Weight weight, Filter filter, Collector collector)
+  /**
+   * Lower-level search API.
+   * 
+   * <p>
+   * {@link Collector#collect(int)} is called for every document. <br>
+   * Collector-based access to remote indexes is discouraged.
+   * 
+   * <p>
+   * Applications should only use this if they need <i>all</i> of the matching
+   * documents. The high-level search API ({@link Searcher#search(Query,int)}) is
+   * usually more efficient, as it skips non-high-scoring hits.
+   * 
+   * @param weight
+   *          to match documents
+   * @param filter
+   *          if non-null, used to permit documents to be collected.
+   * @param collector
+   *          to receive hits
+   * @throws BooleanQuery.TooManyClauses
+   */
+  protected void search(Weight weight, Filter filter, Collector collector)
       throws IOException {
-    
+
+    // TODO: should we make this
+    // threaded...?  the Collector could be sync'd?
+
+    // always use single thread:
     if (filter == null) {
       for (int i = 0; i < subReaders.length; i++) { // search each subreader
         collector.setNextReader(subReaders[i], docStarts[i]);
@@ -268,7 +544,9 @@ public class IndexSearcher extends Searc
     }
   }
 
-  @Override
+  /** Expert: called to re-write queries into primitive queries.
+   * @throws BooleanQuery.TooManyClauses
+   */
   public Query rewrite(Query original) throws IOException {
     Query query = original;
     for (Query rewrittenQuery = query.rewrite(reader); rewrittenQuery != query;
@@ -278,8 +556,30 @@ public class IndexSearcher extends Searc
     return query;
   }
 
-  @Override
-  public Explanation explain(Weight weight, int doc) throws IOException {
+  /** Returns an Explanation that describes how <code>doc</code> scored against
+   * <code>query</code>.
+   *
+   * <p>This is intended to be used in developing Similarity implementations,
+   * and, for good performance, should not be displayed with every hit.
+   * Computing an explanation is as expensive as executing the query over the
+   * entire index.
+   */
+  public Explanation explain(Query query, int doc) throws IOException {
+    return explain(createWeight(query), doc);
+  }
+
+  /** Expert: low-level implementation method
+   * Returns an Explanation that describes how <code>doc</code> scored against
+   * <code>weight</code>.
+   *
+   * <p>This is intended to be used in developing Similarity implementations,
+   * and, for good performance, should not be displayed with every hit.
+   * Computing an explanation is as expensive as executing the query over the
+   * entire index.
+   * <p>Applications should call {@link Searcher#explain(Query, int)}.
+   * @throws BooleanQuery.TooManyClauses
+   */
+  protected Explanation explain(Weight weight, int doc) throws IOException {
     int n = ReaderUtil.subIndex(doc, docStarts);
     int deBasedDoc = doc - docStarts[n];
     
@@ -305,4 +605,175 @@ public class IndexSearcher extends Searc
     fieldSortDoTrackScores = doTrackScores;
     fieldSortDoMaxScore = doMaxScore;
   }
+
+  /**
+   * creates a weight for <code>query</code>
+   * @return new weight
+   */
+  protected Weight createWeight(Query query) throws IOException {
+    return query.weight(this);
+  }
+
+
+  /**
+   * A thread subclass for searching a single searchable 
+   */
+  private static final class MultiSearcherCallableNoSort implements Callable<TopDocs> {
+
+    private final Lock lock;
+    private final IndexSearcher searchable;
+    private final Weight weight;
+    private final Filter filter;
+    private final int nDocs;
+    private final int i;
+    private final HitQueue hq;
+    private final int[] starts;
+
+    public MultiSearcherCallableNoSort(Lock lock, IndexSearcher searchable, Weight weight,
+        Filter filter, int nDocs, HitQueue hq, int i, int[] starts) {
+      this.lock = lock;
+      this.searchable = searchable;
+      this.weight = weight;
+      this.filter = filter;
+      this.nDocs = nDocs;
+      this.hq = hq;
+      this.i = i;
+      this.starts = starts;
+    }
+
+    public TopDocs call() throws IOException {
+      final TopDocs docs = searchable.search (weight, filter, nDocs);
+      final ScoreDoc[] scoreDocs = docs.scoreDocs;
+      for (int j = 0; j < scoreDocs.length; j++) { // merge scoreDocs into hq
+        final ScoreDoc scoreDoc = scoreDocs[j];
+        scoreDoc.doc += starts[i]; // convert doc 
+        //it would be so nice if we had a thread-safe insert 
+        lock.lock();
+        try {
+          if (scoreDoc == hq.insertWithOverflow(scoreDoc))
+            break;
+        } finally {
+          lock.unlock();
+        }
+      }
+      return docs;
+    }
+  }
+
+
+  /**
+   * A thread subclass for searching a single searchable 
+   */
+  private static final class MultiSearcherCallableWithSort implements Callable<TopFieldDocs> {
+
+    private final Lock lock;
+    private final IndexSearcher searchable;
+    private final Weight weight;
+    private final Filter filter;
+    private final int nDocs;
+    private final int i;
+    private final FieldDocSortedHitQueue hq;
+    private final int[] starts;
+    private final Sort sort;
+
+    public MultiSearcherCallableWithSort(Lock lock, IndexSearcher searchable, Weight weight,
+        Filter filter, int nDocs, FieldDocSortedHitQueue hq, Sort sort, int i, int[] starts) {
+      this.lock = lock;
+      this.searchable = searchable;
+      this.weight = weight;
+      this.filter = filter;
+      this.nDocs = nDocs;
+      this.hq = hq;
+      this.i = i;
+      this.starts = starts;
+      this.sort = sort;
+    }
+
+    public TopFieldDocs call() throws IOException {
+      final TopFieldDocs docs = searchable.search (weight, filter, nDocs, sort);
+      // If one of the Sort fields is FIELD_DOC, need to fix its values, so that
+      // it will break ties by doc Id properly. Otherwise, it will compare to
+      // 'relative' doc Ids, that belong to two different searchables.
+      for (int j = 0; j < docs.fields.length; j++) {
+        if (docs.fields[j].getType() == SortField.DOC) {
+          // iterate over the score docs and change their fields value
+          for (int j2 = 0; j2 < docs.scoreDocs.length; j2++) {
+            FieldDoc fd = (FieldDoc) docs.scoreDocs[j2];
+            fd.fields[j] = Integer.valueOf(((Integer) fd.fields[j]).intValue() + starts[i]);
+          }
+          break;
+        }
+      }
+
+      lock.lock();
+      try {
+        hq.setFields(docs.fields);
+      } finally {
+        lock.unlock();
+      }
+
+      final ScoreDoc[] scoreDocs = docs.scoreDocs;
+      for (int j = 0; j < scoreDocs.length; j++) { // merge scoreDocs into hq
+        final FieldDoc fieldDoc = (FieldDoc) scoreDocs[j];
+        fieldDoc.doc += starts[i]; // convert doc 
+        //it would be so nice if we had a thread-safe insert 
+        lock.lock();
+        try {
+          if (fieldDoc == hq.insertWithOverflow(fieldDoc))
+            break;
+        } finally {
+          lock.unlock();
+        }
+      }
+      return docs;
+    }
+  }
+
+  /**
+   * A helper class that wraps a {@link CompletionService} and provides an
+   * iterable interface to the completed {@link Callable} instances.
+   * 
+   * @param <T>
+   *          the type of the {@link Callable} return value
+   */
+  private static final class ExecutionHelper<T> implements Iterator<T>, Iterable<T> {
+    private final CompletionService<T> service;
+    private int numTasks;
+
+    ExecutionHelper(final Executor executor) {
+      this.service = new ExecutorCompletionService<T>(executor);
+    }
+
+    public boolean hasNext() {
+      return numTasks > 0;
+    }
+
+    public void submit(Callable<T> task) {
+      this.service.submit(task);
+      ++numTasks;
+    }
+
+    public T next() {
+      if(!this.hasNext())
+        throw new NoSuchElementException();
+      try {
+        return service.take().get();
+      } catch (InterruptedException e) {
+        throw new ThreadInterruptedException(e);
+      } catch (ExecutionException e) {
+        throw new RuntimeException(e);
+      } finally {
+        --numTasks;
+      }
+    }
+
+    public void remove() {
+      throw new UnsupportedOperationException();
+    }
+
+    public Iterator<T> iterator() {
+      // use the shortcut here - this is only used in a privat context
+      return this;
+    }
+  }
 }

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/MatchAllDocsQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/MatchAllDocsQuery.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/MatchAllDocsQuery.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/MatchAllDocsQuery.java Wed Jan  5 11:16:40 2011
@@ -95,7 +95,7 @@ public class MatchAllDocsQuery extends Q
     private float queryWeight;
     private float queryNorm;
 
-    public MatchAllDocsWeight(Searcher searcher) {
+    public MatchAllDocsWeight(IndexSearcher searcher) {
       this.similarity = searcher.getSimilarity();
     }
 
@@ -147,7 +147,7 @@ public class MatchAllDocsQuery extends Q
   }
 
   @Override
-  public Weight createWeight(Searcher searcher) {
+  public Weight createWeight(IndexSearcher searcher) {
     return new MatchAllDocsWeight(searcher);
   }
 

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java Wed Jan  5 11:16:40 2011
@@ -134,7 +134,7 @@ public class MultiPhraseQuery extends Qu
     private float queryNorm;
     private float queryWeight;
 
-    public MultiPhraseWeight(Searcher searcher)
+    public MultiPhraseWeight(IndexSearcher searcher)
       throws IOException {
       this.similarity = getSimilarity(searcher);
 
@@ -324,7 +324,7 @@ public class MultiPhraseQuery extends Qu
   }
 
   @Override
-  public Weight createWeight(Searcher searcher) throws IOException {
+  public Weight createWeight(IndexSearcher searcher) throws IOException {
     return new MultiPhraseWeight(searcher);
   }
 

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/PhraseQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/PhraseQuery.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/PhraseQuery.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/PhraseQuery.java Wed Jan  5 11:16:40 2011
@@ -143,7 +143,7 @@ public class PhraseQuery extends Query {
     private float queryWeight;
     private IDFExplanation idfExp;
 
-    public PhraseWeight(Searcher searcher)
+    public PhraseWeight(IndexSearcher searcher)
       throws IOException {
       this.similarity = getSimilarity(searcher);
 
@@ -311,7 +311,7 @@ public class PhraseQuery extends Query {
   }
 
   @Override
-  public Weight createWeight(Searcher searcher) throws IOException {
+  public Weight createWeight(IndexSearcher searcher) throws IOException {
     if (terms.size() == 1) {			  // optimize one-term case
       Term term = terms.get(0);
       Query termQuery = new TermQuery(term);

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/Query.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/Query.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/Query.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/Query.java Wed Jan  5 11:16:40 2011
@@ -19,8 +19,6 @@ package org.apache.lucene.search;
 
 import java.io.IOException;
 
-import java.util.HashSet;
-
 import java.util.Set;
 
 import org.apache.lucene.index.IndexReader;
@@ -89,14 +87,14 @@ public abstract class Query implements j
    * <p>
    * Only implemented by primitive queries, which re-write to themselves.
    */
-  public Weight createWeight(Searcher searcher) throws IOException {
+  public Weight createWeight(IndexSearcher searcher) throws IOException {
     throw new UnsupportedOperationException();
   }
 
   /**
    * Expert: Constructs and initializes a Weight for a top-level query.
    */
-  public Weight weight(Searcher searcher) throws IOException {
+  public Weight weight(IndexSearcher searcher) throws IOException {
     Query query = searcher.rewrite(this);
     Weight weight = query.createWeight(searcher);
     float sum = weight.sumOfSquaredWeights();
@@ -116,52 +114,6 @@ public abstract class Query implements j
     return this;
   }
   
-
-  /** Expert: called when re-writing queries under MultiSearcher.
-   *
-   * Create a single query suitable for use by all subsearchers (in 1-1
-   * correspondence with queries). This is an optimization of the OR of
-   * all queries. We handle the common optimization cases of equal
-   * queries and overlapping clauses of boolean OR queries (as generated
-   * by MultiTermQuery.rewrite()).
-   * Be careful overriding this method as queries[0] determines which
-   * method will be called and is not necessarily of the same type as
-   * the other queries.
-  */
-  public Query combine(Query[] queries) {
-    HashSet<Query> uniques = new HashSet<Query>();
-    for (int i = 0; i < queries.length; i++) {
-      Query query = queries[i];
-      BooleanClause[] clauses = null;
-      // check if we can split the query into clauses
-      boolean splittable = (query instanceof BooleanQuery);
-      if(splittable){
-        BooleanQuery bq = (BooleanQuery) query;
-        splittable = bq.isCoordDisabled();
-        clauses = bq.getClauses();
-        for (int j = 0; splittable && j < clauses.length; j++) {
-          splittable = (clauses[j].getOccur() == BooleanClause.Occur.SHOULD);
-        }
-      }
-      if(splittable){
-        for (int j = 0; j < clauses.length; j++) {
-          uniques.add(clauses[j].getQuery());
-        }
-      } else {
-        uniques.add(query);
-      }
-    }
-    // optimization: if we have just one query, just return it
-    if(uniques.size() == 1){
-        return uniques.iterator().next();
-    }
-    BooleanQuery result = new BooleanQuery(true);
-    for (final Query query : uniques)
-      result.add(query, BooleanClause.Occur.SHOULD);
-    return result;
-  }
-  
-
   /**
    * Expert: adds all terms occurring in this query to the terms set. Only
    * works if this query is in its {@link #rewrite rewritten} form.
@@ -174,35 +126,11 @@ public abstract class Query implements j
   }
   
 
-
-  /** Expert: merges the clauses of a set of BooleanQuery's into a single
-   * BooleanQuery.
-   *
-   *<p>A utility for use by {@link #combine(Query[])} implementations.
-   */
-  public static Query mergeBooleanQueries(BooleanQuery... queries) {
-    HashSet<BooleanClause> allClauses = new HashSet<BooleanClause>();
-    for (BooleanQuery booleanQuery : queries) {
-      for (BooleanClause clause : booleanQuery) {
-        allClauses.add(clause);
-      }
-    }
-
-    boolean coordDisabled =
-      queries.length==0? false : queries[0].isCoordDisabled();
-    BooleanQuery result = new BooleanQuery(coordDisabled);
-    for(BooleanClause clause2 : allClauses) {
-      result.add(clause2);
-    }
-    return result;
-  }
-  
-
   /** Expert: Returns the Similarity implementation to be used for this query.
    * Subclasses may override this method to specify their own Similarity
    * implementation, perhaps one that delegates through that of the Searcher.
    * By default the Searcher's Similarity implementation is returned.*/
-  public Similarity getSimilarity(Searcher searcher) {
+  public Similarity getSimilarity(IndexSearcher searcher) {
     return searcher.getSimilarity();
   }
 

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/Similarity.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/Similarity.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/Similarity.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/Similarity.java Wed Jan  5 11:16:40 2011
@@ -722,7 +722,7 @@ public abstract class Similarity impleme
              and an explanation for the term.
    * @throws IOException
    */
-  public IDFExplanation idfExplain(final Term term, final Searcher searcher, int docFreq) throws IOException {
+  public IDFExplanation idfExplain(final Term term, final IndexSearcher searcher, int docFreq) throws IOException {
     final int df = docFreq;
     final int max = searcher.maxDoc();
     final float idf = idf(df, max);
@@ -743,7 +743,7 @@ public abstract class Similarity impleme
    * #idfExplain(Term,Searcher,int)} by passing
    * <code>searcher.docFreq(term)</code> as the docFreq.
    */
-  public IDFExplanation idfExplain(final Term term, final Searcher searcher) throws IOException {
+  public IDFExplanation idfExplain(final Term term, final IndexSearcher searcher) throws IOException {
     return idfExplain(term, searcher, searcher.docFreq(term));
    }
 
@@ -761,7 +761,7 @@ public abstract class Similarity impleme
    *         for each term.
    * @throws IOException
    */
-  public IDFExplanation idfExplain(Collection<Term> terms, Searcher searcher) throws IOException {
+  public IDFExplanation idfExplain(Collection<Term> terms, IndexSearcher searcher) throws IOException {
     final int max = searcher.maxDoc();
     float idf = 0.0f;
     final StringBuilder exp = new StringBuilder();

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/TermQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/TermQuery.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/TermQuery.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/TermQuery.java Wed Jan  5 11:16:40 2011
@@ -41,7 +41,7 @@ public class TermQuery extends Query {
     private float queryWeight;
     private IDFExplanation idfExp;
 
-    public TermWeight(Searcher searcher)
+    public TermWeight(IndexSearcher searcher)
       throws IOException {
       this.similarity = getSimilarity(searcher);
       if (docFreq != -1) {
@@ -180,7 +180,7 @@ public class TermQuery extends Query {
   public Term getTerm() { return term; }
 
   @Override
-  public Weight createWeight(Searcher searcher) throws IOException {
+  public Weight createWeight(IndexSearcher searcher) throws IOException {
     return new TermWeight(searcher);
   }
 

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java Wed Jan  5 11:16:40 2011
@@ -28,7 +28,7 @@ import org.apache.lucene.search.Explanat
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.search.Scorer;
-import org.apache.lucene.search.Searcher;
+import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Similarity;
 import org.apache.lucene.util.ToStringUtils;
 
@@ -187,7 +187,7 @@ public class CustomScoreQuery extends Qu
     Weight[] valSrcWeights;
     boolean qStrict;
 
-    public CustomWeight(Searcher searcher) throws IOException {
+    public CustomWeight(IndexSearcher searcher) throws IOException {
       this.similarity = getSimilarity(searcher);
       this.subQueryWeight = subQuery.weight(searcher);
       this.valSrcWeights = new Weight[valSrcQueries.length];
@@ -350,7 +350,7 @@ public class CustomScoreQuery extends Qu
   }
 
   @Override
-  public Weight createWeight(Searcher searcher) throws IOException {
+  public Weight createWeight(IndexSearcher searcher) throws IOException {
     return new CustomWeight(searcher);
   }
 

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java Wed Jan  5 11:16:40 2011
@@ -68,7 +68,7 @@ public class ValueSourceQuery extends Qu
     float queryNorm;
     float queryWeight;
 
-    public ValueSourceWeight(Searcher searcher) {
+    public ValueSourceWeight(IndexSearcher searcher) {
       this.similarity = getSimilarity(searcher);
     }
 
@@ -173,7 +173,7 @@ public class ValueSourceQuery extends Qu
   }
 
   @Override
-  public Weight createWeight(Searcher searcher) {
+  public Weight createWeight(IndexSearcher searcher) {
     return new ValueSourceQuery.ValueSourceWeight(searcher);
   }
 

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java Wed Jan  5 11:16:40 2011
@@ -20,7 +20,7 @@ package org.apache.lucene.search.payload
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.search.Explanation;
 import org.apache.lucene.search.Scorer;
-import org.apache.lucene.search.Searcher;
+import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Similarity;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.search.spans.NearSpansOrdered;
@@ -66,7 +66,7 @@ public class PayloadNearQuery extends Sp
   }
 
   @Override
-  public Weight createWeight(Searcher searcher) throws IOException {
+  public Weight createWeight(IndexSearcher searcher) throws IOException {
     return new PayloadNearSpanWeight(this, searcher);
   }
 
@@ -137,7 +137,7 @@ public class PayloadNearQuery extends Sp
   }
 
   public class PayloadNearSpanWeight extends SpanWeight {
-    public PayloadNearSpanWeight(SpanQuery query, Searcher searcher)
+    public PayloadNearSpanWeight(SpanQuery query, IndexSearcher searcher)
         throws IOException {
       super(query, searcher);
     }

Modified: lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java?rev=1055416&r1=1055415&r2=1055416&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java (original)
+++ lucene/dev/trunk/lucene/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java Wed Jan  5 11:16:40 2011
@@ -20,7 +20,7 @@ package org.apache.lucene.search.payload
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.DocsAndPositionsEnum;
 import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.search.Searcher;
+import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.search.Similarity;
@@ -62,13 +62,13 @@ public class PayloadTermQuery extends Sp
   }
 
   @Override
-  public Weight createWeight(Searcher searcher) throws IOException {
+  public Weight createWeight(IndexSearcher searcher) throws IOException {
     return new PayloadTermWeight(this, searcher);
   }
 
   protected class PayloadTermWeight extends SpanWeight {
 
-    public PayloadTermWeight(PayloadTermQuery query, Searcher searcher)
+    public PayloadTermWeight(PayloadTermQuery query, IndexSearcher searcher)
         throws IOException {
       super(query, searcher);
     }