Clover Coverage Report
Coverage timestamp: Fri May 9 2008 10:54:27 EST
../../../../img/srcFileCovDistChart9.png 37% of files have more coverage
81   290   29   6.23
30   191   0.36   6.5
13     2.23  
2    
 
  ParallelMultiSearcher       Line # 29 48 18 80% 0.8
  MultiSearcherThread       Line # 194 33 11 91.8% 0.9183673
 
  (4)
 
1    package org.apache.lucene.search;
2   
3    /**
4    * Copyright 2004 The Apache Software Foundation
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10    * http://www.apache.org/licenses/LICENSE-2.0
11    *
12    * Unless required by applicable law or agreed to in writing, software
13    * distributed under the License is distributed on an "AS IS" BASIS,
14    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    * See the License for the specific language governing permissions and
16    * limitations under the License.
17    */
18   
19    import java.io.IOException;
20   
21    import org.apache.lucene.index.Term;
22    import org.apache.lucene.util.PriorityQueue;
23   
24    /** Implements parallel search over a set of <code>Searchables</code>.
25    *
26    * <p>Applications usually need only call the inherited {@link #search(Query)}
27    * or {@link #search(Query,Filter)} methods.
28    */
 
29    public class ParallelMultiSearcher extends MultiSearcher {
30   
31    private Searchable[] searchables;
32    private int[] starts;
33   
34    /** Creates a searcher which searches <i>searchables</i>. */
 
35  6 toggle public ParallelMultiSearcher(Searchable[] searchables) throws IOException {
36  6 super(searchables);
37  6 this.searchables=searchables;
38  6 this.starts=getStarts();
39    }
40   
41    /**
42    * TODO: parallelize this one too
43    */
 
44  26 toggle public int docFreq(Term term) throws IOException {
45  26 return super.docFreq(term);
46    }
47   
48    /**
49    * A search implementation which spans a new thread for each
50    * Searchable, waits for each search to complete and merge
51    * the results back together.
52    */
 
53  4 toggle public TopDocs search(Weight weight, Filter filter, int nDocs)
54    throws IOException {
55  4 HitQueue hq = new HitQueue(nDocs);
56  4 int totalHits = 0;
57  4 MultiSearcherThread[] msta =
58    new MultiSearcherThread[searchables.length];
59  12 for (int i = 0; i < searchables.length; i++) { // search each searcher
60    // Assume not too many searchables and cost of creating a thread is by far inferior to a search
61  8 msta[i] =
62    new MultiSearcherThread(
63    searchables[i],
64    weight,
65    filter,
66    nDocs,
67    hq,
68    i,
69    starts,
70    "MultiSearcher thread #" + (i + 1));
71  8 msta[i].start();
72    }
73   
74  12 for (int i = 0; i < searchables.length; i++) {
75  8 try {
76  8 msta[i].join();
77    } catch (InterruptedException ie) {
78  0 ; // TODO: what should we do with this???
79    }
80  8 IOException ioe = msta[i].getIOException();
81  8 if (ioe == null) {
82  8 totalHits += msta[i].hits();
83    } else {
84    // if one search produced an IOException, rethrow it
85  0 throw ioe;
86    }
87    }
88   
89  4 ScoreDoc[] scoreDocs = new ScoreDoc[hq.size()];
90  16 for (int i = hq.size() - 1; i >= 0; i--) // put docs in array
91  12 scoreDocs[i] = (ScoreDoc) hq.pop();
92   
93  4 float maxScore = (totalHits==0) ? Float.NEGATIVE_INFINITY : scoreDocs[0].score;
94   
95  4 return new TopDocs(totalHits, scoreDocs, maxScore);
96    }
97   
98    /**
99    * A search implementation allowing sorting which spans a new thread for each
100    * Searchable, waits for each search to complete and merges
101    * the results back together.
102    */
 
103  22 toggle public TopFieldDocs search(Weight weight, Filter filter, int nDocs, Sort sort)
104    throws IOException {
105    // don't specify the fields - we'll wait to do this until we get results
106  22 FieldDocSortedHitQueue hq = new FieldDocSortedHitQueue (null, nDocs);
107  22 int totalHits = 0;
108  22 MultiSearcherThread[] msta = new MultiSearcherThread[searchables.length];
109  64 for (int i = 0; i < searchables.length; i++) { // search each searcher
110    // Assume not too many searchables and cost of creating a thread is by far inferior to a search
111  42 msta[i] =
112    new MultiSearcherThread(
113    searchables[i],
114    weight,
115    filter,
116    nDocs,
117    hq,
118    sort,
119    i,
120    starts,
121    "MultiSearcher thread #" + (i + 1));
122  42 msta[i].start();
123    }
124   
125  22 float maxScore=Float.NEGATIVE_INFINITY;
126   
127  64 for (int i = 0; i < searchables.length; i++) {
128  42 try {
129  42 msta[i].join();
130    } catch (InterruptedException ie) {
131  0 ; // TODO: what should we do with this???
132    }
133  42 IOException ioe = msta[i].getIOException();
134  42 if (ioe == null) {
135  42 totalHits += msta[i].hits();
136  42 maxScore=Math.max(maxScore, msta[i].getMaxScore());
137    } else {
138    // if one search produced an IOException, rethrow it
139  0 throw ioe;
140    }
141    }
142   
143  22 ScoreDoc[] scoreDocs = new ScoreDoc[hq.size()];
144  187 for (int i = hq.size() - 1; i >= 0; i--) // put docs in array
145  165 scoreDocs[i] = (ScoreDoc) hq.pop();
146   
147  22 return new TopFieldDocs(totalHits, scoreDocs, hq.getFields(), maxScore);
148    }
149   
150    /** Lower-level search API.
151    *
152    * <p>{@link HitCollector#collect(int,float)} is called for every non-zero
153    * scoring document.
154    *
155    * <p>Applications should only use this if they need <i>all</i> of the
156    * matching documents. The high-level search API ({@link
157    * Searcher#search(Query)}) is usually more efficient, as it skips
158    * non-high-scoring hits.
159    *
160    * @param weight to match documents
161    * @param filter if non-null, a bitset used to eliminate some documents
162    * @param results to receive hits
163    *
164    * @todo parallelize this one too
165    */
 
166  0