FileDocCategorySizeDatePackage
ParallelMultiSearcher.javaAPI DocApache Lucene 1.4.39163Tue May 11 19:18:04 BST 2004org.apache.lucene.search

ParallelMultiSearcher

public class ParallelMultiSearcher extends MultiSearcher
Implements parallel search over a set of Searchables.

Applications usually need only call the inherited {@link #search(Query)} or {@link #search(Query,Filter)} methods.

Fields Summary
private Searchable[]
searchables
private int[]
starts
Constructors Summary
public ParallelMultiSearcher(Searchable[] searchables)
Creates a searcher which searches searchables.

    super(searchables);
    this.searchables=searchables;
    this.starts=getStarts();
  
Methods Summary
public intdocFreq(org.apache.lucene.index.Term term)
TODO: parallelize this one too

    int docFreq = 0;
    for (int i = 0; i < searchables.length; i++)
      docFreq += searchables[i].docFreq(term);
    return docFreq;
  
public org.apache.lucene.search.Queryrewrite(org.apache.lucene.search.Query original)

    Query[] queries = new Query[searchables.length];
    for (int i = 0; i < searchables.length; i++) {
      queries[i] = searchables[i].rewrite(original);
    }
    return original.combine(queries);
  
public org.apache.lucene.search.TopDocssearch(org.apache.lucene.search.Query query, org.apache.lucene.search.Filter filter, int nDocs)
A search implementation which spans a new thread for each Searchable, waits for each search to complete and merge the results back together.

    HitQueue hq = new HitQueue(nDocs);
    int totalHits = 0;
    MultiSearcherThread[] msta =
      new MultiSearcherThread[searchables.length];
    for (int i = 0; i < searchables.length; i++) { // search each searcher
      // Assume not too many searchables and cost of creating a thread is by far inferior to a search
      msta[i] =
        new MultiSearcherThread(
                                searchables[i],
                                query,
                                filter,
                                nDocs,
                                hq,
                                i,
                                starts,
                                "MultiSearcher thread #" + (i + 1));
      msta[i].start();
    }

    for (int i = 0; i < searchables.length; i++) {
      try {
        msta[i].join();
      } catch (InterruptedException ie) {
        ; // TODO: what should we do with this???
      }
      IOException ioe = msta[i].getIOException();
      if (ioe == null) {
        totalHits += msta[i].hits();
      } else {
        // if one search produced an IOException, rethrow it
        throw ioe;
      }
    }

    ScoreDoc[] scoreDocs = new ScoreDoc[hq.size()];
    for (int i = hq.size() - 1; i >= 0; i--) // put docs in array
      scoreDocs[i] = (ScoreDoc) hq.pop();

    return new TopDocs(totalHits, scoreDocs);
  
public org.apache.lucene.search.TopFieldDocssearch(org.apache.lucene.search.Query query, org.apache.lucene.search.Filter filter, int nDocs, org.apache.lucene.search.Sort sort)
A search implementation allowing sorting which spans a new thread for each Searchable, waits for each search to complete and merges the results back together.

    // don't specify the fields - we'll wait to do this until we get results
    FieldDocSortedHitQueue hq = new FieldDocSortedHitQueue (null, nDocs);
    int totalHits = 0;
    MultiSearcherThread[] msta = new MultiSearcherThread[searchables.length];
    for (int i = 0; i < searchables.length; i++) { // search each searcher
      // Assume not too many searchables and cost of creating a thread is by far inferior to a search
      msta[i] =
        new MultiSearcherThread(
                                searchables[i],
                                query,
                                filter,
                                nDocs,
                                hq,
                                sort,
                                i,
                                starts,
                                "MultiSearcher thread #" + (i + 1));
      msta[i].start();
    }

    for (int i = 0; i < searchables.length; i++) {
      try {
        msta[i].join();
      } catch (InterruptedException ie) {
        ; // TODO: what should we do with this???
      }
      IOException ioe = msta[i].getIOException();
      if (ioe == null) {
        totalHits += msta[i].hits();
      } else {
        // if one search produced an IOException, rethrow it
        throw ioe;
      }
    }

    ScoreDoc[] scoreDocs = new ScoreDoc[hq.size()];
    for (int i = hq.size() - 1; i >= 0; i--) // put docs in array
      scoreDocs[i] = (ScoreDoc) hq.pop();

    return new TopFieldDocs(totalHits, scoreDocs, hq.getFields());
  
public voidsearch(org.apache.lucene.search.Query query, org.apache.lucene.search.Filter filter, org.apache.lucene.search.HitCollector results)
Lower-level search API.

{@link HitCollector#collect(int,float)} is called for every non-zero scoring document.

Applications should only use this if they need all of the matching documents. The high-level search API ({@link Searcher#search(Query)}) is usually more efficient, as it skips non-high-scoring hits.

param
query to match documents
param
filter if non-null, a bitset used to eliminate some documents
param
results to receive hits TODO: parallelize this one too

    for (int i = 0; i < searchables.length; i++) {

      final int start = starts[i];

      searchables[i].search(query, filter, new HitCollector() {
          public void collect(int doc, float score) {
            results.collect(doc + start, score);
          }
        });

    }