2 * Copyright 2004 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.
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>
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
)
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();
42 all
.Add(((SpanQuery
) i
.Current
).GetSpans(reader
));
45 private Lucene
.Net
.Index
.IndexReader reader
;
46 private SpanOrQuery enclosingInstance
;
47 public SpanOrQuery Enclosing_Instance
51 return enclosingInstance
;
55 private System
.Collections
.IList all
;
56 private SpanQueue queue
;
58 private bool firstTime
= true;
60 public virtual bool Next()
64 // first time -- initialize
65 for (int i
= 0; i
< all
.Count
; i
++)
67 Spans spans
= (Spans
) all
[i
];
70 // move to first entry
71 queue
.Put(spans
); // build queue
79 return queue
.Size() != 0;
82 if (queue
.Size() == 0)
95 all
.Remove(queue
.Pop()); // exhausted a clause
97 return queue
.Size() != 0;
102 return (Spans
) queue
.Top();
105 public virtual bool SkipTo(int target
)
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
126 while (queue
.Size() != 0 && Top().Doc() < target
)
128 if (Top().SkipTo(target
))
134 all
.Remove(queue
.Pop());
139 return queue
.Size() != 0;
142 public virtual int Doc()
146 public virtual int Start()
148 return Top().Start();
150 public virtual int 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
];
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()
196 public override System
.Collections
.ICollection
GetTerms()
198 System
.Collections
.ArrayList terms
= new System
.Collections
.ArrayList();
199 System
.Collections
.IEnumerator i
= clauses
.GetEnumerator();
202 SpanQuery clause
= (SpanQuery
) i
.Current
;
203 terms
.AddRange(clause
.GetTerms());
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();
215 SpanQuery clause
= (SpanQuery
) i
.Current
;
216 buffer
.Append(clause
.ToString(field
));
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
);
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();
259 return spans1
.Start() < spans2
.Start();
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);