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

搜索引擎

开发平台:

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 Document = Lucene.Net.Documents.Document;
  18. using Field = Lucene.Net.Documents.Field;
  19. namespace Lucene.Net.Index
  20. {
  21. /// <summary>An IndexReader which reads multiple, parallel indexes.  Each index added
  22. /// must have the same number of documents, but typically each contains
  23. /// different fields.  Each document contains the union of the fields of all
  24. /// documents with the same document number.  When searching, matches for a
  25. /// query term are from the first index added that has the field.
  26. /// 
  27. /// <p>This is useful, e.g., with collections that have large fields which
  28. /// change rarely and small fields that change more frequently.  The smaller
  29. /// fields may be re-indexed in a new index and both indexes may be searched
  30. /// together.
  31. /// 
  32. /// <p><strong>Warning:</strong> It is up to you to make sure all indexes
  33. /// are created and modified the same way. For example, if you add
  34. /// documents to one index, you need to add the same documents in the
  35. /// same order to the other indexes. <em>Failure to do so will result in
  36. /// undefined behavior</em>.
  37. /// </summary>
  38. public class ParallelReader : IndexReader
  39. {
  40. private System.Collections.ArrayList readers = new System.Collections.ArrayList();
  41. private System.Collections.SortedList fieldToReader = new System.Collections.SortedList();
  42. private System.Collections.ArrayList storedFieldReaders = new System.Collections.ArrayList();
  43. private int maxDoc;
  44. private int numDocs;
  45. private bool hasDeletions;
  46. /// <summary>Construct a ParallelReader. </summary>
  47. public ParallelReader() : base(null)
  48. {
  49. }
  50. /// <summary>Add an IndexReader. </summary>
  51. public virtual void  Add(IndexReader reader)
  52. {
  53. Add(reader, false);
  54. }
  55. /// <summary>Add an IndexReader whose stored fields will not be returned.  This can
  56. /// accellerate search when stored fields are only needed from a subset of
  57. /// the IndexReaders.
  58. /// 
  59. /// </summary>
  60. /// <throws>  IllegalArgumentException if not all indexes contain the same number  </throws>
  61. /// <summary>     of documents
  62. /// </summary>
  63. /// <throws>  IllegalArgumentException if not all indexes have the same value  </throws>
  64. /// <summary>     of {@link IndexReader#MaxDoc()}
  65. /// </summary>
  66. public virtual void  Add(IndexReader reader, bool ignoreStoredFields)
  67. {
  68. if (readers.Count == 0)
  69. {
  70. this.maxDoc = reader.MaxDoc();
  71. this.numDocs = reader.NumDocs();
  72. this.hasDeletions = reader.HasDeletions();
  73. }
  74. if (reader.MaxDoc() != maxDoc)
  75. // check compatibility
  76. throw new System.ArgumentException("All readers must have same maxDoc: " + maxDoc + "!=" + reader.MaxDoc());
  77. if (reader.NumDocs() != numDocs)
  78. throw new System.ArgumentException("All readers must have same numDocs: " + numDocs + "!=" + reader.NumDocs());
  79. System.Collections.IEnumerator i = reader.GetFieldNames(IndexReader.FieldOption.ALL).GetEnumerator();
  80. while (i.MoveNext())
  81. {
  82. // update fieldToReader map
  83. System.String field = (System.String) i.Current;
  84. if (fieldToReader[field] == null)
  85. fieldToReader[field] = reader;
  86. }
  87. if (!ignoreStoredFields)
  88. storedFieldReaders.Add(reader); // add to storedFieldReaders
  89. readers.Add(reader);
  90. }
  91. public override int NumDocs()
  92. {
  93. return numDocs;
  94. }
  95. public override int MaxDoc()
  96. {
  97. return maxDoc;
  98. }
  99. public override bool HasDeletions()
  100. {
  101. return hasDeletions;
  102. }
  103. // check first reader
  104. public override bool IsDeleted(int n)
  105. {
  106. if (readers.Count > 0)
  107. return ((IndexReader) readers[0]).IsDeleted(n);
  108. return false;
  109. }
  110. // delete in all readers
  111. protected internal override void  DoDelete(int n)
  112. {
  113. for (int i = 0; i < readers.Count; i++)
  114. {
  115. ((IndexReader) readers[i]).DoDelete(n);
  116. }
  117. hasDeletions = true;
  118. }
  119. // undeleteAll in all readers
  120. protected internal override void  DoUndeleteAll()
  121. {
  122. for (int i = 0; i < readers.Count; i++)
  123. {
  124. ((IndexReader) readers[i]).DoUndeleteAll();
  125. }
  126. hasDeletions = false;
  127. }
  128. // append fields from storedFieldReaders
  129. public override Document Document(int n)
  130. {
  131. Document result = new Document();
  132. for (int i = 0; i < storedFieldReaders.Count; i++)
  133. {
  134. IndexReader reader = (IndexReader) storedFieldReaders[i];
  135. System.Collections.IEnumerator fields = reader.Document(n).Fields();
  136. while (fields.MoveNext())
  137. {
  138. result.Add((Field) fields.Current);
  139. }
  140. }
  141. return result;
  142. }
  143. // get all vectors
  144. public override TermFreqVector[] GetTermFreqVectors(int n)
  145. {
  146. System.Collections.ArrayList results = new System.Collections.ArrayList();
  147. System.Collections.IEnumerator i = new System.Collections.Hashtable(fieldToReader).GetEnumerator();
  148. while (i.MoveNext())
  149. {
  150. System.Collections.DictionaryEntry e = (System.Collections.DictionaryEntry) i.Current;
  151. IndexReader reader = (IndexReader) e.Key;
  152. System.String field = (System.String) e.Value;
  153. TermFreqVector vector = reader.GetTermFreqVector(n, field);
  154. if (vector != null)
  155. results.Add(vector);
  156. }
  157. return (TermFreqVector[]) (results.ToArray(typeof(TermFreqVector)));
  158. }
  159. public override TermFreqVector GetTermFreqVector(int n, System.String field)
  160. {
  161. return ((IndexReader) fieldToReader[field]).GetTermFreqVector(n, field);
  162. }
  163. public override bool HasNorms(System.String field)
  164. {
  165. return ((IndexReader) fieldToReader[field]).HasNorms(field);
  166. }
  167. public override byte[] Norms(System.String field)
  168. {
  169. return ((IndexReader) fieldToReader[field]).Norms(field);
  170. }
  171. public override void  Norms(System.String field, byte[] result, int offset)
  172. {
  173. ((IndexReader) fieldToReader[field]).Norms(field, result, offset);
  174. }
  175. protected internal override void  DoSetNorm(int n, System.String field, byte value_Renamed)
  176. {
  177. ((IndexReader) fieldToReader[field]).DoSetNorm(n, field, value_Renamed);
  178. }
  179. public override TermEnum Terms()
  180. {
  181. return new ParallelTermEnum(this);
  182. }
  183. public override TermEnum Terms(Term term)
  184. {
  185. return new ParallelTermEnum(this, term);
  186. }
  187. public override int DocFreq(Term term)
  188. {
  189. return ((IndexReader) fieldToReader[term.Field()]).DocFreq(term);
  190. }
  191. public override TermDocs TermDocs(Term term)
  192. {
  193. return new ParallelTermDocs(this, term);
  194. }
  195. public override TermDocs TermDocs()
  196. {
  197. return new ParallelTermDocs(this);
  198. }
  199. public override TermPositions TermPositions(Term term)
  200. {
  201. return new ParallelTermPositions(this, term);
  202. }
  203. public override TermPositions TermPositions()
  204. {
  205. return new ParallelTermPositions(this);
  206. }
  207. protected internal override void  DoCommit()
  208. {
  209. for (int i = 0; i < readers.Count; i++)
  210. ((IndexReader) readers[i]).Commit();
  211. }
  212. protected internal override void  DoClose()
  213. {
  214. lock (this)
  215. {
  216. for (int i = 0; i < readers.Count; i++)
  217. ((IndexReader) readers[i]).Close();
  218. }
  219. }
  220. public override System.Collections.ICollection GetFieldNames()
  221. {
  222.             System.Collections.Hashtable result = new System.Collections.Hashtable(fieldToReader.Count);
  223.             System.Collections.ICollection items = fieldToReader.Keys;
  224.             foreach (object item in items)
  225.             {
  226.                 result.Add(item, item);
  227.             }
  228.             return result;
  229. }
  230. public override System.Collections.ICollection GetFieldNames(bool indexed)
  231. {
  232. System.Collections.Hashtable fieldSet = new System.Collections.Hashtable();
  233. for (int i = 0; i < readers.Count; i++)
  234. {
  235. IndexReader reader = ((IndexReader) readers[i]);
  236. System.Collections.ICollection names = reader.GetFieldNames(indexed);
  237.                 foreach (object item in names)
  238.                 {
  239.                     if (fieldSet.ContainsKey(item) == false)
  240.                     {
  241.                         fieldSet.Add(item, item);
  242.                     }
  243.                 }
  244. }
  245. return fieldSet;
  246. }
  247. public override System.Collections.ICollection GetIndexedFieldNames(Field.TermVector tvSpec)
  248. {
  249. System.Collections.Hashtable fieldSet = new System.Collections.Hashtable();
  250. for (int i = 0; i < readers.Count; i++)
  251. {
  252. IndexReader reader = ((IndexReader) readers[i]);
  253. System.Collections.ICollection names = reader.GetIndexedFieldNames(tvSpec);
  254.                 foreach (object item in names)
  255.                 {
  256.                     if (fieldSet.ContainsKey(item) == false)
  257.                     {
  258.                         fieldSet.Add(item, item);
  259.                     }
  260.                 }
  261.             }
  262. return fieldSet;
  263. }
  264. public override System.Collections.ICollection GetFieldNames(IndexReader.FieldOption fieldNames)
  265. {
  266. System.Collections.Hashtable fieldSet = new System.Collections.Hashtable();
  267. for (int i = 0; i < readers.Count; i++)
  268. {
  269. IndexReader reader = ((IndexReader) readers[i]);
  270. System.Collections.ICollection names = reader.GetFieldNames(fieldNames);
  271.                 foreach (object item in names)
  272.                 {
  273.                     if (fieldSet.ContainsKey(item) == false)
  274.                     {
  275.                         fieldSet.Add(item, item);
  276.                     }
  277.                 }
  278.             }
  279. return fieldSet;
  280. }
  281. private class ParallelTermEnum : TermEnum
  282. {
  283. private void  InitBlock(ParallelReader enclosingInstance)
  284. {
  285. this.enclosingInstance = enclosingInstance;
  286. }
  287. private ParallelReader enclosingInstance;
  288. public ParallelReader Enclosing_Instance
  289. {
  290. get
  291. {
  292. return enclosingInstance;
  293. }
  294. }
  295. private System.String field;
  296. private TermEnum termEnum;
  297. public ParallelTermEnum(ParallelReader enclosingInstance)
  298. {
  299. InitBlock(enclosingInstance);
  300. field = ((System.String) Enclosing_Instance.fieldToReader.GetKey(0));
  301. if (field != null)
  302. termEnum = ((IndexReader) Enclosing_Instance.fieldToReader[field]).Terms();
  303. }
  304. public ParallelTermEnum(ParallelReader enclosingInstance, Term term)
  305. {
  306. InitBlock(enclosingInstance);
  307. field = term.Field();
  308. termEnum = ((IndexReader) Enclosing_Instance.fieldToReader[field]).Terms(term);
  309. }
  310. public override bool Next()
  311. {
  312. if (field == null)
  313. return false;
  314. bool next = termEnum.Next();
  315. // still within field?
  316. if (next && (System.Object) termEnum.Term().Field() == (System.Object) field)
  317. return true; // yes, keep going
  318. termEnum.Close(); // close old termEnum
  319. // find the next field, if any
  320. field = ((System.String) SupportClass.TailMap(Enclosing_Instance.fieldToReader, field).GetKey(0));
  321. if (field != null)
  322. {
  323. termEnum = ((IndexReader) Enclosing_Instance.fieldToReader[field]).Terms();
  324. return true;
  325. }
  326. return false; // no more fields
  327. }
  328. public override Term Term()
  329. {
  330. return termEnum.Term();
  331. }
  332. public override int DocFreq()
  333. {
  334. return termEnum.DocFreq();
  335. }
  336. public override void  Close()
  337. {
  338. termEnum.Close();
  339. }
  340. }
  341. // wrap a TermDocs in order to support seek(Term)
  342. private class ParallelTermDocs : TermDocs
  343. {
  344. private void  InitBlock(ParallelReader enclosingInstance)
  345. {
  346. this.enclosingInstance = enclosingInstance;
  347. }
  348. private ParallelReader enclosingInstance;
  349. public ParallelReader Enclosing_Instance
  350. {
  351. get
  352. {
  353. return enclosingInstance;
  354. }
  355. }
  356. protected internal TermDocs termDocs;
  357. public ParallelTermDocs(ParallelReader enclosingInstance)
  358. {
  359. InitBlock(enclosingInstance);
  360. }
  361. public ParallelTermDocs(ParallelReader enclosingInstance, Term term)
  362. {
  363. InitBlock(enclosingInstance);
  364. Seek(term);
  365. }
  366. public virtual int Doc()
  367. {
  368. return termDocs.Doc();
  369. }
  370. public virtual int Freq()
  371. {
  372. return termDocs.Freq();
  373. }
  374. public virtual void  Seek(Term term)
  375. {
  376. termDocs = ((IndexReader) Enclosing_Instance.fieldToReader[term.Field()]).TermDocs(term);
  377. }
  378. public virtual void  Seek(TermEnum termEnum)
  379. {
  380. Seek(termEnum.Term());
  381. }
  382. public virtual bool Next()
  383. {
  384. return termDocs.Next();
  385. }
  386. public virtual int Read(int[] docs, int[] freqs)
  387. {
  388. return termDocs.Read(docs, freqs);
  389. }
  390. public virtual bool SkipTo(int target)
  391. {
  392. return termDocs.SkipTo(target);
  393. }
  394. public virtual void  Close()
  395. {
  396. termDocs.Close();
  397. }
  398. }
  399. private class ParallelTermPositions : ParallelTermDocs, TermPositions
  400. {
  401. private void  InitBlock(ParallelReader enclosingInstance)
  402. {
  403. this.enclosingInstance = enclosingInstance;
  404. }
  405. private ParallelReader enclosingInstance;
  406. public new ParallelReader Enclosing_Instance
  407. {
  408. get
  409. {
  410. return enclosingInstance;
  411. }
  412. }
  413. public ParallelTermPositions(ParallelReader enclosingInstance) : base(enclosingInstance)
  414. {
  415. InitBlock(enclosingInstance);
  416. }
  417. public ParallelTermPositions(ParallelReader enclosingInstance, Term term) : base(enclosingInstance)
  418. {
  419. InitBlock(enclosingInstance);
  420. Seek(term);
  421. }
  422. public override void  Seek(Term term)
  423. {
  424. termDocs = ((IndexReader) Enclosing_Instance.fieldToReader[term.Field()]).TermPositions(term);
  425. }
  426. public virtual int NextPosition()
  427. {
  428. return ((TermPositions) termDocs).NextPosition();
  429. }
  430. }
  431. }
  432. }