Made many methods and classes non-final, per requests. This includes

IndexWriter and IndexSearcher, among others.

Moved search implementation methods into a new public interface,
Searchable.  This makes it easier to implement a remote searcher.

Fixed some javadoc comments.


git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@149813 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Doug Cutting 2002-07-17 17:38:04 +00:00
parent 47fc87d4cb
commit 53f0f3b4fb
18 changed files with 238 additions and 110 deletions

View File

@ -111,7 +111,7 @@ public final class Field {
return new Field(name, value);
}
/** The name of the field (e.g., "date", "subject", "title", "body", etc.)
/** The name of the field (e.g., "date", "subject", "title", or "body")
as an interned string. */
public String name() { return name; }

View File

@ -84,7 +84,7 @@ import org.apache.lucene.analysis.Analyzer;
method should be called before the index is closed.
*/
public final class IndexWriter {
public class IndexWriter {
private Directory directory; // where this index resides
private Analyzer analyzer; // how to analyze text
@ -140,7 +140,7 @@ public final class IndexWriter {
/** Flushes all changes to an index, closes all associated files, and closes
the directory that the index is stored in. */
public final synchronized void close() throws IOException {
public synchronized void close() throws IOException {
flushRamSegments();
ramDirectory.close();
writeLock.release(); // release write lock
@ -149,7 +149,7 @@ public final class IndexWriter {
}
/** Release the write lock, if needed. */
protected final void finalize() throws IOException {
protected void finalize() throws IOException {
if (writeLock != null) {
writeLock.release(); // release write lock
writeLock = null;
@ -157,7 +157,7 @@ public final class IndexWriter {
}
/** Returns the number of documents currently in this index. */
public final synchronized int docCount() {
public synchronized int docCount() {
int count = 0;
for (int i = 0; i < segmentInfos.size(); i++) {
SegmentInfo si = segmentInfos.info(i);
@ -175,7 +175,7 @@ public final class IndexWriter {
public int maxFieldLength = 10000;
/** Adds a document to this index.*/
public final void addDocument(Document doc) throws IOException {
public void addDocument(Document doc) throws IOException {
DocumentWriter dw =
new DocumentWriter(ramDirectory, analyzer, maxFieldLength);
String segmentName = newSegmentName();
@ -214,7 +214,7 @@ public final class IndexWriter {
/** Merges all segments together into a single segment, optimizing an index
for search. */
public final synchronized void optimize() throws IOException {
public synchronized void optimize() throws IOException {
flushRamSegments();
while (segmentInfos.size() > 1 ||
(segmentInfos.size() == 1 &&
@ -234,7 +234,7 @@ public final class IndexWriter {
* with this method.
*
* <p>After this completes, the index is optimized. */
public final synchronized void addIndexes(Directory[] dirs)
public synchronized void addIndexes(Directory[] dirs)
throws IOException {
optimize(); // start with zero or 1 seg
for (int i = 0; i < dirs.length; i++) {

View File

@ -55,7 +55,7 @@ package org.apache.lucene.search;
*/
/** A clause in a BooleanQuery. */
public final class BooleanClause {
public class BooleanClause {
/** The query whose matching documents are combined by the boolean query. */
public Query query;
/** If true, documents documents which <i>do not</i>

View File

@ -61,7 +61,7 @@ import org.apache.lucene.index.IndexReader;
/** A Query that matches documents matching boolean combinations of other
queries, typically {@link TermQuery}s or {@link PhraseQuery}s.
*/
final public class BooleanQuery extends Query {
public class BooleanQuery extends Query {
private Vector clauses = new Vector();
/** Constructs an empty boolean query. */
@ -79,12 +79,12 @@ final public class BooleanQuery extends Query {
It is an error to specify a clause as both <code>required</code> and
<code>prohibited</code>.
*/
public final void add(Query query, boolean required, boolean prohibited) {
public void add(Query query, boolean required, boolean prohibited) {
clauses.addElement(new BooleanClause(query, required, prohibited));
}
/** Adds a clause to a boolean query. */
public final void add(BooleanClause clause) {
public void add(BooleanClause clause) {
clauses.addElement(clause);
}
@ -95,7 +95,7 @@ final public class BooleanQuery extends Query {
}
}
final float sumOfSquaredWeights(Searcher searcher)
float sumOfSquaredWeights(Searcher searcher)
throws IOException {
float sum = 0.0f;
@ -108,7 +108,7 @@ final public class BooleanQuery extends Query {
return sum;
}
final void normalize(float norm) {
void normalize(float norm) {
for (int i = 0 ; i < clauses.size(); i++) {
BooleanClause c = (BooleanClause)clauses.elementAt(i);
if (!c.prohibited)
@ -116,7 +116,7 @@ final public class BooleanQuery extends Query {
}
}
final Scorer scorer(IndexReader reader)
Scorer scorer(IndexReader reader)
throws IOException {
if (clauses.size() == 1) { // optimize 1-term queries

View File

@ -69,7 +69,7 @@ import org.apache.lucene.index.IndexReader;
<p>For this to work, documents must have been indexed with a {@link
DateField}. */
public final class DateFilter extends Filter {
public class DateFilter extends Filter {
String field;
String start = DateField.MIN_DATE_STRING();
@ -126,7 +126,7 @@ public final class DateFilter extends Filter {
/** Returns a BitSet with true for documents which should be permitted in
search results, and false for those that should not. */
final public BitSet bits(IndexReader reader) throws IOException {
public BitSet bits(IndexReader reader) throws IOException {
BitSet bits = new BitSet(reader.maxDoc());
TermEnum enum = reader.terms(new Term(field, start));
TermDocs termDocs = reader.termDocs();
@ -153,7 +153,7 @@ public final class DateFilter extends Filter {
return bits;
}
public final String toString() {
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(field);
buffer.append(":");

View File

@ -63,8 +63,12 @@ import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.util.PriorityQueue;
/** Implements search over a single IndexReader. */
public final class IndexSearcher extends Searcher {
/** Implements search over a single IndexReader.
*
* <p>Applications usually need only call the inherited {@link #search(Query)}
* or {@link #search(Query,Filter)} methods.
*/
public class IndexSearcher extends Searcher implements Searchable {
IndexReader reader;
/** Creates a searcher searching the index in the named directory. */
@ -83,24 +87,40 @@ public final class IndexSearcher extends Searcher {
}
/** Frees resources associated with this Searcher. */
public final void close() throws IOException {
public void close() throws IOException {
reader.close();
}
final int docFreq(Term term) throws IOException {
/** Expert: Returns the number of documents containing <code>term</code>.
* Called by search code to compute term weights.
* @see IndexReader#docFreq(Term).
*/
public int docFreq(Term term) throws IOException {
return reader.docFreq(term);
}
/** For use by {@link HitCollector} implementations. */
public final Document doc(int i) throws IOException {
public Document doc(int i) throws IOException {
return reader.document(i);
}
final int maxDoc() throws IOException {
/** Expert: Returns one greater than the largest possible document number.
* Called by search code to compute term weights.
* @see IndexReader#maxDoc().
*/
public int maxDoc() throws IOException {
return reader.maxDoc();
}
final TopDocs search(Query query, Filter filter, final int nDocs)
/** Expert: Low-level search implementation. Finds the top <code>n</code>
* hits for <code>query</code>, applying <code>filter</code> if non-null.
*
* <p>Called by {@link Hits}.
*
* <p>Applications should usually call {@link #search(Query)} or {@link
* #search(Query,Filter)} instead.
*/
public TopDocs search(Query query, Filter filter, final int nDocs)
throws IOException {
Scorer scorer = Query.scorer(query, this, reader);
if (scorer == null)
@ -147,8 +167,8 @@ public final class IndexSearcher extends Searcher {
* @param filter if non-null, a bitset used to eliminate some documents
* @param results to receive hits
*/
public final void search(Query query, Filter filter,
final HitCollector results) throws IOException {
public void search(Query query, Filter filter,
final HitCollector results) throws IOException {
HitCollector collector = results;
if (filter != null) {
final BitSet bits = filter.bits(reader);

View File

@ -61,49 +61,53 @@ import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.util.PriorityQueue;
/** Implements search over a set of <code>Searchers</code>. */
public final class MultiSearcher extends Searcher {
private Searcher[] searchers;
/** Implements search over a set of <code>Searchables</code>.
*
* <p>Applications usually need only call the inherited {@link #search(Query)}
* or {@link #search(Query,Filter)} methods.
*/
public class MultiSearcher extends Searcher implements Searchable {
private Searchable[] searchables;
private int[] starts;
private int maxDoc = 0;
/** Creates a searcher which searches <i>searchers</i>. */
public MultiSearcher(Searcher[] searchers) throws IOException {
this.searchers = searchers;
/** Creates a searcher which searches <i>searchables</i>. */
public MultiSearcher(Searchable[] searchables) throws IOException {
this.searchables = searchables;
starts = new int[searchers.length + 1]; // build starts array
for (int i = 0; i < searchers.length; i++) {
starts = new int[searchables.length + 1]; // build starts array
for (int i = 0; i < searchables.length; i++) {
starts[i] = maxDoc;
maxDoc += searchers[i].maxDoc(); // compute maxDocs
maxDoc += searchables[i].maxDoc(); // compute maxDocs
}
starts[searchers.length] = maxDoc;
starts[searchables.length] = maxDoc;
}
/** Frees resources associated with this <code>Searcher</code>. */
public final void close() throws IOException {
for (int i = 0; i < searchers.length; i++)
searchers[i].close();
public void close() throws IOException {
for (int i = 0; i < searchables.length; i++)
searchables[i].close();
}
final int docFreq(Term term) throws IOException {
public int docFreq(Term term) throws IOException {
int docFreq = 0;
for (int i = 0; i < searchers.length; i++)
docFreq += searchers[i].docFreq(term);
for (int i = 0; i < searchables.length; i++)
docFreq += searchables[i].docFreq(term);
return docFreq;
}
/** For use by {@link HitCollector} implementations. */
public final Document doc(int n) throws IOException {
public Document doc(int n) throws IOException {
int i = searcherIndex(n); // find searcher index
return searchers[i].doc(n - starts[i]); // dispatch to searcher
return searchables[i].doc(n - starts[i]); // dispatch to searcher
}
/** For use by {@link HitCollector} implementations to identify the
* index of the sub-searcher that a particular hit came from. */
public final int searcherIndex(int n) { // find searcher for doc n:
public int searcherIndex(int n) { // find searcher for doc n:
// replace w/ call to Arrays.binarySearch in Java 1.2
int lo = 0; // search starts array
int hi = searchers.length - 1; // for first element less
int hi = searchables.length - 1; // for first element less
// than n, return its index
while (hi >= lo) {
int mid = (lo + hi) >> 1;
@ -118,18 +122,18 @@ public final class MultiSearcher extends Searcher {
return hi;
}
final int maxDoc() throws IOException {
public int maxDoc() throws IOException {
return maxDoc;
}
final TopDocs search(Query query, Filter filter, int nDocs)
throws IOException {
public TopDocs search(Query query, Filter filter, int nDocs)
throws IOException {
HitQueue hq = new HitQueue(nDocs);
float minScore = 0.0f;
int totalHits = 0;
for (int i = 0; i < searchers.length; i++) { // search each searcher
TopDocs docs = searchers[i].search(query, filter, nDocs);
for (int i = 0; i < searchables.length; i++) { // search each searcher
TopDocs docs = searchables[i].search(query, filter, nDocs);
totalHits += docs.totalHits; // update totalHits
ScoreDoc[] scoreDocs = docs.scoreDocs;
for (int j = 0; j < scoreDocs.length; j++) { // merge scoreDocs into hq
@ -168,14 +172,13 @@ public final class MultiSearcher extends Searcher {
* @param filter if non-null, a bitset used to eliminate some documents
* @param results to receive hits
*/
public final void search(Query query, Filter filter,
final HitCollector results)
public void search(Query query, Filter filter, final HitCollector results)
throws IOException {
for (int i = 0; i < searchers.length; i++) {
for (int i = 0; i < searchables.length; i++) {
final int start = starts[i];
searchers[i].search(query, filter, new HitCollector() {
searchables[i].search(query, filter, new HitCollector() {
public void collect(int doc, float score) {
results.collect(doc + start, score);
}

View File

@ -65,7 +65,7 @@ import org.apache.lucene.index.IndexReader;
/** A Query that matches documents containing a particular sequence of terms.
This may be combined with other terms with a {@link BooleanQuery}.
*/
final public class PhraseQuery extends Query {
public class PhraseQuery extends Query {
private String field;
private Vector terms = new Vector();
private float idf = 0.0f;
@ -92,12 +92,12 @@ final public class PhraseQuery extends Query {
results are sorted by exactness.
<p>The slop is zero by default, requiring exact matches.*/
public final void setSlop(int s) { slop = s; }
public void setSlop(int s) { slop = s; }
/** Returns the slop. See setSlop(). */
public final int getSlop() { return slop; }
public int getSlop() { return slop; }
/** Adds a term to the end of the query phrase. */
public final void add(Term term) {
public void add(Term term) {
if (terms.size() == 0)
field = term.field();
else if (term.field() != field)
@ -148,7 +148,7 @@ final public class PhraseQuery extends Query {
}
/** Prints a user-readable version of this query. */
public final String toString(String f) {
public String toString(String f) {
StringBuffer buffer = new StringBuffer();
if (!field.equals(f)) {
buffer.append(field);

View File

@ -61,7 +61,7 @@ import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.IndexReader;
/** A Query that matches documents containing terms with a specified prefix. */
final public class PrefixQuery extends Query {
public class PrefixQuery extends Query {
private Term prefix;
private IndexReader reader;
private BooleanQuery query;

View File

@ -61,7 +61,7 @@ import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.IndexReader;
/** A Query that matches documents within an exclusive range. */
public final class RangeQuery extends Query
public class RangeQuery extends Query
{
private Term lowerTerm;
private Term upperTerm;

View File

@ -54,12 +54,20 @@ package org.apache.lucene.search;
* <http://www.apache.org/>.
*/
final class ScoreDoc {
float score;
int doc;
/** Expert: Returned by low-level search implementations.
* @see TopDocs */
public class ScoreDoc {
/** Expert: The score of this document for the query. */
public float score;
ScoreDoc(int d, float s) {
doc = d;
score = s;
/** Expert: A hit document's number.
* @see Searcher#doc(int)
*/
public int doc;
/** Expert: Constructs a ScoreDoc. */
public ScoreDoc(int doc, float score) {
this.doc = doc;
this.score = score;
}
}

View File

@ -0,0 +1,112 @@
package org.apache.lucene.search;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Lucene" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Lucene", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.io.IOException;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.IndexReader;
/** The interface for search implementations. */
public interface Searchable {
/** Lower-level search API.
*
* <p>{@link HitCollector#collect(int,float)} is called for every non-zero
* scoring 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)}) 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
*/
public abstract void search(Query query, Filter filter, HitCollector results)
throws IOException;
/** Frees resources associated with this Searcher. */
public abstract void close() throws IOException;
/** Expert: Returns the number of documents containing <code>term</code>.
* Called by search code to compute term weights.
* @see IndexReader#docFreq(Term).
*/
public abstract int docFreq(Term term) throws IOException;
/** Expert: Returns one greater than the largest possible document number.
* Called by search code to compute term weights.
* @see IndexReader#maxDoc().
*/
public abstract int maxDoc() throws IOException;
/** Expert: Low-level search implementation. Finds the top <code>n</code>
* hits for <code>query</code>, applying <code>filter</code> if non-null.
*
* <p>Called by {@link Hits}.
*
* <p>Applications should usually call {@link Searcher#search(Query)} or
* {@link Searcher#search(Query,Filter)} instead.
*/
public abstract TopDocs search(Query query, Filter filter, int n)
throws IOException;
/** Expert: Returns the stored fields of document <code>i</code>.
* Called by {@link HitCollector} implementations.
* @see IndexReader#document(int).
*/
public abstract Document doc(int i) throws IOException;
}

View File

@ -57,12 +57,14 @@ package org.apache.lucene.search;
import java.io.IOException;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.IndexReader;
/** The abstract base class for search implementations.
<p>Subclasses implement search over a single index, over multiple indices,
and over indices on remote servers.
*
* <p>Subclasses implement search over a single index, over multiple indices,
* and over indices on remote servers.
*/
public abstract class Searcher {
public abstract class Searcher implements Searchable {
/** Returns the documents matching <code>query</code>. */
public final Hits search(Query query) throws IOException {
@ -88,32 +90,4 @@ public abstract class Searcher {
throws IOException {
search(query, (Filter)null, results);
}
/** Lower-level search API.
*
* <p>{@link HitCollector#collect(int,float)} is called for every non-zero
* scoring 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)}) 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
*/
public abstract void search(Query query, Filter filter, HitCollector results)
throws IOException;
/** Frees resources associated with this Searcher. */
abstract public void close() throws IOException;
abstract int docFreq(Term term) throws IOException;
abstract int maxDoc() throws IOException;
abstract TopDocs search(Query query, Filter filter, int n)
throws IOException;
/** For use by {@link HitCollector} implementations. */
public abstract Document doc(int i) throws IOException;
}

View File

@ -62,7 +62,7 @@ import org.apache.lucene.index.IndexReader;
/** A Query that matches documents containing a term.
This may be combined with other terms with a {@link BooleanQuery}.
*/
final public class TermQuery extends Query {
public class TermQuery extends Query {
private Term term;
private float idf = 0.0f;
private float weight = 0.0f;

View File

@ -54,12 +54,19 @@ package org.apache.lucene.search;
* <http://www.apache.org/>.
*/
final class TopDocs {
int totalHits;
ScoreDoc[] scoreDocs;
/** Expert: Returned by low-level search implementations.
* @see Searcher#search(Query,Filter,int) */
public class TopDocs {
/** Expert: The total number of hits for the query.
* @see Hits#length()
*/
public int totalHits;
/** Expert: The top hits for the query. */
public ScoreDoc[] scoreDocs;
TopDocs(int th, ScoreDoc[] sds) {
totalHits = th;
scoreDocs = sds;
/** Expert: Constructs a TopDocs.*/
TopDocs(int totalHits, ScoreDoc[] scoreDocs) {
this.totalHits = totalHits;
this.scoreDocs = scoreDocs;
}
}

View File

@ -59,7 +59,7 @@ import org.apache.lucene.index.Term;
import java.io.IOException;
/** Implements the wildcard search query */
final public class WildcardQuery extends MultiTermQuery {
public class WildcardQuery extends MultiTermQuery {
private Term wildcardTerm;
public WildcardQuery(Term term) {

View File

@ -6,5 +6,10 @@
</head>
<body>
Search over indices.
Applications usually call {@link
org.apache.lucene.search.Searcher#search(Query)} or {@link
org.apache.lucene.search.Searcher#search(Query,Filter)}.
</body>
</html>

View File

@ -4,8 +4,7 @@
</head>
<body>
<h1>Jakarta Lucene API</h1>
The Jakarta Lucene API is divided into several packages:
The Jakarta Lucene API is divided into several packages.
<ul>
<li>
<b><a href="org/apache/lucene/util/package-summary.html">org.apache.lucene.util</a></b>