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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 using IndexReader = Mono.Lucene.Net.Index.IndexReader;
21 using ToStringUtils = Mono.Lucene.Net.Util.ToStringUtils;
22 using Query = Mono.Lucene.Net.Search.Query;
24 namespace Mono.Lucene.Net.Search.Spans
27 /// <summary>Removes matches which overlap with another SpanQuery. </summary>
29 public class SpanNotQuery:SpanQuery, System.ICloneable
31 private class AnonymousClassSpans : Spans
33 public AnonymousClassSpans(Mono.Lucene.Net.Index.IndexReader reader, SpanNotQuery enclosingInstance)
35 InitBlock(reader, enclosingInstance);
37 private void InitBlock(Mono.Lucene.Net.Index.IndexReader reader, SpanNotQuery enclosingInstance)
40 this.enclosingInstance = enclosingInstance;
41 includeSpans = Enclosing_Instance.include.GetSpans(reader);
42 excludeSpans = Enclosing_Instance.exclude.GetSpans(reader);
43 moreExclude = excludeSpans.Next();
45 private Mono.Lucene.Net.Index.IndexReader reader;
46 private SpanNotQuery enclosingInstance;
47 public SpanNotQuery Enclosing_Instance
51 return enclosingInstance;
55 private Spans includeSpans;
56 private bool moreInclude = true;
58 private Spans excludeSpans;
59 private bool moreExclude;
61 public override bool Next()
64 // move to next include
65 moreInclude = includeSpans.Next();
67 while (moreInclude && moreExclude)
70 if (includeSpans.Doc() > excludeSpans.Doc())
72 moreExclude = excludeSpans.SkipTo(includeSpans.Doc());
74 while (moreExclude && includeSpans.Doc() == excludeSpans.Doc() && excludeSpans.End() <= includeSpans.Start())
76 moreExclude = excludeSpans.Next(); // increment exclude
79 if (!moreExclude || includeSpans.Doc() != excludeSpans.Doc() || includeSpans.End() <= excludeSpans.Start())
80 break; // we found a match
82 moreInclude = includeSpans.Next(); // intersected: keep scanning
87 public override bool SkipTo(int target)
91 moreInclude = includeSpans.SkipTo(target);
96 if (moreExclude && includeSpans.Doc() > excludeSpans.Doc())
97 moreExclude = excludeSpans.SkipTo(includeSpans.Doc());
99 while (moreExclude && includeSpans.Doc() == excludeSpans.Doc() && excludeSpans.End() <= includeSpans.Start())
101 moreExclude = excludeSpans.Next(); // increment exclude
104 if (!moreExclude || includeSpans.Doc() != excludeSpans.Doc() || includeSpans.End() <= excludeSpans.Start())
105 return true; // we found a match
107 return Next(); // scan to next match
110 public override int Doc()
112 return includeSpans.Doc();
114 public override int Start()
116 return includeSpans.Start();
118 public override int End()
120 return includeSpans.End();
123 // TODO: Remove warning after API has been finalizedb
124 public override System.Collections.Generic.ICollection<byte[]> GetPayload()
126 System.Collections.Generic.ICollection<byte[]> result = null;
127 if (includeSpans.IsPayloadAvailable())
129 result = includeSpans.GetPayload();
134 // TODO: Remove warning after API has been finalized
135 public override bool IsPayloadAvailable()
137 return includeSpans.IsPayloadAvailable();
140 public override System.String ToString()
142 return "spans(" + Enclosing_Instance.ToString() + ")";
145 private SpanQuery include;
146 private SpanQuery exclude;
148 /// <summary>Construct a SpanNotQuery matching spans from <code>include</code> which
149 /// have no overlap with spans from <code>exclude</code>.
151 public SpanNotQuery(SpanQuery include, SpanQuery exclude)
153 this.include = include;
154 this.exclude = exclude;
156 if (!include.GetField().Equals(exclude.GetField()))
157 throw new System.ArgumentException("Clauses must have same field.");
160 /// <summary>Return the SpanQuery whose matches are filtered. </summary>
161 public virtual SpanQuery GetInclude()
166 /// <summary>Return the SpanQuery whose matches must not overlap those returned. </summary>
167 public virtual SpanQuery GetExclude()
172 public override System.String GetField()
174 return include.GetField();
177 /// <summary>Returns a collection of all terms matched by this query.</summary>
178 /// <deprecated> use extractTerms instead
180 /// <seealso cref="ExtractTerms(Set)">
182 [Obsolete("use ExtractTerms instead")]
183 public override System.Collections.ICollection GetTerms()
185 return include.GetTerms();
188 public override void ExtractTerms(System.Collections.Hashtable terms)
190 include.ExtractTerms(terms);
193 public override System.String ToString(System.String field)
195 System.Text.StringBuilder buffer = new System.Text.StringBuilder();
196 buffer.Append("spanNot(");
197 buffer.Append(include.ToString(field));
199 buffer.Append(exclude.ToString(field));
201 buffer.Append(ToStringUtils.Boost(GetBoost()));
202 return buffer.ToString();
205 public override System.Object Clone()
207 SpanNotQuery spanNotQuery = new SpanNotQuery((SpanQuery) include.Clone(), (SpanQuery) exclude.Clone());
208 spanNotQuery.SetBoost(GetBoost());
212 public override Spans GetSpans(IndexReader reader)
214 return new AnonymousClassSpans(reader, this);
217 public override Query Rewrite(IndexReader reader)
219 SpanNotQuery clone = null;
221 SpanQuery rewrittenInclude = (SpanQuery) include.Rewrite(reader);
222 if (rewrittenInclude != include)
224 clone = (SpanNotQuery) this.Clone();
225 clone.include = rewrittenInclude;
227 SpanQuery rewrittenExclude = (SpanQuery) exclude.Rewrite(reader);
228 if (rewrittenExclude != exclude)
231 clone = (SpanNotQuery) this.Clone();
232 clone.exclude = rewrittenExclude;
237 return clone; // some clauses rewrote
241 return this; // no clauses rewrote
245 /// <summary>Returns true iff <code>o</code> is equal to this. </summary>
246 public override bool Equals(System.Object o)
250 if (!(o is SpanNotQuery))
253 SpanNotQuery other = (SpanNotQuery) o;
254 return this.include.Equals(other.include) && this.exclude.Equals(other.exclude) && this.GetBoost() == other.GetBoost();
257 public override int GetHashCode()
259 int h = include.GetHashCode();
260 h = (h << 1) | (SupportClass.Number.URShift(h, 31)); // rotate left
261 h ^= exclude.GetHashCode();
262 h = (h << 1) | (SupportClass.Number.URShift(h, 31)); // rotate left
263 h ^= System.Convert.ToInt32(GetBoost());