SpanOrQuery.cs
上传用户:zhangkuixh
上传日期:2013-09-30
资源大小:5473k
文件大小:8k
源码类别:

搜索引擎

开发平台:

C#

  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.
  15.  */
  16. using System;
  17. using IndexReader = Lucene.Net.Index.IndexReader;
  18. using Query = Lucene.Net.Search.Query;
  19. using PriorityQueue = Lucene.Net.Util.PriorityQueue;
  20. using ToStringUtils = Lucene.Net.Util.ToStringUtils;
  21. namespace Lucene.Net.Search.Spans
  22. {
  23. /// <summary>Matches the union of its clauses.</summary>
  24. [Serializable]
  25. public class SpanOrQuery : SpanQuery
  26. {
  27. private class AnonymousClassSpans : Spans
  28. {
  29. public AnonymousClassSpans(Lucene.Net.Index.IndexReader reader, SpanOrQuery enclosingInstance)
  30. {
  31. InitBlock(reader, enclosingInstance);
  32. }
  33. private void  InitBlock(Lucene.Net.Index.IndexReader reader, SpanOrQuery enclosingInstance)
  34. {
  35. this.reader = reader;
  36. this.enclosingInstance = enclosingInstance;
  37. all = new System.Collections.ArrayList(Enclosing_Instance.clauses.Count);
  38. queue = new SpanQueue(enclosingInstance, Enclosing_Instance.clauses.Count);
  39. System.Collections.IEnumerator i = Enclosing_Instance.clauses.GetEnumerator();
  40. while (i.MoveNext())
  41. {
  42. // initialize all
  43. all.Add(((SpanQuery) i.Current).GetSpans(reader));
  44. }
  45. }
  46. private Lucene.Net.Index.IndexReader reader;
  47. private SpanOrQuery enclosingInstance;
  48. public SpanOrQuery Enclosing_Instance
  49. {
  50. get
  51. {
  52. return enclosingInstance;
  53. }
  54. }
  55. private System.Collections.IList all;
  56. private SpanQueue queue;
  57. private bool firstTime = true;
  58. public virtual bool Next()
  59. {
  60. if (firstTime)
  61. {
  62. // first time -- initialize
  63. for (int i = 0; i < all.Count; i++)
  64. {
  65. Spans spans = (Spans) all[i];
  66. if (spans.Next())
  67. {
  68. // move to first entry
  69. queue.Put(spans); // build queue
  70. }
  71. else
  72. {
  73. all.RemoveAt(i--);
  74. }
  75. }
  76. firstTime = false;
  77. return queue.Size() != 0;
  78. }
  79. if (queue.Size() == 0)
  80. {
  81. // all done
  82. return false;
  83. }
  84. if (Top().Next())
  85. {
  86. // move to next
  87. queue.AdjustTop();
  88. return true;
  89. }
  90. all.Remove(queue.Pop()); // exhausted a clause
  91. return queue.Size() != 0;
  92. }
  93. private Spans Top()
  94. {
  95. return (Spans) queue.Top();
  96. }
  97. public virtual bool SkipTo(int target)
  98. {
  99. if (firstTime)
  100. {
  101. for (int i = 0; i < all.Count; i++)
  102. {
  103. Spans spans = (Spans) all[i];
  104. if (spans.SkipTo(target))
  105. {
  106. // skip each spans in all
  107. queue.Put(spans); // build queue
  108. }
  109. else
  110. {
  111. all.RemoveAt(i--);
  112. }
  113. }
  114. firstTime = false;
  115. }
  116. else
  117. {
  118. while (queue.Size() != 0 && Top().Doc() < target)
  119. {
  120. if (Top().SkipTo(target))
  121. {
  122. queue.AdjustTop();
  123. }
  124. else
  125. {
  126. all.Remove(queue.Pop());
  127. }
  128. }
  129. }
  130. return queue.Size() != 0;
  131. }
  132. public virtual int Doc()
  133. {
  134. return Top().Doc();
  135. }
  136. public virtual int Start()
  137. {
  138. return Top().Start();
  139. }
  140. public virtual int End()
  141. {
  142. return Top().End();
  143. }
  144. public override System.String ToString()
  145. {
  146. return "spans(" + Enclosing_Instance + ")@" + (firstTime?"START":(queue.Size() > 0?(Doc() + ":" + Start() + "-" + End()):"END"));
  147. }
  148. }
  149. private System.Collections.ArrayList clauses;
  150. private System.String field;
  151. /// <summary>Construct a SpanOrQuery merging the provided clauses. </summary>
  152. public SpanOrQuery(SpanQuery[] clauses)
  153. {
  154. // copy clauses array into an ArrayList
  155. this.clauses = new System.Collections.ArrayList(clauses.Length);
  156. for (int i = 0; i < clauses.Length; i++)
  157. {
  158. SpanQuery clause = clauses[i];
  159. if (i == 0)
  160. {
  161. // check field
  162. field = clause.GetField();
  163. }
  164. else if (!clause.GetField().Equals(field))
  165. {
  166. throw new System.ArgumentException("Clauses must have same field.");
  167. }
  168. this.clauses.Add(clause);
  169. }
  170. }
  171. /// <summary>Return the clauses whose spans are matched. </summary>
  172. public virtual SpanQuery[] GetClauses()
  173. {
  174.             return (SpanQuery[]) clauses.ToArray(typeof(SpanQuery[]));
  175. }
  176. public override System.String GetField()
  177. {
  178. return field;
  179. }
  180. public override System.Collections.ICollection GetTerms()
  181. {
  182. System.Collections.ArrayList terms = new System.Collections.ArrayList();
  183. System.Collections.IEnumerator i = clauses.GetEnumerator();
  184. while (i.MoveNext())
  185. {
  186. SpanQuery clause = (SpanQuery) i.Current;
  187. terms.AddRange(clause.GetTerms());
  188. }
  189. return terms;
  190. }
  191. public override Query Rewrite(IndexReader reader)
  192. {
  193. SpanOrQuery clone = null;
  194. for (int i = 0; i < clauses.Count; i++)
  195. {
  196. SpanQuery c = (SpanQuery) clauses[i];
  197. SpanQuery query = (SpanQuery) c.Rewrite(reader);
  198. if (query != c)
  199. {
  200. // clause rewrote: must clone
  201. if (clone == null)
  202. clone = (SpanOrQuery) this.Clone();
  203. clone.clauses[i] = query;
  204. }
  205. }
  206. if (clone != null)
  207. {
  208. return clone; // some clauses rewrote
  209. }
  210. else
  211. {
  212. return this; // no clauses rewrote
  213. }
  214. }
  215. public override System.String ToString(System.String field)
  216. {
  217. System.Text.StringBuilder buffer = new System.Text.StringBuilder();
  218. buffer.Append("spanOr([");
  219. System.Collections.IEnumerator i = clauses.GetEnumerator();
  220. while (i.MoveNext())
  221. {
  222. SpanQuery clause = (SpanQuery) i.Current;
  223. buffer.Append(clause.ToString(field));
  224. if (i.MoveNext())
  225. {
  226. buffer.Append(", ");
  227. }
  228. }
  229. buffer.Append("])");
  230. buffer.Append(ToStringUtils.Boost(GetBoost()));
  231. return buffer.ToString();
  232. }
  233. public  override bool Equals(System.Object o)
  234. {
  235. if (this == o)
  236. return true;
  237. if (o == null || GetType() != o.GetType())
  238. return false;
  239. SpanOrQuery that = (SpanOrQuery) o;
  240. if (!clauses.Equals(that.clauses))
  241. return false;
  242. if (!field.Equals(that.field))
  243. return false;
  244. return GetBoost() == that.GetBoost();
  245. }
  246. public override int GetHashCode()
  247. {
  248. int result;
  249. result = clauses.GetHashCode();
  250. result = 29 * result + field.GetHashCode();
  251. return result;
  252. }
  253. private class SpanQueue : PriorityQueue
  254. {
  255. private void  InitBlock(SpanOrQuery enclosingInstance)
  256. {
  257. this.enclosingInstance = enclosingInstance;
  258. }
  259. private SpanOrQuery enclosingInstance;
  260. public SpanOrQuery Enclosing_Instance
  261. {
  262. get
  263. {
  264. return enclosingInstance;
  265. }
  266. }
  267. public SpanQueue(SpanOrQuery enclosingInstance, int size)
  268. {
  269. InitBlock(enclosingInstance);
  270. Initialize(size);
  271. }
  272. public override bool LessThan(System.Object o1, System.Object o2)
  273. {
  274. Spans spans1 = (Spans) o1;
  275. Spans spans2 = (Spans) o2;
  276. if (spans1.Doc() == spans2.Doc())
  277. {
  278. if (spans1.Start() == spans2.Start())
  279. {
  280. return spans1.End() < spans2.End();
  281. }
  282. else
  283. {
  284. return spans1.Start() < spans2.Start();
  285. }
  286. }
  287. else
  288. {
  289. return spans1.Doc() < spans2.Doc();
  290. }
  291. }
  292. }
  293. public override Spans GetSpans(IndexReader reader)
  294. {
  295. if (clauses.Count == 1)
  296.      // optimize 1-clause case
  297. return ((SpanQuery) clauses[0]).GetSpans(reader);
  298. return new AnonymousClassSpans(reader, this);
  299. }
  300. }
  301. }