cvsimport
[beagle.git] / beagled / Lucene.Net / Search / Spans / SpanOrQuery.cs
blob233f490ae8e0f4e8a5f50021d573f156db23cf53
1 /*
2 * Copyright 2004 The Apache Software Foundation
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
17 using System;
18 using IndexReader = Lucene.Net.Index.IndexReader;
19 using Query = Lucene.Net.Search.Query;
20 using PriorityQueue = Lucene.Net.Util.PriorityQueue;
21 using ToStringUtils = Lucene.Net.Util.ToStringUtils;
23 namespace Lucene.Net.Search.Spans
26 /// <summary>Matches the union of its clauses.</summary>
27 [Serializable]
28 public class SpanOrQuery : SpanQuery
30 private class AnonymousClassSpans : Spans
32 public AnonymousClassSpans(Lucene.Net.Index.IndexReader reader, SpanOrQuery enclosingInstance)
34 InitBlock(reader, enclosingInstance);
36 private void InitBlock(Lucene.Net.Index.IndexReader reader, SpanOrQuery enclosingInstance)
38 this.reader = reader;
39 this.enclosingInstance = enclosingInstance;
40 all = new System.Collections.ArrayList(Enclosing_Instance.clauses.Count);
41 queue = new SpanQueue(enclosingInstance, Enclosing_Instance.clauses.Count);
42 System.Collections.IEnumerator i = Enclosing_Instance.clauses.GetEnumerator();
43 while (i.MoveNext())
45 // initialize all
46 all.Add(((SpanQuery) i.Current).GetSpans(reader));
49 private Lucene.Net.Index.IndexReader reader;
50 private SpanOrQuery enclosingInstance;
51 public SpanOrQuery Enclosing_Instance
53 get
55 return enclosingInstance;
59 private System.Collections.IList all;
60 private SpanQueue queue;
62 private bool firstTime = true;
64 public virtual bool Next()
66 if (firstTime)
68 // first time -- initialize
69 for (int i = 0; i < all.Count; i++)
71 Spans spans = (Spans) all[i];
72 if (spans.Next())
74 // move to first entry
75 queue.Put(spans); // build queue
77 else
79 all.RemoveAt(i--);
82 firstTime = false;
83 return queue.Size() != 0;
86 if (queue.Size() == 0)
88 // all done
89 return false;
92 if (Top().Next())
94 // move to next
95 queue.AdjustTop();
96 return true;
99 all.Remove(queue.Pop()); // exhausted a clause
101 return queue.Size() != 0;
104 private Spans Top()
106 return (Spans) queue.Top();
109 public virtual bool SkipTo(int target)
111 if (firstTime)
113 for (int i = 0; i < all.Count; i++)
115 Spans spans = (Spans) all[i];
116 if (spans.SkipTo(target))
118 // skip each spans in all
119 queue.Put(spans); // build queue
121 else
123 all.RemoveAt(i--);
126 firstTime = false;
128 else
130 while (queue.Size() != 0 && Top().Doc() < target)
132 if (Top().SkipTo(target))
134 queue.AdjustTop();
136 else
138 all.Remove(queue.Pop());
143 return queue.Size() != 0;
146 public virtual int Doc()
148 return Top().Doc();
150 public virtual int Start()
152 return Top().Start();
154 public virtual int End()
156 return Top().End();
159 public override System.String ToString()
161 return "spans(" + Enclosing_Instance + ")@" + (firstTime?"START":(queue.Size() > 0?(Doc() + ":" + Start() + "-" + End()):"END"));
164 private System.Collections.ArrayList clauses;
165 private System.String field;
167 /// <summary>Construct a SpanOrQuery merging the provided clauses. </summary>
168 public SpanOrQuery(SpanQuery[] clauses)
171 // copy clauses array into an ArrayList
172 this.clauses = new System.Collections.ArrayList(clauses.Length);
173 for (int i = 0; i < clauses.Length; i++)
175 SpanQuery clause = clauses[i];
176 if (i == 0)
178 // check field
179 field = clause.GetField();
181 else if (!clause.GetField().Equals(field))
183 throw new System.ArgumentException("Clauses must have same field.");
185 this.clauses.Add(clause);
189 /// <summary>Return the clauses whose spans are matched. </summary>
190 public virtual SpanQuery[] GetClauses()
192 return (SpanQuery[]) clauses.ToArray(typeof(SpanQuery[]));
195 public override System.String GetField()
197 return field;
200 public override System.Collections.ICollection GetTerms()
202 System.Collections.ArrayList terms = new System.Collections.ArrayList();
203 System.Collections.IEnumerator i = clauses.GetEnumerator();
204 while (i.MoveNext())
206 SpanQuery clause = (SpanQuery) i.Current;
207 terms.AddRange(clause.GetTerms());
209 return terms;
212 public override Query Rewrite(IndexReader reader)
214 SpanOrQuery clone = null;
215 for (int i = 0; i < clauses.Count; i++)
217 SpanQuery c = (SpanQuery) clauses[i];
218 SpanQuery query = (SpanQuery) c.Rewrite(reader);
219 if (query != c)
221 // clause rewrote: must clone
222 if (clone == null)
223 clone = (SpanOrQuery) this.Clone();
224 clone.clauses[i] = query;
227 if (clone != null)
229 return clone; // some clauses rewrote
231 else
233 return this; // no clauses rewrote
237 public override System.String ToString(System.String field)
239 System.Text.StringBuilder buffer = new System.Text.StringBuilder();
240 buffer.Append("spanOr([");
241 System.Collections.IEnumerator i = clauses.GetEnumerator();
242 while (i.MoveNext())
244 SpanQuery clause = (SpanQuery) i.Current;
245 buffer.Append(clause.ToString(field));
246 if (i.MoveNext())
248 buffer.Append(", ");
251 buffer.Append("])");
252 buffer.Append(ToStringUtils.Boost(GetBoost()));
253 return buffer.ToString();
256 public override bool Equals(System.Object o)
258 if (this == o)
259 return true;
260 if (o == null || GetType() != o.GetType())
261 return false;
263 SpanOrQuery that = (SpanOrQuery) o;
265 if (!clauses.Equals(that.clauses))
266 return false;
267 if (!field.Equals(that.field))
268 return false;
270 return GetBoost() == that.GetBoost();
273 public override int GetHashCode()
275 int result;
276 result = clauses.GetHashCode();
277 result = 29 * result + field.GetHashCode();
278 return result;
281 private class SpanQueue : PriorityQueue
283 private void InitBlock(SpanOrQuery enclosingInstance)
285 this.enclosingInstance = enclosingInstance;
287 private SpanOrQuery enclosingInstance;
288 public SpanOrQuery Enclosing_Instance
292 return enclosingInstance;
296 public SpanQueue(SpanOrQuery enclosingInstance, int size)
298 InitBlock(enclosingInstance);
299 Initialize(size);
302 public override bool LessThan(System.Object o1, System.Object o2)
304 Spans spans1 = (Spans) o1;
305 Spans spans2 = (Spans) o2;
306 if (spans1.Doc() == spans2.Doc())
308 if (spans1.Start() == spans2.Start())
310 return spans1.End() < spans2.End();
312 else
314 return spans1.Start() < spans2.Start();
317 else
319 return spans1.Doc() < spans2.Doc();
325 public override Spans GetSpans(IndexReader reader)
327 if (clauses.Count == 1)
328 // optimize 1-clause case
329 return ((SpanQuery) clauses[0]).GetSpans(reader);
331 return new AnonymousClassSpans(reader, this);