2 * Copyright 2005 The Apache Software Foundation
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 namespace Lucene
.Net
.Search
23 /// <summary>A Scorer for queries with a required subscorer and an excluding (prohibited) subscorer.
25 /// This <code>Scorer</code> implements {@link Scorer#SkipTo(int)},
26 /// and it uses the skipTo() on the given scorers.
28 public class ReqExclScorer
: Scorer
30 private Scorer reqScorer
, exclScorer
;
32 /// <summary>Construct a <code>ReqExclScorer</code>.</summary>
33 /// <param name="reqScorer">The scorer that must match, except where
35 /// <param name="exclScorer">indicates exclusion.
37 public ReqExclScorer(Scorer reqScorer
, Scorer exclScorer
) : base(null)
38 { // No similarity used.
39 this.reqScorer
= reqScorer
;
40 this.exclScorer
= exclScorer
;
43 private bool firstTime
= true;
45 public override bool Next()
49 if (!exclScorer
.Next())
51 exclScorer
= null; // exhausted at start
55 if (reqScorer
== null)
59 if (!reqScorer
.Next())
61 reqScorer
= null; // exhausted, nothing left
64 if (exclScorer
== null)
66 return true; // reqScorer.next() already returned true
68 return ToNonExcluded();
71 /// <summary>Advance to non excluded doc.
74 /// <li>reqScorer != null,
75 /// <li>exclScorer != null,
76 /// <li>reqScorer was advanced once via next() or skipTo()
77 /// and reqScorer.doc() may still be excluded.
79 /// Advances reqScorer a non excluded required doc, if any.
81 /// <returns> true iff there is a non excluded required doc.
83 private bool ToNonExcluded()
85 int exclDoc
= exclScorer
.Doc();
88 int reqDoc
= reqScorer
.Doc(); // may be excluded
91 return true; // reqScorer advanced to before exclScorer, ie. not excluded
93 else if (reqDoc
> exclDoc
)
95 if (!exclScorer
.SkipTo(reqDoc
))
97 exclScorer
= null; // exhausted, no more exclusions
100 exclDoc
= exclScorer
.Doc();
101 if (exclDoc
> reqDoc
)
103 return true; // not excluded
107 while (reqScorer
.Next());
108 reqScorer
= null; // exhausted, nothing left
112 public override int Doc()
114 return reqScorer
.Doc(); // reqScorer may be null when next() or skipTo() already return false
117 /// <summary>Returns the score of the current document matching the query.
118 /// Initially invalid, until {@link #Next()} is called the first time.
120 /// <returns> The score of the required scorer.
122 public override float Score()
124 return reqScorer
.Score(); // reqScorer may be null when next() or skipTo() already return false
127 /// <summary>Skips to the first match beyond the current whose document number is
128 /// greater than or equal to a given target.
129 /// <br>When this method is used the {@link #Explain(int)} method should not be used.
131 /// <param name="target">The target document number.
133 /// <returns> true iff there is such a match.
135 public override bool SkipTo(int target
)
140 if (!exclScorer
.SkipTo(target
))
142 exclScorer
= null; // exhausted
145 if (reqScorer
== null)
149 if (exclScorer
== null)
151 return reqScorer
.SkipTo(target
);
153 if (!reqScorer
.SkipTo(target
))
158 return ToNonExcluded();
161 public override Explanation
Explain(int doc
)
163 Explanation res
= new Explanation();
164 if (exclScorer
.SkipTo(doc
) && (exclScorer
.Doc() == doc
))
166 res
.SetDescription("excluded");
170 res
.SetDescription("not excluded");
171 res
.AddDetail(reqScorer
.Explain(doc
));