Lucene.Net  3.0.3
Lucene.Net is a port of the Lucene search engine library, written in C# and targeted at .NET runtime users.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
RAMInputStream.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 using System;
19 
20 namespace Lucene.Net.Store
21 {
22 
23  /// <summary> A memory-resident <see cref="IndexInput" /> implementation.
24  ///
25  /// </summary>
26  public class RAMInputStream : IndexInput
27  {
28  internal static readonly int BUFFER_SIZE;
29 
30  private RAMFile file;
31  private long length;
32 
33  private byte[] currentBuffer;
34  private int currentBufferIndex;
35 
36  private int bufferPosition;
37  private long bufferStart;
38  private int bufferLength;
39 
40  public /*internal*/ RAMInputStream(RAMFile f)
41  {
42  file = f;
43  length = file.length;
44  if (length / BUFFER_SIZE >= System.Int32.MaxValue)
45  {
46  throw new System.IO.IOException("Too large RAMFile! " + length);
47  }
48 
49  // make sure that we switch to the
50  // first needed buffer lazily
51  currentBufferIndex = - 1;
52  currentBuffer = null;
53  }
54 
55  protected override void Dispose(bool disposing)
56  {
57  // do nothing
58  }
59 
60  public override long Length()
61  {
62  return length;
63  }
64 
65  public override byte ReadByte()
66  {
67  if (bufferPosition >= bufferLength)
68  {
69  currentBufferIndex++;
70  SwitchCurrentBuffer(true);
71  }
72  return currentBuffer[bufferPosition++];
73  }
74 
75  public override void ReadBytes(byte[] b, int offset, int len)
76  {
77  while (len > 0)
78  {
79  if (bufferPosition >= bufferLength)
80  {
81  currentBufferIndex++;
82  SwitchCurrentBuffer(true);
83  }
84 
85  int remainInBuffer = bufferLength - bufferPosition;
86  int bytesToCopy = len < remainInBuffer?len:remainInBuffer;
87  Array.Copy(currentBuffer, bufferPosition, b, offset, bytesToCopy);
88  offset += bytesToCopy;
89  len -= bytesToCopy;
90  bufferPosition += bytesToCopy;
91  }
92  }
93 
94  private void SwitchCurrentBuffer(bool enforceEOF)
95  {
96  if (currentBufferIndex >= file.NumBuffers())
97  {
98  // end of file reached, no more buffers left
99  if (enforceEOF)
100  throw new System.IO.IOException("Read past EOF");
101  else
102  {
103  // Force EOF if a read takes place at this position
104  currentBufferIndex--;
105  bufferPosition = BUFFER_SIZE;
106  }
107  }
108  else
109  {
110  currentBuffer = file.GetBuffer(currentBufferIndex);
111  bufferPosition = 0;
112  bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex;
113  long buflen = length - bufferStart;
114  bufferLength = buflen > BUFFER_SIZE?BUFFER_SIZE:(int) buflen;
115  }
116  }
117 
118  public override long FilePointer
119  {
120  get { return currentBufferIndex < 0 ? 0 : bufferStart + bufferPosition; }
121  }
122 
123  public override void Seek(long pos)
124  {
125  if (currentBuffer == null || pos < bufferStart || pos >= bufferStart + BUFFER_SIZE)
126  {
127  currentBufferIndex = (int) (pos / BUFFER_SIZE);
128  SwitchCurrentBuffer(false);
129  }
130  bufferPosition = (int) (pos % BUFFER_SIZE);
131  }
132 
133  static RAMInputStream()
134  {
135  BUFFER_SIZE = RAMOutputStream.BUFFER_SIZE;
136  }
137  }
138 }