add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / src / java / org / apache / lucene / search / ReqExclScorer.java
1 package org.apache.lucene.search;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 import java.io.IOException;
21
22
23 /** A Scorer for queries with a required subscorer
24  * and an excluding (prohibited) sub DocIdSetIterator.
25  * <br>
26  * This <code>Scorer</code> implements {@link Scorer#skipTo(int)},
27  * and it uses the skipTo() on the given scorers.
28  */
29 class ReqExclScorer extends Scorer {
30   private Scorer reqScorer;
31   private DocIdSetIterator exclDisi;
32   private int doc = -1;
33
34   /** Construct a <code>ReqExclScorer</code>.
35    * @param reqScorer The scorer that must match, except where
36    * @param exclDisi indicates exclusion.
37    */
38   public ReqExclScorer(Scorer reqScorer, DocIdSetIterator exclDisi) {
39     super(reqScorer.weight);
40     this.reqScorer = reqScorer;
41     this.exclDisi = exclDisi;
42   }
43
44   @Override
45   public int nextDoc() throws IOException {
46     if (reqScorer == null) {
47       return doc;
48     }
49     doc = reqScorer.nextDoc();
50     if (doc == NO_MORE_DOCS) {
51       reqScorer = null; // exhausted, nothing left
52       return doc;
53     }
54     if (exclDisi == null) {
55       return doc;
56     }
57     return doc = toNonExcluded();
58   }
59   
60   /** Advance to non excluded doc.
61    * <br>On entry:
62    * <ul>
63    * <li>reqScorer != null,
64    * <li>exclScorer != null,
65    * <li>reqScorer was advanced once via next() or skipTo()
66    *      and reqScorer.doc() may still be excluded.
67    * </ul>
68    * Advances reqScorer a non excluded required doc, if any.
69    * @return true iff there is a non excluded required doc.
70    */
71   private int toNonExcluded() throws IOException {
72     int exclDoc = exclDisi.docID();
73     int reqDoc = reqScorer.docID(); // may be excluded
74     do {  
75       if (reqDoc < exclDoc) {
76         return reqDoc; // reqScorer advanced to before exclScorer, ie. not excluded
77       } else if (reqDoc > exclDoc) {
78         exclDoc = exclDisi.advance(reqDoc);
79         if (exclDoc == NO_MORE_DOCS) {
80           exclDisi = null; // exhausted, no more exclusions
81           return reqDoc;
82         }
83         if (exclDoc > reqDoc) {
84           return reqDoc; // not excluded
85         }
86       }
87     } while ((reqDoc = reqScorer.nextDoc()) != NO_MORE_DOCS);
88     reqScorer = null; // exhausted, nothing left
89     return NO_MORE_DOCS;
90   }
91
92   @Override
93   public int docID() {
94     return doc;
95   }
96
97   /** Returns the score of the current document matching the query.
98    * Initially invalid, until {@link #nextDoc()} is called the first time.
99    * @return The score of the required scorer.
100    */
101   @Override
102   public float score() throws IOException {
103     return reqScorer.score(); // reqScorer may be null when next() or skipTo() already return false
104   }
105   
106   @Override
107   public int advance(int target) throws IOException {
108     if (reqScorer == null) {
109       return doc = NO_MORE_DOCS;
110     }
111     if (exclDisi == null) {
112       return doc = reqScorer.advance(target);
113     }
114     if (reqScorer.advance(target) == NO_MORE_DOCS) {
115       reqScorer = null;
116       return doc = NO_MORE_DOCS;
117     }
118     return doc = toNonExcluded();
119   }
120 }