Thumbnail file hits. Based on a patch from D Bera
[beagle.git] / beagled / Lucene.Net / Search / Spans / SpanOrQuery.cs
blob3a72f9f1aa65723bafc9ffe21b1b738a51905eca
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.
16 using System;
17 using IndexReader = Lucene.Net.Index.IndexReader;
18 using PriorityQueue = Lucene.Net.Util.PriorityQueue;
19 namespace Lucene.Net.Search.Spans
22 /// <summary>Matches the union of its clauses.</summary>
23 [Serializable]
24 public class SpanOrQuery : SpanQuery
26 private class AnonymousClassSpans : Spans
28 public AnonymousClassSpans(Lucene.Net.Index.IndexReader reader, SpanOrQuery enclosingInstance)
30 InitBlock(reader, enclosingInstance);
32 private void InitBlock(Lucene.Net.Index.IndexReader reader, SpanOrQuery enclosingInstance)
34 this.reader = reader;
35 this.enclosingInstance = enclosingInstance;
36 all = new System.Collections.ArrayList(Enclosing_Instance.clauses.Count);
37 queue = new SpanQueue(enclosingInstance, Enclosing_Instance.clauses.Count);
38 System.Collections.IEnumerator i = Enclosing_Instance.clauses.GetEnumerator();
39 while (i.MoveNext())
41 // initialize all
42 all.Add(((SpanQuery) i.Current).GetSpans(reader));
45 private Lucene.Net.Index.IndexReader reader;
46 private SpanOrQuery enclosingInstance;
47 public SpanOrQuery Enclosing_Instance
49 get
51 return enclosingInstance;
55 private System.Collections.IList all;
56 private SpanQueue queue;
58 private bool firstTime = true;
60 public virtual bool Next()
62 if (firstTime)
64 // first time -- initialize
65 for (int i = 0; i < all.Count; i++)
67 Spans spans = (Spans) all[i];
68 if (spans.Next())
70 // move to first entry
71 queue.Put(spans); // build queue
73 else
75 all.RemoveAt(i--);
78 firstTime = false;
79 return queue.Size() != 0;
82 if (queue.Size() == 0)
84 // all done
85 return false;
88 if (Top().Next())
90 // move to next
91 queue.AdjustTop();
92 return true;
95 all.Remove(queue.Pop()); // exhausted a clause
97 return queue.Size() != 0;
100 private Spans Top()
102 return (Spans) queue.Top();
105 public virtual bool SkipTo(int target)
107 if (firstTime)
109 for (int i = 0; i < all.Count; i++)
111 Spans spans = (Spans) all[i];
112 if (spans.SkipTo(target))
114 // skip each spans in all
115 queue.Put(spans); // build queue
117 else
119 all.RemoveAt(i--);
122 firstTime = false;
124 else
126 while (queue.Size() != 0 && Top().Doc() < target)
128 if (Top().SkipTo(target))
130 queue.AdjustTop();
132 else
134 all.Remove(queue.Pop());
139 return queue.Size() != 0;
142 public virtual int Doc()
144 return Top().Doc();
146 public virtual int Start()
148 return Top().Start();
150 public virtual int End()
152 return Top().End();
155 public override System.String ToString()
157 return "spans(" + Enclosing_Instance + ")@" + (firstTime?"START":(queue.Size() > 0?(Doc() + ":" + Start() + "-" + End()):"END"));
160 private System.Collections.ArrayList clauses;
161 private System.String field;
163 /// <summary>Construct a SpanOrQuery merging the provided clauses. </summary>
164 public SpanOrQuery(SpanQuery[] clauses)
167 // copy clauses array into an ArrayList
168 this.clauses = new System.Collections.ArrayList(clauses.Length);
169 for (int i = 0; i < clauses.Length; i++)
171 SpanQuery clause = clauses[i];
172 if (i == 0)
174 // check Field
175 field = clause.GetField();
177 else if (!clause.GetField().Equals(field))
179 throw new System.ArgumentException("Clauses must have same Field.");
181 this.clauses.Add(clause);
185 /// <summary>Return the clauses whose spans are matched. </summary>
186 public virtual SpanQuery[] GetClauses()
188 return (SpanQuery[]) clauses.ToArray(typeof(SpanQuery[]));
191 public override System.String GetField()
193 return field;
196 public override System.Collections.ICollection GetTerms()
198 System.Collections.ArrayList terms = new System.Collections.ArrayList();
199 System.Collections.IEnumerator i = clauses.GetEnumerator();
200 while (i.MoveNext())
202 SpanQuery clause = (SpanQuery) i.Current;
203 terms.AddRange(clause.GetTerms());
205 return terms;
208 public override System.String ToString(System.String field)
210 System.Text.StringBuilder buffer = new System.Text.StringBuilder();
211 buffer.Append("spanOr([");
212 System.Collections.IEnumerator i = clauses.GetEnumerator();
213 while (i.MoveNext())
215 SpanQuery clause = (SpanQuery) i.Current;
216 buffer.Append(clause.ToString(field));
217 if (i.MoveNext())
219 buffer.Append(", ");
222 buffer.Append("])");
223 return buffer.ToString();
226 private class SpanQueue:PriorityQueue
228 private void InitBlock(SpanOrQuery enclosingInstance)
230 this.enclosingInstance = enclosingInstance;
232 private SpanOrQuery enclosingInstance;
233 public SpanOrQuery Enclosing_Instance
237 return enclosingInstance;
241 public SpanQueue(SpanOrQuery enclosingInstance, int size)
243 InitBlock(enclosingInstance);
244 Initialize(size);
247 public override bool LessThan(System.Object o1, System.Object o2)
249 Spans spans1 = (Spans) o1;
250 Spans spans2 = (Spans) o2;
251 if (spans1.Doc() == spans2.Doc())
253 if (spans1.Start() == spans2.Start())
255 return spans1.End() < spans2.End();
257 else
259 return spans1.Start() < spans2.Start();
262 else
264 return spans1.Doc() < spans2.Doc();
270 public override Spans GetSpans(IndexReader reader)
272 if (clauses.Count == 1)
273 // optimize 1-clause case
274 return ((SpanQuery) clauses[0]).GetSpans(reader);
276 return new AnonymousClassSpans(reader, this);