add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / src / java / org / apache / lucene / store / RAMOutputStream.java
1 package org.apache.lucene.store;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 import java.io.IOException;
21
22 /**
23  * A memory-resident {@link IndexOutput} implementation.
24  *
25  * @lucene.internal
26  */
27 public class RAMOutputStream extends IndexOutput {
28   static final int BUFFER_SIZE = 1024;
29
30   private RAMFile file;
31
32   private byte[] currentBuffer;
33   private int currentBufferIndex;
34   
35   private int bufferPosition;
36   private long bufferStart;
37   private int bufferLength;
38
39   /** Construct an empty output buffer. */
40   public RAMOutputStream() {
41     this(new RAMFile());
42   }
43
44   public RAMOutputStream(RAMFile f) {
45     file = f;
46
47     // make sure that we switch to the
48     // first needed buffer lazily
49     currentBufferIndex = -1;
50     currentBuffer = null;
51   }
52
53   /** Copy the current contents of this buffer to the named output. */
54   public void writeTo(IndexOutput out) throws IOException {
55     flush();
56     final long end = file.length;
57     long pos = 0;
58     int buffer = 0;
59     while (pos < end) {
60       int length = BUFFER_SIZE;
61       long nextPos = pos + length;
62       if (nextPos > end) {                        // at the last buffer
63         length = (int)(end - pos);
64       }
65       out.writeBytes(file.getBuffer(buffer++), length);
66       pos = nextPos;
67     }
68   }
69
70   /** Resets this to an empty file. */
71   public void reset() {
72     currentBuffer = null;
73     currentBufferIndex = -1;
74     bufferPosition = 0;
75     bufferStart = 0;
76     bufferLength = 0;
77     file.setLength(0);
78   }
79
80   @Override
81   public void close() throws IOException {
82     flush();
83   }
84
85   @Override
86   public void seek(long pos) throws IOException {
87     // set the file length in case we seek back
88     // and flush() has not been called yet
89     setFileLength();
90     if (pos < bufferStart || pos >= bufferStart + bufferLength) {
91       currentBufferIndex = (int) (pos / BUFFER_SIZE);
92       switchCurrentBuffer();
93     }
94
95     bufferPosition = (int) (pos % BUFFER_SIZE);
96   }
97
98   @Override
99   public long length() {
100     return file.length;
101   }
102
103   @Override
104   public void writeByte(byte b) throws IOException {
105     if (bufferPosition == bufferLength) {
106       currentBufferIndex++;
107       switchCurrentBuffer();
108     }
109     currentBuffer[bufferPosition++] = b;
110   }
111
112   @Override
113   public void writeBytes(byte[] b, int offset, int len) throws IOException {
114     assert b != null;
115     while (len > 0) {
116       if (bufferPosition ==  bufferLength) {
117         currentBufferIndex++;
118         switchCurrentBuffer();
119       }
120
121       int remainInBuffer = currentBuffer.length - bufferPosition;
122       int bytesToCopy = len < remainInBuffer ? len : remainInBuffer;
123       System.arraycopy(b, offset, currentBuffer, bufferPosition, bytesToCopy);
124       offset += bytesToCopy;
125       len -= bytesToCopy;
126       bufferPosition += bytesToCopy;
127     }
128   }
129
130   private final void switchCurrentBuffer() throws IOException {
131     if (currentBufferIndex == file.numBuffers()) {
132       currentBuffer = file.addBuffer(BUFFER_SIZE);
133     } else {
134       currentBuffer = file.getBuffer(currentBufferIndex);
135     }
136     bufferPosition = 0;
137     bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex;
138     bufferLength = currentBuffer.length;
139   }
140
141   private void setFileLength() {
142     long pointer = bufferStart + bufferPosition;
143     if (pointer > file.length) {
144       file.setLength(pointer);
145     }
146   }
147
148   @Override
149   public void flush() throws IOException {
150     file.setLastModified(System.currentTimeMillis());
151     setFileLength();
152   }
153
154   @Override
155   public long getFilePointer() {
156     return currentBufferIndex < 0 ? 0 : bufferStart + bufferPosition;
157   }
158
159   /** Returns byte usage of all buffers. */
160   public long sizeInBytes() {
161     return file.numBuffers() * BUFFER_SIZE;
162   }
163   
164   @Override
165   public void copyBytes(DataInput input, long numBytes) throws IOException {
166     assert numBytes >= 0: "numBytes=" + numBytes;
167
168     while (numBytes > 0) {
169       if (bufferPosition == bufferLength) {
170         currentBufferIndex++;
171         switchCurrentBuffer();
172       }
173
174       int toCopy = currentBuffer.length - bufferPosition;
175       if (numBytes < toCopy) {
176         toCopy = (int) numBytes;
177       }
178       input.readBytes(currentBuffer, bufferPosition, toCopy, false);
179       numBytes -= toCopy;
180       bufferPosition += toCopy;
181     }
182
183   }
184   
185 }