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

搜索引擎

开发平台:

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 Directory = Lucene.Net.Store.Directory;
  18. using IndexInput = Lucene.Net.Store.IndexInput;
  19. namespace Lucene.Net.Index
  20. {
  21. /// <version>  $Id: TermVectorsReader.java 170226 2005-05-15 15:04:39Z bmesser $
  22. /// </version>
  23. class TermVectorsReader : System.ICloneable
  24. {
  25. private FieldInfos fieldInfos;
  26. private IndexInput tvx;
  27. private IndexInput tvd;
  28. private IndexInput tvf;
  29. private int size;
  30. private int tvdFormat;
  31. private int tvfFormat;
  32. public /*internal*/ TermVectorsReader(Directory d, System.String segment, FieldInfos fieldInfos)
  33. {
  34. if (d.FileExists(segment + TermVectorsWriter.TVX_EXTENSION))
  35. {
  36. tvx = d.OpenInput(segment + TermVectorsWriter.TVX_EXTENSION);
  37. CheckValidFormat(tvx);
  38. tvd = d.OpenInput(segment + TermVectorsWriter.TVD_EXTENSION);
  39. tvdFormat = CheckValidFormat(tvd);
  40. tvf = d.OpenInput(segment + TermVectorsWriter.TVF_EXTENSION);
  41. tvfFormat = CheckValidFormat(tvf);
  42. size = (int) tvx.Length() / 8;
  43. }
  44. this.fieldInfos = fieldInfos;
  45. }
  46. private int CheckValidFormat(IndexInput in_Renamed)
  47. {
  48. int format = in_Renamed.ReadInt();
  49. if (format > TermVectorsWriter.FORMAT_VERSION)
  50. {
  51. throw new System.IO.IOException("Incompatible format version: " + format + " expected " + TermVectorsWriter.FORMAT_VERSION + " or less");
  52. }
  53. return format;
  54. }
  55. internal virtual void  Close()
  56. {
  57. // make all effort to close up. Keep the first exception
  58. // and throw it as a new one.
  59. System.IO.IOException keep = null;
  60. if (tvx != null)
  61. try
  62. {
  63. tvx.Close();
  64. }
  65. catch (System.IO.IOException e)
  66. {
  67. if (keep == null)
  68. keep = e;
  69. }
  70. if (tvd != null)
  71. try
  72. {
  73. tvd.Close();
  74. }
  75. catch (System.IO.IOException e)
  76. {
  77. if (keep == null)
  78. keep = e;
  79. }
  80. if (tvf != null)
  81. try
  82. {
  83. tvf.Close();
  84. }
  85. catch (System.IO.IOException e)
  86. {
  87. if (keep == null)
  88. keep = e;
  89. }
  90. if (keep != null)
  91. {
  92. throw new System.IO.IOException(keep.StackTrace);
  93. }
  94. }
  95. /// <summary> </summary>
  96. /// <returns> The number of documents in the reader
  97. /// </returns>
  98. internal virtual int Size()
  99. {
  100. return size;
  101. }
  102. /// <summary> Retrieve the term vector for the given document and field</summary>
  103. /// <param name="docNum">The document number to retrieve the vector for
  104. /// </param>
  105. /// <param name="field">The field within the document to retrieve
  106. /// </param>
  107. /// <returns> The TermFreqVector for the document and field or null if there is no termVector for this field.
  108. /// </returns>
  109. /// <throws>  IOException if there is an error reading the term vector files </throws>
  110. public /*internal*/ virtual TermFreqVector Get(int docNum, System.String field)
  111. {
  112. // Check if no term vectors are available for this segment at all
  113. int fieldNumber = fieldInfos.FieldNumber(field);
  114. TermFreqVector result = null;
  115. if (tvx != null)
  116. {
  117. //We need to account for the FORMAT_SIZE at when seeking in the tvx
  118. //We don't need to do this in other seeks because we already have the
  119. // file pointer
  120. //that was written in another file
  121. tvx.Seek((docNum * 8L) + TermVectorsWriter.FORMAT_SIZE);
  122. //System.out.println("TVX Pointer: " + tvx.getFilePointer());
  123. long position = tvx.ReadLong();
  124. tvd.Seek(position);
  125. int fieldCount = tvd.ReadVInt();
  126. //System.out.println("Num Fields: " + fieldCount);
  127. // There are only a few fields per document. We opt for a full scan
  128. // rather then requiring that they be ordered. We need to read through
  129. // all of the fields anyway to get to the tvf pointers.
  130. int number = 0;
  131. int found = - 1;
  132. for (int i = 0; i < fieldCount; i++)
  133. {
  134. if (tvdFormat == TermVectorsWriter.FORMAT_VERSION)
  135. number = tvd.ReadVInt();
  136. else
  137. number += tvd.ReadVInt();
  138. if (number == fieldNumber)
  139. found = i;
  140. }
  141. // This field, although valid in the segment, was not found in this
  142. // document
  143. if (found != - 1)
  144. {
  145. // Compute position in the tvf file
  146. position = 0;
  147. for (int i = 0; i <= found; i++)
  148. position += tvd.ReadVLong();
  149. result = ReadTermVector(field, position);
  150. }
  151. else
  152. {
  153. //System.out.println("Field not found");
  154. }
  155. }
  156. else
  157. {
  158. //System.out.println("No tvx file");
  159. }
  160. return result;
  161. }
  162. /// <summary> Return all term vectors stored for this document or null if the could not be read in.
  163. /// 
  164. /// </summary>
  165. /// <param name="docNum">The document number to retrieve the vector for
  166. /// </param>
  167. /// <returns> All term frequency vectors
  168. /// </returns>
  169. /// <throws>  IOException if there is an error reading the term vector files  </throws>
  170. internal virtual TermFreqVector[] Get(int docNum)
  171. {
  172. TermFreqVector[] result = null;
  173. // Check if no term vectors are available for this segment at all
  174. if (tvx != null)
  175. {
  176. //We need to offset by
  177. tvx.Seek((docNum * 8L) + TermVectorsWriter.FORMAT_SIZE);
  178. long position = tvx.ReadLong();
  179. tvd.Seek(position);
  180. int fieldCount = tvd.ReadVInt();
  181. // No fields are vectorized for this document
  182. if (fieldCount != 0)
  183. {
  184. int number = 0;
  185. System.String[] fields = new System.String[fieldCount];
  186. for (int i = 0; i < fieldCount; i++)
  187. {
  188. if (tvdFormat == TermVectorsWriter.FORMAT_VERSION)
  189. number = tvd.ReadVInt();
  190. else
  191. number += tvd.ReadVInt();
  192. fields[i] = fieldInfos.FieldName(number);
  193. }
  194. // Compute position in the tvf file
  195. position = 0;
  196. long[] tvfPointers = new long[fieldCount];
  197. for (int i = 0; i < fieldCount; i++)
  198. {
  199. position += tvd.ReadVLong();
  200. tvfPointers[i] = position;
  201. }
  202. result = ReadTermVectors(fields, tvfPointers);
  203. }
  204. }
  205. else
  206. {
  207. //System.out.println("No tvx file");
  208. }
  209. return result;
  210. }
  211. private SegmentTermVector[] ReadTermVectors(System.String[] fields, long[] tvfPointers)
  212. {
  213. SegmentTermVector[] res = new SegmentTermVector[fields.Length];
  214. for (int i = 0; i < fields.Length; i++)
  215. {
  216. res[i] = ReadTermVector(fields[i], tvfPointers[i]);
  217. }
  218. return res;
  219. }
  220. /// <summary> </summary>
  221. /// <param name="field">The field to read in
  222. /// </param>
  223. /// <param name="tvfPointer">The pointer within the tvf file where we should start reading
  224. /// </param>
  225. /// <returns> The TermVector located at that position
  226. /// </returns>
  227. /// <throws>  IOException </throws>
  228. private SegmentTermVector ReadTermVector(System.String field, long tvfPointer)
  229. {
  230. // Now read the data from specified position
  231. //We don't need to offset by the FORMAT here since the pointer already includes the offset
  232. tvf.Seek(tvfPointer);
  233. int numTerms = tvf.ReadVInt();
  234. //System.out.println("Num Terms: " + numTerms);
  235. // If no terms - return a constant empty termvector. However, this should never occur!
  236. if (numTerms == 0)
  237. return new SegmentTermVector(field, null, null);
  238. bool storePositions;
  239. bool storeOffsets;
  240. if (tvfFormat == TermVectorsWriter.FORMAT_VERSION)
  241. {
  242. byte bits = tvf.ReadByte();
  243. storePositions = (bits & TermVectorsWriter.STORE_POSITIONS_WITH_TERMVECTOR) != 0;
  244. storeOffsets = (bits & TermVectorsWriter.STORE_OFFSET_WITH_TERMVECTOR) != 0;
  245. }
  246. else
  247. {
  248. tvf.ReadVInt();
  249. storePositions = false;
  250. storeOffsets = false;
  251. }
  252. System.String[] terms = new System.String[numTerms];
  253. int[] termFreqs = new int[numTerms];
  254. //  we may not need these, but declare them
  255. int[][] positions = null;
  256. TermVectorOffsetInfo[][] offsets = null;
  257. if (storePositions)
  258. positions = new int[numTerms][];
  259. if (storeOffsets)
  260. offsets = new TermVectorOffsetInfo[numTerms][];
  261. int start = 0;
  262. int deltaLength = 0;
  263. int totalLength = 0;
  264. char[] buffer = new char[10]; // init the buffer with a length of 10 character
  265. char[] previousBuffer = new char[]{};
  266. for (int i = 0; i < numTerms; i++)
  267. {
  268. start = tvf.ReadVInt();
  269. deltaLength = tvf.ReadVInt();
  270. totalLength = start + deltaLength;
  271. if (buffer.Length < totalLength)
  272. {
  273. // increase buffer
  274. buffer = null; // give a hint to garbage collector
  275. buffer = new char[totalLength];
  276. if (start > 0)
  277.      // just copy if necessary
  278. Array.Copy(previousBuffer, 0, buffer, 0, start);
  279. }
  280. tvf.ReadChars(buffer, start, deltaLength);
  281. terms[i] = new System.String(buffer, 0, totalLength);
  282. previousBuffer = buffer;
  283. int freq = tvf.ReadVInt();
  284. termFreqs[i] = freq;
  285. if (storePositions)
  286. {
  287. //read in the positions
  288. int[] pos = new int[freq];
  289. positions[i] = pos;
  290. int prevPosition = 0;
  291. for (int j = 0; j < freq; j++)
  292. {
  293. pos[j] = prevPosition + tvf.ReadVInt();
  294. prevPosition = pos[j];
  295. }
  296. }
  297. if (storeOffsets)
  298. {
  299. TermVectorOffsetInfo[] offs = new TermVectorOffsetInfo[freq];
  300. offsets[i] = offs;
  301. int prevOffset = 0;
  302. for (int j = 0; j < freq; j++)
  303. {
  304. int startOffset = prevOffset + tvf.ReadVInt();
  305. int endOffset = startOffset + tvf.ReadVInt();
  306. offs[j] = new TermVectorOffsetInfo(startOffset, endOffset);
  307. prevOffset = endOffset;
  308. }
  309. }
  310. }
  311. SegmentTermVector tv;
  312. if (storePositions || storeOffsets)
  313. {
  314. tv = new SegmentTermPositionVector(field, terms, termFreqs, positions, offsets);
  315. }
  316. else
  317. {
  318. tv = new SegmentTermVector(field, terms, termFreqs);
  319. }
  320. return tv;
  321. }
  322. public virtual System.Object Clone()
  323. {
  324. if (tvx == null || tvd == null || tvf == null)
  325. return null;
  326. TermVectorsReader clone = null;
  327. try
  328. {
  329. clone = (TermVectorsReader) base.MemberwiseClone();
  330. }
  331. catch (System.Exception)
  332. {
  333. }
  334. clone.tvx = (IndexInput) tvx.Clone();
  335. clone.tvd = (IndexInput) tvd.Clone();
  336. clone.tvf = (IndexInput) tvf.Clone();
  337. return clone;
  338. }
  339. }
  340. }