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

搜索引擎

开发平台:

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 ByteBuffer = java.nio.ByteBuffer;                  // {{Aroush-1.9}}
  18. // using FileChannel = java.nio.channels.FileChannel;       // {{Aroush-1.9}}
  19. // using MapMode = java.nio.channels.FileChannel.MapMode;   // {{Aroush-1.9}}
  20. namespace Lucene.Net.Store
  21. {
  22. /// <summary>File-based {@link Directory} implementation that uses mmap for input.
  23. /// 
  24. /// <p>To use this, invoke Java with the System property
  25. /// Lucene.Net.FSDirectory.class set to
  26. /// Lucene.Net.store.MMapDirectory.  This will cause {@link
  27. /// FSDirectory#GetDirectory(File,boolean)} to return instances of this class.
  28. /// </summary>
  29. public class MMapDirectory : FSDirectory
  30. {
  31. private class MMapIndexInput : IndexInput, System.ICloneable
  32. {
  33. private System.IO.FileStream buffer;    // private ByteBuffer buffer;   // {{Aroush-1.9}}
  34. private long length;
  35. internal MMapIndexInput(System.IO.FileStream raf)
  36. {
  37. this.length = raf.Length;
  38. // this.buffer = raf.getChannel().map(MapMode.READ_ONLY, 0, length);    // {{Aroush-1.9}}
  39. }
  40. public override byte ReadByte()
  41. {
  42. return 0;   // return buffer.get_Renamed(); // {{Aroush-1.9}}
  43. }
  44. public override void  ReadBytes(byte[] b, int offset, int len)
  45. {
  46. // buffer.get_Renamed(b, offset, len);  // {{Aroush-1.9}}
  47. }
  48. public override long GetFilePointer()
  49. {
  50. return buffer.Position;
  51. }
  52. public override void  Seek(long pos)
  53. {
  54. buffer.Seek(pos, System.IO.SeekOrigin.Begin);
  55. }
  56. public override long Length()
  57. {
  58. return length;
  59. }
  60. public override System.Object Clone()
  61. {
  62. MMapIndexInput clone = (MMapIndexInput) base.Clone();
  63. // clone.buffer = buffer.duplicate();   // {{Aroush-1.9}}
  64. return clone;
  65. }
  66. public override void  Close()
  67. {
  68. }
  69. }
  70. /* Added class MultiMMapIndexInput, Paul Elschot.
  71. * Slightly adapted constructor of MMapIndexInput.
  72. * Licensed under the Apache License, Version 2.0.
  73. */
  74. private class MultiMMapIndexInput:IndexInput, System.ICloneable
  75. {
  76. private System.IO.FileStream[] buffers; // private ByteBuffer[] buffers;    // {{Aroush-1.9}}
  77. private int[] bufSizes; // keep here, ByteBuffer.size() method is optional
  78. private long length;
  79. private int curBufIndex;
  80. private int maxBufSize;
  81. private System.IO.FileStream curBuf;    // private ByteBuffer curBuf; // {{Aroush-1.9}}    // redundant for speed: buffers[curBufIndex]
  82. private int curAvail; // redundant for speed: (bufSizes[curBufIndex] - curBuf.position())
  83. public MultiMMapIndexInput(System.IO.FileStream raf, int maxBufSize)
  84. {
  85. this.length = raf.Length;
  86. this.maxBufSize = maxBufSize;
  87. if (maxBufSize <= 0)
  88. throw new System.ArgumentException("Non positive maxBufSize: " + maxBufSize);
  89. if ((length / maxBufSize) > System.Int32.MaxValue)
  90. {
  91. throw new System.ArgumentException("RandomAccessFile too big for maximum buffer size: " + raf.ToString());
  92. }
  93. int nrBuffers = (int) (length / maxBufSize);
  94. if ((nrBuffers * maxBufSize) < length)
  95. nrBuffers++;
  96. this.buffers = new System.IO.FileStream[nrBuffers]; // this.buffers = new ByteBuffer[nrBuffers];   // {{Aroush-1.9}}
  97. this.bufSizes = new int[nrBuffers];
  98. long bufferStart = 0;
  99. System.IO.FileStream rafc = null;   // FileChannel rafc = raf.getChannel();    // {{Aroush-1.9}}
  100. for (int bufNr = 0; bufNr < nrBuffers; bufNr++)
  101. {
  102. int bufSize = (length > (bufferStart + maxBufSize))?maxBufSize:(int) (length - bufferStart);
  103. // this.buffers[bufNr] = rafc.map(MapMode.READ_ONLY, bufferStart, bufSize);    // {{Aroush-1.9}}
  104. this.bufSizes[bufNr] = bufSize;
  105. bufferStart += bufSize;
  106. }
  107. Seek(0L);
  108. }
  109. public override byte ReadByte()
  110. {
  111. // Performance might be improved by reading ahead into an array of
  112. // eg. 128 bytes and readByte() from there.
  113. if (curAvail == 0)
  114. {
  115. curBufIndex++;
  116. curBuf = buffers[curBufIndex]; // index out of bounds when too many bytes requested
  117. curBuf.Seek(0, System.IO.SeekOrigin.Begin);
  118. curAvail = bufSizes[curBufIndex];
  119. }
  120. curAvail--;
  121. return 0;   // return curBuf.get_Renamed();     // {{Aroush-1.9}}
  122. }
  123. public override void  ReadBytes(byte[] b, int offset, int len)
  124. {
  125. while (len > curAvail)
  126. {
  127. // curBuf.get_Renamed(b, offset, curAvail);    // {{Aroush-1.9}}
  128. len -= curAvail;
  129. offset += curAvail;
  130. curBufIndex++;
  131. curBuf = buffers[curBufIndex]; // index out of bounds when too many bytes requested
  132. curBuf.Seek(0, System.IO.SeekOrigin.Begin);
  133. curAvail = bufSizes[curBufIndex];
  134. }
  135. // curBuf.get_Renamed(b, offset, len); // {{Aroush-1.9}}
  136. curAvail -= len;
  137. }
  138. public override long GetFilePointer()
  139. {
  140. return (curBufIndex * (long) maxBufSize) + curBuf.Position;
  141. }
  142. public override void  Seek(long pos)
  143. {
  144. curBufIndex = (int) (pos / maxBufSize);
  145. curBuf = buffers[curBufIndex];
  146. int bufOffset = (int) (pos - (curBufIndex * maxBufSize));
  147. curBuf.Seek(bufOffset, System.IO.SeekOrigin.Begin);
  148. curAvail = bufSizes[curBufIndex] - bufOffset;
  149. }
  150. public override long Length()
  151. {
  152. return length;
  153. }
  154. public override System.Object Clone()
  155. {
  156. MultiMMapIndexInput clone = (MultiMMapIndexInput) base.Clone();
  157. // clone.buffers = new ByteBuffer[buffers.length];  // {{Aroush-1.9}}
  158. // No need to clone bufSizes.
  159. // Since most clones will use only one buffer, duplicate() could also be
  160. // done lazy in clones, eg. when adapting curBuf.
  161. for (int bufNr = 0; bufNr < buffers.Length; bufNr++)
  162. {
  163. // clone.buffers[bufNr] = buffers[bufNr].duplicate();   // {{Aroush-1.9}}
  164. }
  165. try
  166. {
  167. clone.Seek(GetFilePointer());
  168. }
  169. catch (System.IO.IOException ioe)
  170. {
  171. throw new System.Exception(ioe.ToString()); // {{Aroush-1.9}} should be re-thrown as RuntimeException
  172. }
  173. return clone;
  174. }
  175. public override void  Close()
  176. {
  177. }
  178. }
  179. private int MAX_BBUF = System.Int32.MaxValue;
  180. public override IndexInput OpenInput(System.String name)
  181. {
  182. System.IO.FileInfo f = new System.IO.FileInfo(GetFile().FullName + "\" + name);
  183. System.IO.FileStream raf = new System.IO.FileStream(f.FullName, System.IO.FileMode.Open, System.IO.FileAccess.Read); 
  184. try
  185. {
  186. return (raf.Length <= MAX_BBUF) ? (IndexInput) new MMapIndexInput(raf) : (IndexInput) new MultiMMapIndexInput(raf, MAX_BBUF);
  187. }
  188. finally
  189. {
  190. raf.Close();
  191. }
  192. }
  193. }
  194. }