Merge pull request #409 from Alkarex/patch-1
[mono.git] / mcs / tools / monkeydoc / Lucene.Net / Lucene.Net / Search / ReqExclScorer.cs
1 /* 
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  * 
9  * http://www.apache.org/licenses/LICENSE-2.0
10  * 
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 using System;
19
20 namespace Mono.Lucene.Net.Search
21 {
22         
23         
24         /// <summary>A Scorer for queries with a required subscorer
25         /// and an excluding (prohibited) sub DocIdSetIterator.
26         /// <br/>
27         /// This <code>Scorer</code> implements {@link Scorer#SkipTo(int)},
28         /// and it uses the skipTo() on the given scorers.
29         /// </summary>
30         class ReqExclScorer:Scorer
31         {
32                 private Scorer reqScorer;
33                 private DocIdSetIterator exclDisi;
34                 private int doc = - 1;
35                 
36                 /// <summary>Construct a <code>ReqExclScorer</code>.</summary>
37                 /// <param name="reqScorer">The scorer that must match, except where
38                 /// </param>
39                 /// <param name="exclDisi">indicates exclusion.
40                 /// </param>
41                 public ReqExclScorer(Scorer reqScorer, DocIdSetIterator exclDisi):base(null)
42                 { // No similarity used.
43                         this.reqScorer = reqScorer;
44                         this.exclDisi = exclDisi;
45                 }
46                 
47                 /// <deprecated> use {@link #NextDoc()} instead. 
48                 /// </deprecated>
49         [Obsolete("use NextDoc() instead. ")]
50                 public override bool Next()
51                 {
52                         return NextDoc() != NO_MORE_DOCS;
53                 }
54                 
55                 public override int NextDoc()
56                 {
57                         if (reqScorer == null)
58                         {
59                                 return doc;
60                         }
61                         doc = reqScorer.NextDoc();
62                         if (doc == NO_MORE_DOCS)
63                         {
64                                 reqScorer = null; // exhausted, nothing left
65                                 return doc;
66                         }
67                         if (exclDisi == null)
68                         {
69                                 return doc;
70                         }
71                         return doc = ToNonExcluded();
72                 }
73                 
74                 /// <summary>Advance to non excluded doc.
75                 /// <br/>On entry:
76                 /// <ul>
77                 /// <li>reqScorer != null, </li>
78                 /// <li>exclScorer != null, </li>
79                 /// <li>reqScorer was advanced once via next() or skipTo() 
80         /// and reqScorer.doc() may still be excluded.</li>
81                 /// </ul>
82                 /// Advances reqScorer a non excluded required doc, if any.
83                 /// </summary>
84                 /// <returns> true iff there is a non excluded required doc.
85                 /// </returns>
86                 private int ToNonExcluded()
87                 {
88                         int exclDoc = exclDisi.DocID();
89                         int reqDoc = reqScorer.DocID(); // may be excluded
90                         do 
91                         {
92                                 if (reqDoc < exclDoc)
93                                 {
94                                         return reqDoc; // reqScorer advanced to before exclScorer, ie. not excluded
95                                 }
96                                 else if (reqDoc > exclDoc)
97                                 {
98                                         exclDoc = exclDisi.Advance(reqDoc);
99                                         if (exclDoc == NO_MORE_DOCS)
100                                         {
101                                                 exclDisi = null; // exhausted, no more exclusions
102                                                 return reqDoc;
103                                         }
104                                         if (exclDoc > reqDoc)
105                                         {
106                                                 return reqDoc; // not excluded
107                                         }
108                                 }
109                         }
110                         while ((reqDoc = reqScorer.NextDoc()) != NO_MORE_DOCS);
111                         reqScorer = null; // exhausted, nothing left
112                         return NO_MORE_DOCS;
113                 }
114                 
115                 /// <deprecated> use {@link #DocID()} instead. 
116                 /// </deprecated>
117         [Obsolete("use DocID() instead.")]
118                 public override int Doc()
119                 {
120                         return reqScorer.Doc(); // reqScorer may be null when next() or skipTo() already return false
121                 }
122                 
123                 public override int DocID()
124                 {
125                         return doc;
126                 }
127                 
128                 /// <summary>Returns the score of the current document matching the query.
129                 /// Initially invalid, until {@link #Next()} is called the first time.
130                 /// </summary>
131                 /// <returns> The score of the required scorer.
132                 /// </returns>
133                 public override float Score()
134                 {
135                         return reqScorer.Score(); // reqScorer may be null when next() or skipTo() already return false
136                 }
137                 
138                 /// <deprecated> use {@link #Advance(int)} instead. 
139                 /// </deprecated>
140         [Obsolete("use Advance(int) instead.")]
141                 public override bool SkipTo(int target)
142                 {
143                         return Advance(target) != NO_MORE_DOCS;
144                 }
145                 
146                 public override int Advance(int target)
147                 {
148                         if (reqScorer == null)
149                         {
150                                 return doc = NO_MORE_DOCS;
151                         }
152                         if (exclDisi == null)
153                         {
154                                 return doc = reqScorer.Advance(target);
155                         }
156                         if (reqScorer.Advance(target) == NO_MORE_DOCS)
157                         {
158                                 reqScorer = null;
159                                 return doc = NO_MORE_DOCS;
160                         }
161                         return doc = ToNonExcluded();
162                 }
163                 
164                 public override Explanation Explain(int doc)
165                 {
166                         Explanation res = new Explanation();
167                         if (exclDisi.Advance(doc) == doc)
168                         {
169                                 res.SetDescription("excluded");
170                         }
171                         else
172                         {
173                                 res.SetDescription("not excluded");
174                                 res.AddDetail(reqScorer.Explain(doc));
175                         }
176                         return res;
177                 }
178         }
179 }