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
RAMOutputStream.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="IndexOutput" /> implementation.
24  /// <para>For lucene internal use.</para>
25  /// </summary>
27  {
28  internal const int BUFFER_SIZE = 1024;
29 
30  private RAMFile file;
31 
32  private byte[] currentBuffer;
33  private int currentBufferIndex;
34 
35  private bool isDisposed;
36 
37  private int bufferPosition;
38  private long bufferStart;
39  private int bufferLength;
40 
41  /// <summary>Construct an empty output buffer. </summary>
42  public RAMOutputStream():this(new RAMFile())
43  {
44  }
45 
46  internal RAMOutputStream(RAMFile f)
47  {
48  file = f;
49 
50  // make sure that we switch to the
51  // first needed buffer lazily
52  currentBufferIndex = - 1;
53  currentBuffer = null;
54  }
55 
56  /// <summary>Copy the current contents of this buffer to the named output. </summary>
57  public virtual void WriteTo(IndexOutput out_Renamed)
58  {
59  Flush();
60  long end = file.length;
61  long pos = 0;
62  int buffer = 0;
63  while (pos < end)
64  {
65  int length = BUFFER_SIZE;
66  long nextPos = pos + length;
67  if (nextPos > end)
68  {
69  // at the last buffer
70  length = (int) (end - pos);
71  }
72  out_Renamed.WriteBytes(file.GetBuffer(buffer++), length);
73  pos = nextPos;
74  }
75  }
76 
77  /// <summary>Resets this to an empty buffer. </summary>
78  public virtual void Reset()
79  {
80  currentBuffer = null;
81  currentBufferIndex = -1;
82  bufferPosition = 0;
83  bufferStart = 0;
84  bufferLength = 0;
85 
86  file.Length = 0;
87  }
88 
89  protected override void Dispose(bool disposing)
90  {
91  if (isDisposed) return;
92 
93  if (disposing)
94  {
95  Flush();
96  }
97 
98  isDisposed = true;
99  }
100 
101  public override void Seek(long pos)
102  {
103  // set the file length in case we seek back
104  // and flush() has not been called yet
105  SetFileLength();
106  if (pos < bufferStart || pos >= bufferStart + bufferLength)
107  {
108  currentBufferIndex = (int) (pos / BUFFER_SIZE);
109  SwitchCurrentBuffer();
110  }
111 
112  bufferPosition = (int) (pos % BUFFER_SIZE);
113  }
114 
115  public override long Length
116  {
117  get { return file.length; }
118  }
119 
120  public override void WriteByte(byte b)
121  {
122  if (bufferPosition == bufferLength)
123  {
124  currentBufferIndex++;
125  SwitchCurrentBuffer();
126  }
127  currentBuffer[bufferPosition++] = b;
128  }
129 
130  public override void WriteBytes(byte[] b, int offset, int len)
131  {
132  System.Diagnostics.Debug.Assert(b != null);
133  while (len > 0)
134  {
135  if (bufferPosition == bufferLength)
136  {
137  currentBufferIndex++;
138  SwitchCurrentBuffer();
139  }
140 
141  int remainInBuffer = currentBuffer.Length - bufferPosition;
142  int bytesToCopy = len < remainInBuffer?len:remainInBuffer;
143  Array.Copy(b, offset, currentBuffer, bufferPosition, bytesToCopy);
144  offset += bytesToCopy;
145  len -= bytesToCopy;
146  bufferPosition += bytesToCopy;
147  }
148  }
149 
150  private void SwitchCurrentBuffer()
151  {
152  if (currentBufferIndex == file.NumBuffers())
153  {
154  currentBuffer = file.AddBuffer(BUFFER_SIZE);
155  }
156  else
157  {
158  currentBuffer = file.GetBuffer(currentBufferIndex);
159  }
160  bufferPosition = 0;
161  bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex;
162  bufferLength = currentBuffer.Length;
163  }
164 
165  private void SetFileLength()
166  {
167  long pointer = bufferStart + bufferPosition;
168  if (pointer > file.length)
169  {
170  file.Length = pointer;
171  }
172  }
173 
174  public override void Flush()
175  {
176  file.LastModified = (DateTime.UtcNow.Ticks / TimeSpan.TicksPerMillisecond);
177  SetFileLength();
178  }
179 
180  public override long FilePointer
181  {
182  get { return currentBufferIndex < 0 ? 0 : bufferStart + bufferPosition; }
183  }
184 
185  /// <summary>Returns byte usage of all buffers. </summary>
186  public virtual long SizeInBytes()
187  {
188  return file.NumBuffers() * BUFFER_SIZE;
189  }
190  }
191 }