Lucene.Net  3.0.3
Lucene.Net is a port of the Lucene search engine library, written in C# and targeted at .NET runtime users.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
SpanNotQuery.cs
Go to the documentation of this file.
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 using System.Collections.Generic;
20 using Lucene.Net.Index;
21 using Lucene.Net.Support;
22 using IndexReader = Lucene.Net.Index.IndexReader;
23 using ToStringUtils = Lucene.Net.Util.ToStringUtils;
24 using Query = Lucene.Net.Search.Query;
25 
26 namespace Lucene.Net.Search.Spans
27 {
28 
29  /// <summary>Removes matches which overlap with another SpanQuery. </summary>
30  [Serializable]
31  public class SpanNotQuery:SpanQuery, System.ICloneable
32  {
33  private class AnonymousClassSpans : Spans
34  {
35  public AnonymousClassSpans(Lucene.Net.Index.IndexReader reader, SpanNotQuery enclosingInstance)
36  {
37  InitBlock(reader, enclosingInstance);
38  }
39  private void InitBlock(Lucene.Net.Index.IndexReader reader, SpanNotQuery enclosingInstance)
40  {
41  this.reader = reader;
42  this.enclosingInstance = enclosingInstance;
43  includeSpans = Enclosing_Instance.include.GetSpans(reader);
44  excludeSpans = Enclosing_Instance.exclude.GetSpans(reader);
45  moreExclude = excludeSpans.Next();
46  }
47  private Lucene.Net.Index.IndexReader reader;
48  private SpanNotQuery enclosingInstance;
49  public SpanNotQuery Enclosing_Instance
50  {
51  get
52  {
53  return enclosingInstance;
54  }
55 
56  }
57  private Spans includeSpans;
58  private bool moreInclude = true;
59 
60  private Spans excludeSpans;
61  private bool moreExclude;
62 
63  public override bool Next()
64  {
65  if (moreInclude)
66  // move to next include
67  moreInclude = includeSpans.Next();
68 
69  while (moreInclude && moreExclude)
70  {
71 
72  if (includeSpans.Doc() > excludeSpans.Doc())
73  // skip exclude
74  moreExclude = excludeSpans.SkipTo(includeSpans.Doc());
75 
76  while (moreExclude && includeSpans.Doc() == excludeSpans.Doc() && excludeSpans.End() <= includeSpans.Start())
77  {
78  moreExclude = excludeSpans.Next(); // increment exclude
79  }
80 
81  if (!moreExclude || includeSpans.Doc() != excludeSpans.Doc() || includeSpans.End() <= excludeSpans.Start())
82  break; // we found a match
83 
84  moreInclude = includeSpans.Next(); // intersected: keep scanning
85  }
86  return moreInclude;
87  }
88 
89  public override bool SkipTo(int target)
90  {
91  if (moreInclude)
92  // skip include
93  moreInclude = includeSpans.SkipTo(target);
94 
95  if (!moreInclude)
96  return false;
97 
98  if (moreExclude && includeSpans.Doc() > excludeSpans.Doc())
99  moreExclude = excludeSpans.SkipTo(includeSpans.Doc());
100 
101  while (moreExclude && includeSpans.Doc() == excludeSpans.Doc() && excludeSpans.End() <= includeSpans.Start())
102  {
103  moreExclude = excludeSpans.Next(); // increment exclude
104  }
105 
106  if (!moreExclude || includeSpans.Doc() != excludeSpans.Doc() || includeSpans.End() <= excludeSpans.Start())
107  return true; // we found a match
108 
109  return Next(); // scan to next match
110  }
111 
112  public override int Doc()
113  {
114  return includeSpans.Doc();
115  }
116  public override int Start()
117  {
118  return includeSpans.Start();
119  }
120  public override int End()
121  {
122  return includeSpans.End();
123  }
124 
125  // TODO: Remove warning after API has been finalizedb
126 
127  public override ICollection<byte[]> GetPayload()
128  {
129  System.Collections.Generic.ICollection<byte[]> result = null;
130  if (includeSpans.IsPayloadAvailable())
131  {
132  result = includeSpans.GetPayload();
133  }
134  return result;
135  }
136 
137  // TODO: Remove warning after API has been finalized
138 
139  public override bool IsPayloadAvailable()
140  {
141  return includeSpans.IsPayloadAvailable();
142  }
143 
144  public override System.String ToString()
145  {
146  return "spans(" + Enclosing_Instance.ToString() + ")";
147  }
148  }
149  private SpanQuery include;
150  private SpanQuery exclude;
151 
152  /// <summary>Construct a SpanNotQuery matching spans from <c>include</c> which
153  /// have no overlap with spans from <c>exclude</c>.
154  /// </summary>
155  public SpanNotQuery(SpanQuery include, SpanQuery exclude)
156  {
157  this.include = include;
158  this.exclude = exclude;
159 
160  if (!include.Field.Equals(exclude.Field))
161  throw new System.ArgumentException("Clauses must have same field.");
162  }
163 
164  /// <summary>Return the SpanQuery whose matches are filtered. </summary>
165  public virtual SpanQuery Include
166  {
167  get { return include; }
168  }
169 
170  /// <summary>Return the SpanQuery whose matches must not overlap those returned. </summary>
171  public virtual SpanQuery Exclude
172  {
173  get { return exclude; }
174  }
175 
176  public override string Field
177  {
178  get { return include.Field; }
179  }
180 
181  public override void ExtractTerms(System.Collections.Generic.ISet<Term> terms)
182  {
183  include.ExtractTerms(terms);
184  }
185 
186  public override System.String ToString(System.String field)
187  {
188  System.Text.StringBuilder buffer = new System.Text.StringBuilder();
189  buffer.Append("spanNot(");
190  buffer.Append(include.ToString(field));
191  buffer.Append(", ");
192  buffer.Append(exclude.ToString(field));
193  buffer.Append(")");
194  buffer.Append(ToStringUtils.Boost(Boost));
195  return buffer.ToString();
196  }
197 
198  public override System.Object Clone()
199  {
200  SpanNotQuery spanNotQuery = new SpanNotQuery((SpanQuery) include.Clone(), (SpanQuery) exclude.Clone());
201  spanNotQuery.Boost = Boost;
202  return spanNotQuery;
203  }
204 
205  public override Spans GetSpans(IndexReader reader)
206  {
207  return new AnonymousClassSpans(reader, this);
208  }
209 
210  public override Query Rewrite(IndexReader reader)
211  {
212  SpanNotQuery clone = null;
213 
214  SpanQuery rewrittenInclude = (SpanQuery) include.Rewrite(reader);
215  if (rewrittenInclude != include)
216  {
217  clone = (SpanNotQuery) this.Clone();
218  clone.include = rewrittenInclude;
219  }
220  SpanQuery rewrittenExclude = (SpanQuery) exclude.Rewrite(reader);
221  if (rewrittenExclude != exclude)
222  {
223  if (clone == null)
224  clone = (SpanNotQuery) this.Clone();
225  clone.exclude = rewrittenExclude;
226  }
227 
228  if (clone != null)
229  {
230  return clone; // some clauses rewrote
231  }
232  else
233  {
234  return this; // no clauses rewrote
235  }
236  }
237 
238  /// <summary>Returns true iff <c>o</c> is equal to this. </summary>
239  public override bool Equals(System.Object o)
240  {
241  if (this == o)
242  return true;
243  if (!(o is SpanNotQuery))
244  return false;
245 
246  SpanNotQuery other = (SpanNotQuery) o;
247  return this.include.Equals(other.include) && this.exclude.Equals(other.exclude) && this.Boost == other.Boost;
248  }
249 
250  public override int GetHashCode()
251  {
252  int h = include.GetHashCode();
253  h = (h << 1) | (Number.URShift(h, 31)); // rotate left
254  h ^= exclude.GetHashCode();
255  h = (h << 1) | (Number.URShift(h, 31)); // rotate left
256  h ^= System.Convert.ToInt32(Boost);
257  return h;
258  }
259  }
260 }